1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a9 < %s | FileCheck %s 3 4define i8 @atomicrmw_uinc_wrap_i8(ptr %ptr, i8 %val) { 5; CHECK-LABEL: atomicrmw_uinc_wrap_i8: 6; CHECK: @ %bb.0: 7; CHECK-NEXT: uxtb r12, r1 8; CHECK-NEXT: dmb ish 9; CHECK-NEXT: .LBB0_1: @ %atomicrmw.start 10; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 11; CHECK-NEXT: ldrexb r1, [r0] 12; CHECK-NEXT: cmp r1, r12 13; CHECK-NEXT: add r3, r1, #1 14; CHECK-NEXT: movwhs r3, #0 15; CHECK-NEXT: strexb r2, r3, [r0] 16; CHECK-NEXT: cmp r2, #0 17; CHECK-NEXT: bne .LBB0_1 18; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 19; CHECK-NEXT: mov r0, r1 20; CHECK-NEXT: dmb ish 21; CHECK-NEXT: bx lr 22 %result = atomicrmw uinc_wrap ptr %ptr, i8 %val seq_cst 23 ret i8 %result 24} 25 26define i16 @atomicrmw_uinc_wrap_i16(ptr %ptr, i16 %val) { 27; CHECK-LABEL: atomicrmw_uinc_wrap_i16: 28; CHECK: @ %bb.0: 29; CHECK-NEXT: uxth r12, r1 30; CHECK-NEXT: dmb ish 31; CHECK-NEXT: .LBB1_1: @ %atomicrmw.start 32; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 33; CHECK-NEXT: ldrexh r1, [r0] 34; CHECK-NEXT: cmp r1, r12 35; CHECK-NEXT: add r3, r1, #1 36; CHECK-NEXT: movwhs r3, #0 37; CHECK-NEXT: strexh r2, r3, [r0] 38; CHECK-NEXT: cmp r2, #0 39; CHECK-NEXT: bne .LBB1_1 40; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 41; CHECK-NEXT: mov r0, r1 42; CHECK-NEXT: dmb ish 43; CHECK-NEXT: bx lr 44 %result = atomicrmw uinc_wrap ptr %ptr, i16 %val seq_cst 45 ret i16 %result 46} 47 48define i32 @atomicrmw_uinc_wrap_i32(ptr %ptr, i32 %val) { 49; CHECK-LABEL: atomicrmw_uinc_wrap_i32: 50; CHECK: @ %bb.0: 51; CHECK-NEXT: dmb ish 52; CHECK-NEXT: .LBB2_1: @ %atomicrmw.start 53; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 54; CHECK-NEXT: ldrex r2, [r0] 55; CHECK-NEXT: cmp r2, r1 56; CHECK-NEXT: add r12, r2, #1 57; CHECK-NEXT: movwhs r12, #0 58; CHECK-NEXT: strex r3, r12, [r0] 59; CHECK-NEXT: cmp r3, #0 60; CHECK-NEXT: bne .LBB2_1 61; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 62; CHECK-NEXT: mov r0, r2 63; CHECK-NEXT: dmb ish 64; CHECK-NEXT: bx lr 65 %result = atomicrmw uinc_wrap ptr %ptr, i32 %val seq_cst 66 ret i32 %result 67} 68 69define i64 @atomicrmw_uinc_wrap_i64(ptr %ptr, i64 %val) { 70; CHECK-LABEL: atomicrmw_uinc_wrap_i64: 71; CHECK: @ %bb.0: 72; CHECK-NEXT: .save {r4, r6, r7, lr} 73; CHECK-NEXT: push {r4, r6, r7, lr} 74; CHECK-NEXT: mov r12, r0 75; CHECK-NEXT: dmb ish 76; CHECK-NEXT: .LBB3_1: @ %atomicrmw.start 77; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 78; CHECK-NEXT: ldrexd r0, r1, [r12] 79; CHECK-NEXT: adds r6, r0, #1 80; CHECK-NEXT: adc r7, r1, #0 81; CHECK-NEXT: subs r4, r0, r2 82; CHECK-NEXT: sbcs r4, r1, r3 83; CHECK-NEXT: movwhs r7, #0 84; CHECK-NEXT: movwhs r6, #0 85; CHECK-NEXT: strexd r4, r6, r7, [r12] 86; CHECK-NEXT: cmp r4, #0 87; CHECK-NEXT: bne .LBB3_1 88; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 89; CHECK-NEXT: dmb ish 90; CHECK-NEXT: pop {r4, r6, r7, pc} 91 %result = atomicrmw uinc_wrap ptr %ptr, i64 %val seq_cst 92 ret i64 %result 93} 94 95define i8 @atomicrmw_udec_wrap_i8(ptr %ptr, i8 %val) { 96; CHECK-LABEL: atomicrmw_udec_wrap_i8: 97; CHECK: @ %bb.0: 98; CHECK-NEXT: dmb ish 99; CHECK-NEXT: .LBB4_1: @ %atomicrmw.start 100; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 101; CHECK-NEXT: ldrexb r12, [r0] 102; CHECK-NEXT: uxtb r3, r1 103; CHECK-NEXT: cmp r12, r3 104; CHECK-NEXT: mov r3, r1 105; CHECK-NEXT: subls r3, r12, #1 106; CHECK-NEXT: cmp r12, #0 107; CHECK-NEXT: moveq r3, r1 108; CHECK-NEXT: strexb r2, r3, [r0] 109; CHECK-NEXT: cmp r2, #0 110; CHECK-NEXT: bne .LBB4_1 111; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 112; CHECK-NEXT: mov r0, r12 113; CHECK-NEXT: dmb ish 114; CHECK-NEXT: bx lr 115 %result = atomicrmw udec_wrap ptr %ptr, i8 %val seq_cst 116 ret i8 %result 117} 118 119define i16 @atomicrmw_udec_wrap_i16(ptr %ptr, i16 %val) { 120; CHECK-LABEL: atomicrmw_udec_wrap_i16: 121; CHECK: @ %bb.0: 122; CHECK-NEXT: dmb ish 123; CHECK-NEXT: .LBB5_1: @ %atomicrmw.start 124; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 125; CHECK-NEXT: ldrexh r12, [r0] 126; CHECK-NEXT: uxth r3, r1 127; CHECK-NEXT: cmp r12, r3 128; CHECK-NEXT: mov r3, r1 129; CHECK-NEXT: subls r3, r12, #1 130; CHECK-NEXT: cmp r12, #0 131; CHECK-NEXT: moveq r3, r1 132; CHECK-NEXT: strexh r2, r3, [r0] 133; CHECK-NEXT: cmp r2, #0 134; CHECK-NEXT: bne .LBB5_1 135; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 136; CHECK-NEXT: mov r0, r12 137; CHECK-NEXT: dmb ish 138; CHECK-NEXT: bx lr 139 %result = atomicrmw udec_wrap ptr %ptr, i16 %val seq_cst 140 ret i16 %result 141} 142 143define i32 @atomicrmw_udec_wrap_i32(ptr %ptr, i32 %val) { 144; CHECK-LABEL: atomicrmw_udec_wrap_i32: 145; CHECK: @ %bb.0: 146; CHECK-NEXT: dmb ish 147; CHECK-NEXT: .LBB6_1: @ %atomicrmw.start 148; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 149; CHECK-NEXT: ldrex r12, [r0] 150; CHECK-NEXT: mov r3, r1 151; CHECK-NEXT: cmp r12, r1 152; CHECK-NEXT: subls r3, r12, #1 153; CHECK-NEXT: cmp r12, #0 154; CHECK-NEXT: moveq r3, r1 155; CHECK-NEXT: strex r2, r3, [r0] 156; CHECK-NEXT: cmp r2, #0 157; CHECK-NEXT: bne .LBB6_1 158; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 159; CHECK-NEXT: mov r0, r12 160; CHECK-NEXT: dmb ish 161; CHECK-NEXT: bx lr 162 %result = atomicrmw udec_wrap ptr %ptr, i32 %val seq_cst 163 ret i32 %result 164} 165 166define i64 @atomicrmw_udec_wrap_i64(ptr %ptr, i64 %val) { 167; CHECK-LABEL: atomicrmw_udec_wrap_i64: 168; CHECK: @ %bb.0: 169; CHECK-NEXT: .save {r4, r5, r6, r7, r11, lr} 170; CHECK-NEXT: push {r4, r5, r6, r7, r11, lr} 171; CHECK-NEXT: dmb ish 172; CHECK-NEXT: .LBB7_1: @ %atomicrmw.start 173; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1 174; CHECK-NEXT: ldrexd r4, r5, [r0] 175; CHECK-NEXT: mov r12, #0 176; CHECK-NEXT: subs r1, r2, r4 177; CHECK-NEXT: sbcs r1, r3, r5 178; CHECK-NEXT: orr r1, r4, r5 179; CHECK-NEXT: clz r1, r1 180; CHECK-NEXT: movwlo r12, #1 181; CHECK-NEXT: lsr r1, r1, #5 182; CHECK-NEXT: subs r6, r4, #1 183; CHECK-NEXT: sbc r7, r5, #0 184; CHECK-NEXT: orr r1, r1, r12 185; CHECK-NEXT: cmp r1, #0 186; CHECK-NEXT: movne r7, r3 187; CHECK-NEXT: movne r6, r2 188; CHECK-NEXT: strexd r1, r6, r7, [r0] 189; CHECK-NEXT: cmp r1, #0 190; CHECK-NEXT: bne .LBB7_1 191; CHECK-NEXT: @ %bb.2: @ %atomicrmw.end 192; CHECK-NEXT: mov r0, r4 193; CHECK-NEXT: mov r1, r5 194; CHECK-NEXT: dmb ish 195; CHECK-NEXT: pop {r4, r5, r6, r7, r11, pc} 196 %result = atomicrmw udec_wrap ptr %ptr, i64 %val seq_cst 197 ret i64 %result 198} 199