xref: /llvm-project/llvm/test/CodeGen/ARM/atomicrmw-uinc-udec-wrap.ll (revision e0ed0333f0fed2e73f805afd58b61176a87aa3ad)
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