blob: a39565e515c722c3590bffa61f4341a0a5442a17 [file] [log] [blame]
Christian Pirkerb5728192014-05-08 14:06:24 +00001; RUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-LE
2; RUN: llc -mtriple=armebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-BE
3; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE
4; RUN: llc -mtriple=thumbebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE
Amara Emersonb4ad2f32013-09-26 12:22:36 +00005
6@var8 = global i8 0
7@var16 = global i16 0
8@var32 = global i32 0
9@var64 = global i64 0
10
11define i8 @test_atomic_load_add_i8(i8 %offset) nounwind {
12; CHECK-LABEL: test_atomic_load_add_i8:
13 %old = atomicrmw add i8* @var8, i8 %offset seq_cst
14; CHECK-NOT: dmb
15; CHECK-NOT: mcr
16; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
17; CHECK: movt r[[ADDR]], :upper16:var8
18
19; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +000020; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +000021 ; r0 below is a reasonable guess but could change: it certainly comes into the
22 ; function there.
23; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
24; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
25; CHECK-NEXT: cmp [[STATUS]], #0
26; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
27; CHECK-NOT: dmb
28; CHECK-NOT: mcr
29
30; CHECK: mov r0, r[[OLD]]
31 ret i8 %old
32}
33
34define i16 @test_atomic_load_add_i16(i16 %offset) nounwind {
35; CHECK-LABEL: test_atomic_load_add_i16:
36 %old = atomicrmw add i16* @var16, i16 %offset acquire
37; CHECK-NOT: dmb
38; CHECK-NOT: mcr
39; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
40; CHECK: movt r[[ADDR]], :upper16:var16
41
42; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +000043; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +000044 ; r0 below is a reasonable guess but could change: it certainly comes into the
45 ; function there.
46; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
47; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
48; CHECK-NEXT: cmp [[STATUS]], #0
49; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
50; CHECK-NOT: dmb
51; CHECK-NOT: mcr
52
53; CHECK: mov r0, r[[OLD]]
54 ret i16 %old
55}
56
57define i32 @test_atomic_load_add_i32(i32 %offset) nounwind {
58; CHECK-LABEL: test_atomic_load_add_i32:
59 %old = atomicrmw add i32* @var32, i32 %offset release
60; CHECK-NOT: dmb
61; CHECK-NOT: mcr
62; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
63; CHECK: movt r[[ADDR]], :upper16:var32
64
65; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +000066; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +000067 ; r0 below is a reasonable guess but could change: it certainly comes into the
68 ; function there.
69; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
70; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
71; CHECK-NEXT: cmp [[STATUS]], #0
72; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
73; CHECK-NOT: dmb
74; CHECK-NOT: mcr
75
76; CHECK: mov r0, r[[OLD]]
77 ret i32 %old
78}
79
Tim Northoverc882eb02014-04-03 11:44:58 +000080define void @test_atomic_load_add_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +000081; CHECK-LABEL: test_atomic_load_add_i64:
82 %old = atomicrmw add i64* @var64, i64 %offset monotonic
83; CHECK-NOT: dmb
84; CHECK-NOT: mcr
85; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
86; CHECK: movt r[[ADDR]], :upper16:var64
87
88; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +000089; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +000090 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
91 ; function there.
Christian Pirkerb5728192014-05-08 14:06:24 +000092; CHECK-LE-NEXT: adds{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
93; CHECK-LE-NEXT: adc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1
94; CHECK-BE-NEXT: adds{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
95; CHECK-BE-NEXT: adc{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0
Amara Emersonb4ad2f32013-09-26 12:22:36 +000096; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
97; CHECK-NEXT: cmp [[STATUS]], #0
98; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
99; CHECK-NOT: dmb
100; CHECK-NOT: mcr
101
Tim Northoverc882eb02014-04-03 11:44:58 +0000102; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
103 store i64 %old, i64* @var64
104 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000105}
106
107define i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {
108; CHECK-LABEL: test_atomic_load_sub_i8:
109 %old = atomicrmw sub i8* @var8, i8 %offset monotonic
110; CHECK-NOT: dmb
111; CHECK-NOT: mcr
112; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
113; CHECK: movt r[[ADDR]], :upper16:var8
114
115; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000116; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000117 ; r0 below is a reasonable guess but could change: it certainly comes into the
118 ; function there.
119; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
120; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
121; CHECK-NEXT: cmp [[STATUS]], #0
122; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
123; CHECK-NOT: dmb
124; CHECK-NOT: mcr
125
126; CHECK: mov r0, r[[OLD]]
127 ret i8 %old
128}
129
130define i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {
131; CHECK-LABEL: test_atomic_load_sub_i16:
132 %old = atomicrmw sub i16* @var16, i16 %offset release
133; CHECK-NOT: dmb
134; CHECK-NOT: mcr
135; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
136; CHECK: movt r[[ADDR]], :upper16:var16
137
138; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000139; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000140 ; r0 below is a reasonable guess but could change: it certainly comes into the
141 ; function there.
142; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
143; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
144; CHECK-NEXT: cmp [[STATUS]], #0
145; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
146; CHECK-NOT: dmb
147; CHECK-NOT: mcr
148
149; CHECK: mov r0, r[[OLD]]
150 ret i16 %old
151}
152
153define i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {
154; CHECK-LABEL: test_atomic_load_sub_i32:
155 %old = atomicrmw sub i32* @var32, i32 %offset acquire
156; CHECK-NOT: dmb
157; CHECK-NOT: mcr
158; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
159; CHECK: movt r[[ADDR]], :upper16:var32
160
161; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000162; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000163 ; r0 below is a reasonable guess but could change: it certainly comes into the
164 ; function there.
165; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
166; CHECK-NEXT: strex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
167; CHECK-NEXT: cmp [[STATUS]], #0
168; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
169; CHECK-NOT: dmb
170; CHECK-NOT: mcr
171
172; CHECK: mov r0, r[[OLD]]
173 ret i32 %old
174}
175
Tim Northoverc882eb02014-04-03 11:44:58 +0000176define void @test_atomic_load_sub_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000177; CHECK-LABEL: test_atomic_load_sub_i64:
178 %old = atomicrmw sub i64* @var64, i64 %offset seq_cst
179; CHECK-NOT: dmb
180; CHECK-NOT: mcr
181; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
182; CHECK: movt r[[ADDR]], :upper16:var64
183
184; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000185; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000186 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
187 ; function there.
Christian Pirkerb5728192014-05-08 14:06:24 +0000188; CHECK-LE-NEXT: subs{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
189; CHECK-LE-NEXT: sbc{{(\.w)?}} [[NEW2:r[0-9]+]], r[[OLD2]], r1
190; CHECK-BE-NEXT: subs{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
191; CHECK-BE-NEXT: sbc{{(\.w)?}} [[NEW1:r[0-9]+]], r[[OLD1]], r0
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000192; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
193; CHECK-NEXT: cmp [[STATUS]], #0
194; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
195; CHECK-NOT: dmb
196; CHECK-NOT: mcr
197
Tim Northoverc882eb02014-04-03 11:44:58 +0000198; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
199 store i64 %old, i64* @var64
200 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000201}
202
203define i8 @test_atomic_load_and_i8(i8 %offset) nounwind {
204; CHECK-LABEL: test_atomic_load_and_i8:
205 %old = atomicrmw and i8* @var8, i8 %offset release
206; CHECK-NOT: dmb
207; CHECK-NOT: mcr
208; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
209; CHECK: movt r[[ADDR]], :upper16:var8
210
211; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000212; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000213 ; r0 below is a reasonable guess but could change: it certainly comes into the
214 ; function there.
215; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
216; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
217; CHECK-NEXT: cmp [[STATUS]], #0
218; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
219; CHECK-NOT: dmb
220; CHECK-NOT: mcr
221
222; CHECK: mov r0, r[[OLD]]
223 ret i8 %old
224}
225
226define i16 @test_atomic_load_and_i16(i16 %offset) nounwind {
227; CHECK-LABEL: test_atomic_load_and_i16:
228 %old = atomicrmw and i16* @var16, i16 %offset monotonic
229; CHECK-NOT: dmb
230; CHECK-NOT: mcr
231; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
232; CHECK: movt r[[ADDR]], :upper16:var16
233
234; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000235; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000236 ; r0 below is a reasonable guess but could change: it certainly comes into the
237 ; function there.
238; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
239; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
240; CHECK-NEXT: cmp [[STATUS]], #0
241; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
242; CHECK-NOT: dmb
243; CHECK-NOT: mcr
244
245; CHECK: mov r0, r[[OLD]]
246 ret i16 %old
247}
248
249define i32 @test_atomic_load_and_i32(i32 %offset) nounwind {
250; CHECK-LABEL: test_atomic_load_and_i32:
251 %old = atomicrmw and i32* @var32, i32 %offset seq_cst
252; CHECK-NOT: dmb
253; CHECK-NOT: mcr
254; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
255; CHECK: movt r[[ADDR]], :upper16:var32
256
257; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000258; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000259 ; r0 below is a reasonable guess but could change: it certainly comes into the
260 ; function there.
261; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
262; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
263; CHECK-NEXT: cmp [[STATUS]], #0
264; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
265; CHECK-NOT: dmb
266; CHECK-NOT: mcr
267
268; CHECK: mov r0, r[[OLD]]
269 ret i32 %old
270}
271
Tim Northoverc882eb02014-04-03 11:44:58 +0000272define void @test_atomic_load_and_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000273; CHECK-LABEL: test_atomic_load_and_i64:
274 %old = atomicrmw and i64* @var64, i64 %offset acquire
275; CHECK-NOT: dmb
276; CHECK-NOT: mcr
277; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
278; CHECK: movt r[[ADDR]], :upper16:var64
279
280; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000281; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000282 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
283 ; function there.
Christian Pirkerb5728192014-05-08 14:06:24 +0000284; CHECK-LE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
285; CHECK-LE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
286; CHECK-BE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
287; CHECK-BE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000288; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000289; CHECK-NEXT: cmp [[STATUS]], #0
290; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
291; CHECK-NOT: dmb
292; CHECK-NOT: mcr
293
Tim Northoverc882eb02014-04-03 11:44:58 +0000294; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
295 store i64 %old, i64* @var64
296 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000297}
298
299define i8 @test_atomic_load_or_i8(i8 %offset) nounwind {
300; CHECK-LABEL: test_atomic_load_or_i8:
301 %old = atomicrmw or i8* @var8, i8 %offset seq_cst
302; CHECK-NOT: dmb
303; CHECK-NOT: mcr
304; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
305; CHECK: movt r[[ADDR]], :upper16:var8
306
307; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000308; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000309 ; r0 below is a reasonable guess but could change: it certainly comes into the
310 ; function there.
311; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
312; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
313; CHECK-NEXT: cmp [[STATUS]], #0
314; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
315; CHECK-NOT: dmb
316; CHECK-NOT: mcr
317
318; CHECK: mov r0, r[[OLD]]
319 ret i8 %old
320}
321
322define i16 @test_atomic_load_or_i16(i16 %offset) nounwind {
323; CHECK-LABEL: test_atomic_load_or_i16:
324 %old = atomicrmw or i16* @var16, i16 %offset monotonic
325; CHECK-NOT: dmb
326; CHECK-NOT: mcr
327; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
328; CHECK: movt r[[ADDR]], :upper16:var16
329
330; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000331; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000332 ; r0 below is a reasonable guess but could change: it certainly comes into the
333 ; function there.
334; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
335; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
336; CHECK-NEXT: cmp [[STATUS]], #0
337; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
338; CHECK-NOT: dmb
339; CHECK-NOT: mcr
340
341; CHECK: mov r0, r[[OLD]]
342 ret i16 %old
343}
344
345define i32 @test_atomic_load_or_i32(i32 %offset) nounwind {
346; CHECK-LABEL: test_atomic_load_or_i32:
347 %old = atomicrmw or i32* @var32, i32 %offset acquire
348; CHECK-NOT: dmb
349; CHECK-NOT: mcr
350; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
351; CHECK: movt r[[ADDR]], :upper16:var32
352
353; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000354; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000355 ; r0 below is a reasonable guess but could change: it certainly comes into the
356 ; function there.
357; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
358; CHECK-NEXT: strex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
359; CHECK-NEXT: cmp [[STATUS]], #0
360; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
361; CHECK-NOT: dmb
362; CHECK-NOT: mcr
363
364; CHECK: mov r0, r[[OLD]]
365 ret i32 %old
366}
367
Tim Northoverc882eb02014-04-03 11:44:58 +0000368define void @test_atomic_load_or_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000369; CHECK-LABEL: test_atomic_load_or_i64:
370 %old = atomicrmw or i64* @var64, i64 %offset release
371; CHECK-NOT: dmb
372; CHECK-NOT: mcr
373; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
374; CHECK: movt r[[ADDR]], :upper16:var64
375
376; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000377; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000378 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
379 ; function there.
Christian Pirkerb5728192014-05-08 14:06:24 +0000380; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
381; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
382; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
383; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000384; CHECK: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000385; CHECK-NEXT: cmp [[STATUS]], #0
386; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
387; CHECK-NOT: dmb
388; CHECK-NOT: mcr
389
Tim Northoverc882eb02014-04-03 11:44:58 +0000390; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
391 store i64 %old, i64* @var64
392 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000393}
394
395define i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {
396; CHECK-LABEL: test_atomic_load_xor_i8:
397 %old = atomicrmw xor i8* @var8, i8 %offset acquire
398; CHECK-NOT: dmb
399; CHECK-NOT: mcr
400; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
401; CHECK: movt r[[ADDR]], :upper16:var8
402
403; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000404; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000405 ; r0 below is a reasonable guess but could change: it certainly comes into the
406 ; function there.
407; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
408; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
409; CHECK-NEXT: cmp [[STATUS]], #0
410; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
411; CHECK-NOT: dmb
412; CHECK-NOT: mcr
413
414; CHECK: mov r0, r[[OLD]]
415 ret i8 %old
416}
417
418define i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {
419; CHECK-LABEL: test_atomic_load_xor_i16:
420 %old = atomicrmw xor i16* @var16, i16 %offset release
421; CHECK-NOT: dmb
422; CHECK-NOT: mcr
423; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
424; CHECK: movt r[[ADDR]], :upper16:var16
425
426; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000427; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000428 ; r0 below is a reasonable guess but could change: it certainly comes into the
429 ; function there.
430; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
431; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
432; CHECK-NEXT: cmp [[STATUS]], #0
433; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
434; CHECK-NOT: dmb
435; CHECK-NOT: mcr
436
437; CHECK: mov r0, r[[OLD]]
438 ret i16 %old
439}
440
441define i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {
442; CHECK-LABEL: test_atomic_load_xor_i32:
443 %old = atomicrmw xor i32* @var32, i32 %offset seq_cst
444; CHECK-NOT: dmb
445; CHECK-NOT: mcr
446; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
447; CHECK: movt r[[ADDR]], :upper16:var32
448
449; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000450; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000451 ; r0 below is a reasonable guess but could change: it certainly comes into the
452 ; function there.
453; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
454; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
455; CHECK-NEXT: cmp [[STATUS]], #0
456; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
457; CHECK-NOT: dmb
458; CHECK-NOT: mcr
459
460; CHECK: mov r0, r[[OLD]]
461 ret i32 %old
462}
463
Tim Northoverc882eb02014-04-03 11:44:58 +0000464define void @test_atomic_load_xor_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000465; CHECK-LABEL: test_atomic_load_xor_i64:
466 %old = atomicrmw xor i64* @var64, i64 %offset monotonic
467; CHECK-NOT: dmb
468; CHECK-NOT: mcr
469; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
470; CHECK: movt r[[ADDR]], :upper16:var64
471
472; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000473; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000474 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
475 ; function there.
Christian Pirkerb5728192014-05-08 14:06:24 +0000476; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
477; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
478; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
479; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000480; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000481; CHECK-NEXT: cmp [[STATUS]], #0
482; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
483; CHECK-NOT: dmb
484; CHECK-NOT: mcr
485
Tim Northoverc882eb02014-04-03 11:44:58 +0000486; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
487 store i64 %old, i64* @var64
488 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000489}
490
491define i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {
492; CHECK-LABEL: test_atomic_load_xchg_i8:
493 %old = atomicrmw xchg i8* @var8, i8 %offset monotonic
494; CHECK-NOT: dmb
495; CHECK-NOT: mcr
496; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
497; CHECK: movt r[[ADDR]], :upper16:var8
498
499; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000500; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000501 ; r0 below is a reasonable guess but could change: it certainly comes into the
502 ; function there.
503; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]
504; CHECK-NEXT: cmp [[STATUS]], #0
505; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
506; CHECK-NOT: dmb
507; CHECK-NOT: mcr
508
509; CHECK: mov r0, r[[OLD]]
510 ret i8 %old
511}
512
513define i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {
514; CHECK-LABEL: test_atomic_load_xchg_i16:
515 %old = atomicrmw xchg i16* @var16, i16 %offset seq_cst
516; CHECK-NOT: dmb
517; CHECK-NOT: mcr
518; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
519; CHECK: movt r[[ADDR]], :upper16:var16
520
521; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000522; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000523 ; r0 below is a reasonable guess but could change: it certainly comes into the
524 ; function there.
525; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]
526; CHECK-NEXT: cmp [[STATUS]], #0
527; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
528; CHECK-NOT: dmb
529; CHECK-NOT: mcr
530
531; CHECK: mov r0, r[[OLD]]
532 ret i16 %old
533}
534
535define i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {
536; CHECK-LABEL: test_atomic_load_xchg_i32:
537 %old = atomicrmw xchg i32* @var32, i32 %offset release
538; CHECK-NOT: dmb
539; CHECK-NOT: mcr
540; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
541; CHECK: movt r[[ADDR]], :upper16:var32
542
543; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000544; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000545 ; r0 below is a reasonable guess but could change: it certainly comes into the
546 ; function there.
547; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]
548; CHECK-NEXT: cmp [[STATUS]], #0
549; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
550; CHECK-NOT: dmb
551; CHECK-NOT: mcr
552
553; CHECK: mov r0, r[[OLD]]
554 ret i32 %old
555}
556
Tim Northoverc882eb02014-04-03 11:44:58 +0000557define void @test_atomic_load_xchg_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000558; CHECK-LABEL: test_atomic_load_xchg_i64:
559 %old = atomicrmw xchg i64* @var64, i64 %offset acquire
560; CHECK-NOT: dmb
561; CHECK-NOT: mcr
562; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
563; CHECK: movt r[[ADDR]], :upper16:var64
564
565; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000566; CHECK: ldaexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000567 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
568 ; function there.
569; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], r0, r1, [r[[ADDR]]]
570; CHECK-NEXT: cmp [[STATUS]], #0
571; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
572; CHECK-NOT: dmb
573; CHECK-NOT: mcr
574
Tim Northoverc882eb02014-04-03 11:44:58 +0000575; CHECK: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
576 store i64 %old, i64* @var64
577 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000578}
579
Tim Northoverc882eb02014-04-03 11:44:58 +0000580define i8 @test_atomic_load_min_i8(i8 signext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000581; CHECK-LABEL: test_atomic_load_min_i8:
582 %old = atomicrmw min i8* @var8, i8 %offset acquire
583; CHECK-NOT: dmb
584; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +0000585; CHECK-DAG: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
586; CHECK-DAG: movt [[ADDR]], :upper16:var8
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000587
588; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000589; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000590; CHECK-NEXT: sxtb r[[OLDX:[0-9]+]], r[[OLD]]
591 ; r0 below is a reasonable guess but could change: it certainly comes into the
592 ; function there.
593; CHECK-NEXT: cmp r[[OLDX]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000594; Thumb mode: it le
595; CHECK: movle r[[OLDX]], r[[OLD]]
596; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000597; CHECK-NEXT: cmp [[STATUS]], #0
598; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
599; CHECK-NOT: dmb
600; CHECK-NOT: mcr
601
602; CHECK: mov r0, r[[OLD]]
603 ret i8 %old
604}
605
Tim Northoverc882eb02014-04-03 11:44:58 +0000606define i16 @test_atomic_load_min_i16(i16 signext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000607; CHECK-LABEL: test_atomic_load_min_i16:
608 %old = atomicrmw min i16* @var16, i16 %offset release
609; CHECK-NOT: dmb
610; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +0000611; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16
612; CHECK: movt [[ADDR]], :upper16:var16
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000613
614; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000615; CHECK: ldrexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000616; CHECK-NEXT: sxth r[[OLDX:[0-9]+]], r[[OLD]]
617 ; r0 below is a reasonable guess but could change: it certainly comes into the
618 ; function there.
619; CHECK-NEXT: cmp r[[OLDX]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000620; Thumb mode: it le
621; CHECK: movle r[[OLDX]], r[[OLD]]
622; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000623; CHECK-NEXT: cmp [[STATUS]], #0
624; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
625; CHECK-NOT: dmb
626; CHECK-NOT: mcr
627
628; CHECK: mov r0, r[[OLD]]
629 ret i16 %old
630}
631
632define i32 @test_atomic_load_min_i32(i32 %offset) nounwind {
633; CHECK-LABEL: test_atomic_load_min_i32:
634 %old = atomicrmw min i32* @var32, i32 %offset monotonic
635; CHECK-NOT: dmb
636; CHECK-NOT: mcr
637; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
638; CHECK: movt r[[ADDR]], :upper16:var32
639
640; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000641; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000642 ; r0 below is a reasonable guess but could change: it certainly comes into the
643 ; function there.
644; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
645; CHECK-NEXT: cmp r[[OLD]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000646; Thumb mode: it le
647; CHECK: movle r[[NEW]], r[[OLD]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000648; CHECK-NEXT: strex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
649; CHECK-NEXT: cmp [[STATUS]], #0
650; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
651; CHECK-NOT: dmb
652; CHECK-NOT: mcr
653
654; CHECK: mov r0, r[[OLD]]
655 ret i32 %old
656}
657
Tim Northoverc882eb02014-04-03 11:44:58 +0000658define void @test_atomic_load_min_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000659; CHECK-LABEL: test_atomic_load_min_i64:
660 %old = atomicrmw min i64* @var64, i64 %offset seq_cst
661; CHECK-NOT: dmb
662; CHECK-NOT: mcr
663; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
664; CHECK: movt r[[ADDR]], :upper16:var64
665
666; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000667; CHECK: ldaexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000668 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
669 ; function there.
Tim Northoverc882eb02014-04-03 11:44:58 +0000670; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
671; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
Christian Pirkerb5728192014-05-08 14:06:24 +0000672; CHECK-ARM-LE: cmp [[OLD1]], r0
673; CHECK-ARM-LE: movwls [[LOCARRY]], #1
674; CHECK-ARM-LE: cmp [[OLD2]], r1
675; CHECK-ARM-LE: movwle [[HICARRY]], #1
676; CHECK-ARM-BE: cmp [[OLD2]], r1
677; CHECK-ARM-BE: movwls [[LOCARRY]], #1
678; CHECK-ARM-BE: cmp [[OLD1]], r0
679; CHECK-ARM-BE: movwle [[HICARRY]], #1
Tim Northoverc882eb02014-04-03 11:44:58 +0000680; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
681; CHECK-ARM: cmp [[HICARRY]], #0
682; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
683; CHECK-ARM: movne [[MINHI]], [[OLD2]]
684; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
685; CHECK-ARM: movne [[MINLO]], [[OLD1]]
686; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
687; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000688; CHECK-NEXT: cmp [[STATUS]], #0
689; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
690; CHECK-NOT: dmb
691; CHECK-NOT: mcr
692
Tim Northoverc882eb02014-04-03 11:44:58 +0000693; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
694 store i64 %old, i64* @var64
695 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000696}
697
Tim Northoverc882eb02014-04-03 11:44:58 +0000698define i8 @test_atomic_load_max_i8(i8 signext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000699; CHECK-LABEL: test_atomic_load_max_i8:
700 %old = atomicrmw max i8* @var8, i8 %offset seq_cst
701; CHECK-NOT: dmb
702; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +0000703; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
704; CHECK: movt [[ADDR]], :upper16:var8
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000705
706; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000707; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000708; CHECK-NEXT: sxtb r[[OLDX:[0-9]+]], r[[OLD]]
709 ; r0 below is a reasonable guess but could change: it certainly comes into the
710 ; function there.
711; CHECK-NEXT: cmp r[[OLDX]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000712; Thumb mode: it gt
713; CHECK: movgt r[[OLDX]], r[[OLD]]
714; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000715; CHECK-NEXT: cmp [[STATUS]], #0
716; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
717; CHECK-NOT: dmb
718; CHECK-NOT: mcr
719
720; CHECK: mov r0, r[[OLD]]
721 ret i8 %old
722}
723
Tim Northoverc882eb02014-04-03 11:44:58 +0000724define i16 @test_atomic_load_max_i16(i16 signext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000725; CHECK-LABEL: test_atomic_load_max_i16:
726 %old = atomicrmw max i16* @var16, i16 %offset acquire
727; CHECK-NOT: dmb
728; CHECK-NOT: mcr
729; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
730; CHECK: movt r[[ADDR]], :upper16:var16
731
732; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000733; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000734; CHECK-NEXT: sxth r[[OLDX:[0-9]+]], r[[OLD]]
735 ; r0 below is a reasonable guess but could change: it certainly comes into the
736 ; function there.
737; CHECK-NEXT: cmp r[[OLDX]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000738; Thumb mode: it gt
739; CHECK: movgt r[[OLDX]], r[[OLD]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000740; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[OLDX]], [r[[ADDR]]]
741; CHECK-NEXT: cmp [[STATUS]], #0
742; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
743; CHECK-NOT: dmb
744; CHECK-NOT: mcr
745
746; CHECK: mov r0, r[[OLD]]
747 ret i16 %old
748}
749
750define i32 @test_atomic_load_max_i32(i32 %offset) nounwind {
751; CHECK-LABEL: test_atomic_load_max_i32:
752 %old = atomicrmw max i32* @var32, i32 %offset release
753; CHECK-NOT: dmb
754; CHECK-NOT: mcr
755; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
756; CHECK: movt r[[ADDR]], :upper16:var32
757
758; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000759; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000760 ; r0 below is a reasonable guess but could change: it certainly comes into the
761 ; function there.
762; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
763; CHECK-NEXT: cmp r[[OLD]], r0
764; Thumb mode: it gt
765; CHECK: movgt r[[NEW]], r[[OLD]]
766; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
767; CHECK-NEXT: cmp [[STATUS]], #0
768; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
769; CHECK-NOT: dmb
770; CHECK-NOT: mcr
771
772; CHECK: mov r0, r[[OLD]]
773 ret i32 %old
774}
775
Tim Northoverc882eb02014-04-03 11:44:58 +0000776define void @test_atomic_load_max_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000777; CHECK-LABEL: test_atomic_load_max_i64:
778 %old = atomicrmw max i64* @var64, i64 %offset monotonic
779; CHECK-NOT: dmb
780; CHECK-NOT: mcr
781; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
782; CHECK: movt r[[ADDR]], :upper16:var64
783
784; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000785; CHECK: ldrexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000786 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
787 ; function there.
Tim Northoverc882eb02014-04-03 11:44:58 +0000788; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
789; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
Christian Pirkerb5728192014-05-08 14:06:24 +0000790; CHECK-ARM-LE: cmp [[OLD1]], r0
791; CHECK-ARM-LE: movwhi [[LOCARRY]], #1
792; CHECK-ARM-LE: cmp [[OLD2]], r1
793; CHECK-ARM-LE: movwgt [[HICARRY]], #1
794; CHECK-ARM-BE: cmp [[OLD2]], r1
795; CHECK-ARM-BE: movwhi [[LOCARRY]], #1
796; CHECK-ARM-BE: cmp [[OLD1]], r0
797; CHECK-ARM-BE: movwgt [[HICARRY]], #1
Tim Northoverc882eb02014-04-03 11:44:58 +0000798; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
799; CHECK-ARM: cmp [[HICARRY]], #0
800; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
801; CHECK-ARM: movne [[MINHI]], [[OLD2]]
802; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
803; CHECK-ARM: movne [[MINLO]], [[OLD1]]
804; CHECK-ARM: strexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
805; CHECK-THUMB: strexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000806; CHECK-NEXT: cmp [[STATUS]], #0
807; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
808; CHECK-NOT: dmb
809; CHECK-NOT: mcr
810
Tim Northoverc882eb02014-04-03 11:44:58 +0000811; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
812 store i64 %old, i64* @var64
813 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000814}
815
Tim Northoverc882eb02014-04-03 11:44:58 +0000816define i8 @test_atomic_load_umin_i8(i8 zeroext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000817; CHECK-LABEL: test_atomic_load_umin_i8:
818 %old = atomicrmw umin i8* @var8, i8 %offset monotonic
819; CHECK-NOT: dmb
820; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +0000821; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
822; CHECK: movt [[ADDR]], :upper16:var8
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000823
824; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000825; CHECK: ldrexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000826 ; r0 below is a reasonable guess but could change: it certainly comes into the
827 ; function there.
Tim Northover01b4aa92014-04-03 15:10:35 +0000828; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
829; CHECK-NEXT: cmp r[[OLD]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000830; Thumb mode: it ls
831; CHECK: movls r[[NEW]], r[[OLD]]
832; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000833; CHECK-NEXT: cmp [[STATUS]], #0
834; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
835; CHECK-NOT: dmb
836; CHECK-NOT: mcr
837
838; CHECK: mov r0, r[[OLD]]
839 ret i8 %old
840}
841
Tim Northoverc882eb02014-04-03 11:44:58 +0000842define i16 @test_atomic_load_umin_i16(i16 zeroext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000843; CHECK-LABEL: test_atomic_load_umin_i16:
844 %old = atomicrmw umin i16* @var16, i16 %offset acquire
845; CHECK-NOT: dmb
846; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +0000847; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16
848; CHECK: movt [[ADDR]], :upper16:var16
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000849
850; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000851; CHECK: ldaexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000852 ; r0 below is a reasonable guess but could change: it certainly comes into the
853 ; function there.
Tim Northover01b4aa92014-04-03 15:10:35 +0000854; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
855; CHECK-NEXT: cmp r[[OLD]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000856; Thumb mode: it ls
857; CHECK: movls r[[NEW]], r[[OLD]]
858; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000859; CHECK-NEXT: cmp [[STATUS]], #0
860; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
861; CHECK-NOT: dmb
862; CHECK-NOT: mcr
863
864; CHECK: mov r0, r[[OLD]]
865 ret i16 %old
866}
867
868define i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {
869; CHECK-LABEL: test_atomic_load_umin_i32:
870 %old = atomicrmw umin i32* @var32, i32 %offset seq_cst
871; CHECK-NOT: dmb
872; CHECK-NOT: mcr
873; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
874; CHECK: movt r[[ADDR]], :upper16:var32
875
876; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000877; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000878 ; r0 below is a reasonable guess but could change: it certainly comes into the
879 ; function there.
880; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
881; CHECK-NEXT: cmp r[[OLD]], r0
Tim Northoverc882eb02014-04-03 11:44:58 +0000882; Thumb mode: it ls
883; CHECK: movls r[[NEW]], r[[OLD]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000884; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
885; CHECK-NEXT: cmp [[STATUS]], #0
886; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
887; CHECK-NOT: dmb
888; CHECK-NOT: mcr
889
890; CHECK: mov r0, r[[OLD]]
891 ret i32 %old
892}
893
Tim Northoverc882eb02014-04-03 11:44:58 +0000894define void @test_atomic_load_umin_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000895; CHECK-LABEL: test_atomic_load_umin_i64:
Tim Northoverc882eb02014-04-03 11:44:58 +0000896 %old = atomicrmw umin i64* @var64, i64 %offset seq_cst
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000897; CHECK-NOT: dmb
898; CHECK-NOT: mcr
899; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
900; CHECK: movt r[[ADDR]], :upper16:var64
901
902; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000903; CHECK: ldaexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000904 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
905 ; function there.
Tim Northoverc882eb02014-04-03 11:44:58 +0000906; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
907; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
Christian Pirkerb5728192014-05-08 14:06:24 +0000908; CHECK-ARM-LE: cmp [[OLD1]], r0
909; CHECK-ARM-LE: movwls [[LOCARRY]], #1
910; CHECK-ARM-LE: cmp [[OLD2]], r1
911; CHECK-ARM-LE: movwls [[HICARRY]], #1
912; CHECK-ARM-BE: cmp [[OLD2]], r1
913; CHECK-ARM-BE: movwls [[LOCARRY]], #1
914; CHECK-ARM-BE: cmp [[OLD1]], r0
915; CHECK-ARM-BE: movwls [[HICARRY]], #1
Tim Northoverc882eb02014-04-03 11:44:58 +0000916; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
917; CHECK-ARM: cmp [[HICARRY]], #0
918; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
919; CHECK-ARM: movne [[MINHI]], [[OLD2]]
920; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
921; CHECK-ARM: movne [[MINLO]], [[OLD1]]
922; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
923; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000924; CHECK-NEXT: cmp [[STATUS]], #0
925; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
926; CHECK-NOT: dmb
927; CHECK-NOT: mcr
928
Tim Northoverc882eb02014-04-03 11:44:58 +0000929; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
930 store i64 %old, i64* @var64
931 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000932}
933
Tim Northoverc882eb02014-04-03 11:44:58 +0000934define i8 @test_atomic_load_umax_i8(i8 zeroext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000935; CHECK-LABEL: test_atomic_load_umax_i8:
936 %old = atomicrmw umax i8* @var8, i8 %offset acq_rel
937; CHECK-NOT: dmb
938; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +0000939; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
940; CHECK: movt [[ADDR]], :upper16:var8
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000941
942; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000943; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000944 ; r0 below is a reasonable guess but could change: it certainly comes into the
945 ; function there.
Tim Northover01b4aa92014-04-03 15:10:35 +0000946; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
947; CHECK-NEXT: cmp r[[OLD]], r0
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000948; Thumb mode: it hi
949; CHECK: movhi r[[NEW]], r[[OLD]]
Tim Northoverc882eb02014-04-03 11:44:58 +0000950; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000951; CHECK-NEXT: cmp [[STATUS]], #0
952; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
953; CHECK-NOT: dmb
954; CHECK-NOT: mcr
955
956; CHECK: mov r0, r[[OLD]]
957 ret i8 %old
958}
959
Tim Northoverc882eb02014-04-03 11:44:58 +0000960define i16 @test_atomic_load_umax_i16(i16 zeroext %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000961; CHECK-LABEL: test_atomic_load_umax_i16:
962 %old = atomicrmw umax i16* @var16, i16 %offset monotonic
963; CHECK-NOT: dmb
964; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +0000965; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16
966; CHECK: movt [[ADDR]], :upper16:var16
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000967
968; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000969; CHECK: ldrexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000970 ; r0 below is a reasonable guess but could change: it certainly comes into the
971 ; function there.
Tim Northover01b4aa92014-04-03 15:10:35 +0000972; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
973; CHECK-NEXT: cmp r[[OLD]], r0
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000974; Thumb mode: it hi
975; CHECK: movhi r[[NEW]], r[[OLD]]
Tim Northoverc882eb02014-04-03 11:44:58 +0000976; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000977; CHECK-NEXT: cmp [[STATUS]], #0
978; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
979; CHECK-NOT: dmb
980; CHECK-NOT: mcr
981
982; CHECK: mov r0, r[[OLD]]
983 ret i16 %old
984}
985
986define i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {
987; CHECK-LABEL: test_atomic_load_umax_i32:
988 %old = atomicrmw umax i32* @var32, i32 %offset seq_cst
989; CHECK-NOT: dmb
990; CHECK-NOT: mcr
991; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
992; CHECK: movt r[[ADDR]], :upper16:var32
993
994; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +0000995; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +0000996 ; r0 below is a reasonable guess but could change: it certainly comes into the
997 ; function there.
998; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
999; CHECK-NEXT: cmp r[[OLD]], r0
1000; Thumb mode: it hi
1001; CHECK: movhi r[[NEW]], r[[OLD]]
1002; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
1003; CHECK-NEXT: cmp [[STATUS]], #0
1004; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1005; CHECK-NOT: dmb
1006; CHECK-NOT: mcr
1007
1008; CHECK: mov r0, r[[OLD]]
1009 ret i32 %old
1010}
1011
Tim Northoverc882eb02014-04-03 11:44:58 +00001012define void @test_atomic_load_umax_i64(i64 %offset) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001013; CHECK-LABEL: test_atomic_load_umax_i64:
Tim Northoverc882eb02014-04-03 11:44:58 +00001014 %old = atomicrmw umax i64* @var64, i64 %offset seq_cst
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001015; CHECK-NOT: dmb
1016; CHECK-NOT: mcr
1017; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
1018; CHECK: movt r[[ADDR]], :upper16:var64
1019
1020; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +00001021; CHECK: ldaexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001022 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
1023 ; function there.
Tim Northoverc882eb02014-04-03 11:44:58 +00001024; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
1025; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
Christian Pirkerb5728192014-05-08 14:06:24 +00001026; CHECK-ARM-LE: cmp [[OLD1]], r0
1027; CHECK-ARM-LE: movwhi [[LOCARRY]], #1
1028; CHECK-ARM-LE: cmp [[OLD2]], r1
1029; CHECK-ARM-LE: movwhi [[HICARRY]], #1
1030; CHECK-ARM-BE: cmp [[OLD2]], r1
1031; CHECK-ARM-BE: movwhi [[LOCARRY]], #1
1032; CHECK-ARM-BE: cmp [[OLD1]], r0
1033; CHECK-ARM-BE: movwhi [[HICARRY]], #1
Tim Northoverc882eb02014-04-03 11:44:58 +00001034; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
1035; CHECK-ARM: cmp [[HICARRY]], #0
1036; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
1037; CHECK-ARM: movne [[MINHI]], [[OLD2]]
1038; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
1039; CHECK-ARM: movne [[MINLO]], [[OLD1]]
1040; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
1041; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001042; CHECK-NEXT: cmp [[STATUS]], #0
1043; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1044; CHECK-NOT: dmb
1045; CHECK-NOT: mcr
1046
Tim Northoverc882eb02014-04-03 11:44:58 +00001047; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
1048 store i64 %old, i64* @var64
1049 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001050}
1051
Tim Northoverc882eb02014-04-03 11:44:58 +00001052define i8 @test_atomic_cmpxchg_i8(i8 zeroext %wanted, i8 zeroext %new) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001053; CHECK-LABEL: test_atomic_cmpxchg_i8:
Tim Northovere94a5182014-03-11 10:48:52 +00001054 %old = cmpxchg i8* @var8, i8 %wanted, i8 %new acquire acquire
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001055; CHECK-NOT: dmb
1056; CHECK-NOT: mcr
1057; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1058; CHECK: movt r[[ADDR]], :upper16:var8
1059
1060; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +00001061; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001062 ; r0 below is a reasonable guess but could change: it certainly comes into the
1063 ; function there.
Tim Northover01b4aa92014-04-03 15:10:35 +00001064; CHECK-NEXT: cmp r[[OLD]], r0
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001065; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1066; CHECK-NEXT: BB#2:
1067 ; As above, r1 is a reasonable guess.
Tim Northoverc882eb02014-04-03 11:44:58 +00001068; CHECK: strexb [[STATUS:r[0-9]+]], r1, {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001069; CHECK-NEXT: cmp [[STATUS]], #0
1070; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1071; CHECK-NOT: dmb
1072; CHECK-NOT: mcr
1073
1074; CHECK: mov r0, r[[OLD]]
1075 ret i8 %old
1076}
1077
Tim Northoverc882eb02014-04-03 11:44:58 +00001078define i16 @test_atomic_cmpxchg_i16(i16 zeroext %wanted, i16 zeroext %new) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001079; CHECK-LABEL: test_atomic_cmpxchg_i16:
Tim Northovere94a5182014-03-11 10:48:52 +00001080 %old = cmpxchg i16* @var16, i16 %wanted, i16 %new seq_cst seq_cst
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001081; CHECK-NOT: dmb
1082; CHECK-NOT: mcr
1083; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
1084; CHECK: movt r[[ADDR]], :upper16:var16
1085
1086; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +00001087; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001088 ; r0 below is a reasonable guess but could change: it certainly comes into the
1089 ; function there.
Tim Northover01b4aa92014-04-03 15:10:35 +00001090; CHECK-NEXT: cmp r[[OLD]], r0
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001091; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1092; CHECK-NEXT: BB#2:
1093 ; As above, r1 is a reasonable guess.
Tim Northoverc882eb02014-04-03 11:44:58 +00001094; CHECK: stlexh [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001095; CHECK-NEXT: cmp [[STATUS]], #0
1096; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1097; CHECK-NOT: dmb
1098; CHECK-NOT: mcr
1099
1100; CHECK: mov r0, r[[OLD]]
1101 ret i16 %old
1102}
1103
Tim Northover70450c52014-04-03 13:06:54 +00001104define void @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001105; CHECK-LABEL: test_atomic_cmpxchg_i32:
Tim Northovere94a5182014-03-11 10:48:52 +00001106 %old = cmpxchg i32* @var32, i32 %wanted, i32 %new release monotonic
Tim Northover70450c52014-04-03 13:06:54 +00001107 store i32 %old, i32* @var32
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001108; CHECK-NOT: dmb
1109; CHECK-NOT: mcr
1110; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
1111; CHECK: movt r[[ADDR]], :upper16:var32
1112
1113; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +00001114; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001115 ; r0 below is a reasonable guess but could change: it certainly comes into the
1116 ; function there.
1117; CHECK-NEXT: cmp r[[OLD]], r0
1118; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1119; CHECK-NEXT: BB#2:
1120 ; As above, r1 is a reasonable guess.
Tim Northoverc882eb02014-04-03 11:44:58 +00001121; CHECK: stlex [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001122; CHECK-NEXT: cmp [[STATUS]], #0
1123; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1124; CHECK-NOT: dmb
1125; CHECK-NOT: mcr
1126
Tim Northover70450c52014-04-03 13:06:54 +00001127; CHECK: str{{(.w)?}} r[[OLD]],
1128 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001129}
1130
Tim Northoverc882eb02014-04-03 11:44:58 +00001131define void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001132; CHECK-LABEL: test_atomic_cmpxchg_i64:
Tim Northovere94a5182014-03-11 10:48:52 +00001133 %old = cmpxchg i64* @var64, i64 %wanted, i64 %new monotonic monotonic
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001134; CHECK-NOT: dmb
1135; CHECK-NOT: mcr
1136; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
1137; CHECK: movt r[[ADDR]], :upper16:var64
1138
1139; CHECK: .LBB{{[0-9]+}}_1:
Tim Northoverc882eb02014-04-03 11:44:58 +00001140; CHECK: ldrexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001141 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
1142 ; function there.
Christian Pirkerb5728192014-05-08 14:06:24 +00001143; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0
1144; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1
1145; CHECK-LE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
1146; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1
1147; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0
1148; CHECK-BE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_HI]], [[MISMATCH_LO]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001149; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1150; CHECK-NEXT: BB#2:
1151 ; As above, r2, r3 is a reasonable guess.
Tim Northoverc882eb02014-04-03 11:44:58 +00001152; CHECK: strexd [[STATUS:r[0-9]+]], r2, r3, [r[[ADDR]]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001153; CHECK-NEXT: cmp [[STATUS]], #0
1154; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1155; CHECK-NOT: dmb
1156; CHECK-NOT: mcr
1157
Tim Northoverc882eb02014-04-03 11:44:58 +00001158; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
1159 store i64 %old, i64* @var64
1160 ret void
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001161}
1162
1163define i8 @test_atomic_load_monotonic_i8() nounwind {
1164; CHECK-LABEL: test_atomic_load_monotonic_i8:
1165 %val = load atomic i8* @var8 monotonic, align 1
1166; CHECK-NOT: dmb
1167; CHECK-NOT: mcr
1168; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1169; CHECK: movt r[[ADDR]], :upper16:var8
1170; CHECK: ldrb r0, [r[[ADDR]]]
1171; CHECK-NOT: dmb
1172; CHECK-NOT: mcr
1173
1174 ret i8 %val
1175}
1176
1177define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
1178; CHECK-LABEL: test_atomic_load_monotonic_regoff_i8:
1179 %addr_int = add i64 %base, %off
1180 %addr = inttoptr i64 %addr_int to i8*
1181
1182 %val = load atomic i8* %addr monotonic, align 1
1183; CHECK-NOT: dmb
1184; CHECK-NOT: mcr
Christian Pirkerb5728192014-05-08 14:06:24 +00001185; CHECK-LE: ldrb r0, [r0, r2]
1186; CHECK-BE: ldrb r0, [r1, r3]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001187; CHECK-NOT: dmb
1188; CHECK-NOT: mcr
1189
1190 ret i8 %val
1191}
1192
1193define i8 @test_atomic_load_acquire_i8() nounwind {
1194; CHECK-LABEL: test_atomic_load_acquire_i8:
1195 %val = load atomic i8* @var8 acquire, align 1
1196; CHECK-NOT: dmb
1197; CHECK-NOT: mcr
1198; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1199; CHECK-NOT: dmb
1200; CHECK-NOT: mcr
1201; CHECK: movt r[[ADDR]], :upper16:var8
1202; CHECK-NOT: dmb
1203; CHECK-NOT: mcr
1204; CHECK: ldab r0, [r[[ADDR]]]
1205; CHECK-NOT: dmb
1206; CHECK-NOT: mcr
1207 ret i8 %val
1208}
1209
1210define i8 @test_atomic_load_seq_cst_i8() nounwind {
1211; CHECK-LABEL: test_atomic_load_seq_cst_i8:
1212 %val = load atomic i8* @var8 seq_cst, align 1
1213; CHECK-NOT: dmb
1214; CHECK-NOT: mcr
1215; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1216; CHECK-NOT: dmb
1217; CHECK-NOT: mcr
1218; CHECK: movt r[[ADDR]], :upper16:var8
1219; CHECK-NOT: dmb
1220; CHECK-NOT: mcr
1221; CHECK: ldab r0, [r[[ADDR]]]
1222; CHECK-NOT: dmb
1223; CHECK-NOT: mcr
1224 ret i8 %val
1225}
1226
1227define i16 @test_atomic_load_monotonic_i16() nounwind {
1228; CHECK-LABEL: test_atomic_load_monotonic_i16:
1229 %val = load atomic i16* @var16 monotonic, align 2
1230; CHECK-NOT: dmb
1231; CHECK-NOT: mcr
1232; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
1233; CHECK-NOT: dmb
1234; CHECK-NOT: mcr
1235; CHECK: movt r[[ADDR]], :upper16:var16
1236; CHECK-NOT: dmb
1237; CHECK-NOT: mcr
1238; CHECK: ldrh r0, [r[[ADDR]]]
1239; CHECK-NOT: dmb
1240; CHECK-NOT: mcr
1241
1242 ret i16 %val
1243}
1244
1245define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {
1246; CHECK-LABEL: test_atomic_load_monotonic_regoff_i32:
1247 %addr_int = add i64 %base, %off
1248 %addr = inttoptr i64 %addr_int to i32*
1249
1250 %val = load atomic i32* %addr monotonic, align 4
1251; CHECK-NOT: dmb
1252; CHECK-NOT: mcr
Christian Pirkerb5728192014-05-08 14:06:24 +00001253; CHECK-LE: ldr r0, [r0, r2]
1254; CHECK-BE: ldr r0, [r1, r3]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001255; CHECK-NOT: dmb
1256; CHECK-NOT: mcr
1257
1258 ret i32 %val
1259}
1260
1261define i64 @test_atomic_load_seq_cst_i64() nounwind {
1262; CHECK-LABEL: test_atomic_load_seq_cst_i64:
1263 %val = load atomic i64* @var64 seq_cst, align 8
1264; CHECK-NOT: dmb
1265; CHECK-NOT: mcr
1266; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
1267; CHECK-NOT: dmb
1268; CHECK-NOT: mcr
1269; CHECK: movt r[[ADDR]], :upper16:var64
1270; CHECK-NOT: dmb
1271; CHECK-NOT: mcr
1272; CHECK: ldaexd r0, r1, [r[[ADDR]]]
1273; CHECK-NOT: dmb
1274; CHECK-NOT: mcr
1275 ret i64 %val
1276}
1277
1278define void @test_atomic_store_monotonic_i8(i8 %val) nounwind {
1279; CHECK-LABEL: test_atomic_store_monotonic_i8:
1280 store atomic i8 %val, i8* @var8 monotonic, align 1
1281; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1282; CHECK: movt r[[ADDR]], :upper16:var8
1283; CHECK: strb r0, [r[[ADDR]]]
1284
1285 ret void
1286}
1287
1288define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {
1289; CHECK-LABEL: test_atomic_store_monotonic_regoff_i8:
1290
1291 %addr_int = add i64 %base, %off
1292 %addr = inttoptr i64 %addr_int to i8*
1293
1294 store atomic i8 %val, i8* %addr monotonic, align 1
Christian Pirkerb5728192014-05-08 14:06:24 +00001295; CHECK-LE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp]
1296; CHECK-LE: strb [[VAL]], [r0, r2]
1297; CHECK-BE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp, #3]
1298; CHECK-BE: strb [[VAL]], [r1, r3]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001299
1300 ret void
1301}
1302
1303define void @test_atomic_store_release_i8(i8 %val) nounwind {
1304; CHECK-LABEL: test_atomic_store_release_i8:
1305 store atomic i8 %val, i8* @var8 release, align 1
1306; CHECK-NOT: dmb
1307; CHECK-NOT: mcr
1308; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1309; CHECK-NOT: dmb
1310; CHECK-NOT: mcr
1311; CHECK: movt r[[ADDR]], :upper16:var8
1312; CHECK-NOT: dmb
1313; CHECK-NOT: mcr
1314; CHECK: stlb r0, [r[[ADDR]]]
1315; CHECK-NOT: dmb
1316; CHECK-NOT: mcr
1317 ret void
1318}
1319
1320define void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {
1321; CHECK-LABEL: test_atomic_store_seq_cst_i8:
1322 store atomic i8 %val, i8* @var8 seq_cst, align 1
1323; CHECK-NOT: dmb
1324; CHECK-NOT: mcr
1325; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1326; CHECK-NOT: dmb
1327; CHECK-NOT: mcr
1328; CHECK: movt r[[ADDR]], :upper16:var8
1329; CHECK-NOT: dmb
1330; CHECK-NOT: mcr
1331; CHECK: stlb r0, [r[[ADDR]]]
1332; CHECK-NOT: dmb
1333; CHECK-NOT: mcr
1334 ret void
1335}
1336
1337define void @test_atomic_store_monotonic_i16(i16 %val) nounwind {
1338; CHECK-LABEL: test_atomic_store_monotonic_i16:
1339 store atomic i16 %val, i16* @var16 monotonic, align 2
1340; CHECK-NOT: dmb
1341; CHECK-NOT: mcr
1342; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
1343; CHECK-NOT: dmb
1344; CHECK-NOT: mcr
1345; CHECK: movt r[[ADDR]], :upper16:var16
1346; CHECK-NOT: dmb
1347; CHECK-NOT: mcr
1348; CHECK: strh r0, [r[[ADDR]]]
1349; CHECK-NOT: dmb
1350; CHECK-NOT: mcr
1351 ret void
1352}
1353
1354define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {
1355; CHECK-LABEL: test_atomic_store_monotonic_regoff_i32:
1356
1357 %addr_int = add i64 %base, %off
1358 %addr = inttoptr i64 %addr_int to i32*
1359
1360 store atomic i32 %val, i32* %addr monotonic, align 4
1361; CHECK-NOT: dmb
1362; CHECK-NOT: mcr
1363; CHECK: ldr [[VAL:r[0-9]+]], [sp]
1364; CHECK-NOT: dmb
1365; CHECK-NOT: mcr
Christian Pirkerb5728192014-05-08 14:06:24 +00001366; CHECK-LE: str [[VAL]], [r0, r2]
1367; CHECK-BE: str [[VAL]], [r1, r3]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001368; CHECK-NOT: dmb
1369; CHECK-NOT: mcr
1370
1371 ret void
1372}
1373
1374define void @test_atomic_store_release_i64(i64 %val) nounwind {
1375; CHECK-LABEL: test_atomic_store_release_i64:
1376 store atomic i64 %val, i64* @var64 release, align 8
1377; CHECK-NOT: dmb
1378; CHECK-NOT: mcr
Tim Northoverc882eb02014-04-03 11:44:58 +00001379; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var64
1380; CHECK: movt [[ADDR]], :upper16:var64
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001381
1382; CHECK: .LBB{{[0-9]+}}_1:
1383 ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
1384 ; function there.
Tim Northoverc882eb02014-04-03 11:44:58 +00001385; CHECK: stlexd [[STATUS:r[0-9]+]], r0, r1, {{.*}}[[ADDR]]
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001386; CHECK-NEXT: cmp [[STATUS]], #0
1387; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1388; CHECK-NOT: dmb
1389; CHECK-NOT: mcr
1390
1391 ret void
1392}
1393
1394define i32 @not.barriers(i32* %var, i1 %cond) {
1395; CHECK-LABEL: not.barriers:
1396 br i1 %cond, label %atomic_ver, label %simple_ver
1397simple_ver:
1398 %oldval = load i32* %var
1399 %newval = add nsw i32 %oldval, -1
1400 store i32 %newval, i32* %var
1401 br label %somewhere
1402atomic_ver:
1403 fence seq_cst
1404 %val = atomicrmw add i32* %var, i32 -1 monotonic
1405 fence seq_cst
1406 br label %somewhere
1407; CHECK: dmb
1408; CHECK: ldrex
1409; CHECK: dmb
1410 ; The key point here is that the second dmb isn't immediately followed by the
1411 ; simple_ver basic block, which LLVM attempted to do when DMB had been marked
1412 ; with isBarrier. For now, look for something that looks like "somewhere".
Tim Northoverc882eb02014-04-03 11:44:58 +00001413; CHECK-NEXT: {{mov|bx}}
Amara Emersonb4ad2f32013-09-26 12:22:36 +00001414somewhere:
1415 %combined = phi i32 [ %val, %atomic_ver ], [ %newval, %simple_ver]
1416 ret i32 %combined
1417}