blob: f3c16171cc83d2aa535843ea8900a996d3b65841 [file] [log] [blame]
Tim Northovere3d42362013-02-01 11:40:47 +00001; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s
Tim Northovere0e3aef2013-01-31 12:12:40 +00002
3@var8 = global i8 0
4@var16 = global i16 0
5@var32 = global i32 0
6@var64 = global i64 0
7
8define i8 @test_atomic_load_add_i8(i8 %offset) nounwind {
9; CHECK: test_atomic_load_add_i8:
10 %old = atomicrmw add i8* @var8, i8 %offset seq_cst
11; CHECK: dmb ish
12; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
13; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
14
15; CHECK: .LBB{{[0-9]+}}_1:
16; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
17 ; w0 below is a reasonable guess but could change: it certainly comes into the
18 ; function there.
19; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
20; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +000021; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +000022; CHECK: dmb ish
23
24; CHECK: mov x0, x[[OLD]]
25 ret i8 %old
26}
27
28define i16 @test_atomic_load_add_i16(i16 %offset) nounwind {
29; CHECK: test_atomic_load_add_i16:
30 %old = atomicrmw add i16* @var16, i16 %offset seq_cst
31; CHECK: dmb ish
32; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
33; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
34
35; CHECK: .LBB{{[0-9]+}}_1:
36; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
37 ; w0 below is a reasonable guess but could change: it certainly comes into the
38 ; function there.
39; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
40; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +000041; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +000042; CHECK: dmb ish
43
44; CHECK: mov x0, x[[OLD]]
45 ret i16 %old
46}
47
48define i32 @test_atomic_load_add_i32(i32 %offset) nounwind {
49; CHECK: test_atomic_load_add_i32:
50 %old = atomicrmw add i32* @var32, i32 %offset seq_cst
51; CHECK: dmb ish
52; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
53; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
54
55; CHECK: .LBB{{[0-9]+}}_1:
56; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
57 ; w0 below is a reasonable guess but could change: it certainly comes into the
58 ; function there.
59; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
60; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +000061; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +000062; CHECK: dmb ish
63
64; CHECK: mov x0, x[[OLD]]
65 ret i32 %old
66}
67
68define i64 @test_atomic_load_add_i64(i64 %offset) nounwind {
69; CHECK: test_atomic_load_add_i64:
70 %old = atomicrmw add i64* @var64, i64 %offset seq_cst
71; CHECK: dmb ish
72; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
73; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
74
75; CHECK: .LBB{{[0-9]+}}_1:
76; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
77 ; x0 below is a reasonable guess but could change: it certainly comes into the
78 ; function there.
79; CHECK-NEXT: add [[NEW:x[0-9]+]], x[[OLD]], x0
80; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +000081; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +000082; CHECK: dmb ish
83
84; CHECK: mov x0, x[[OLD]]
85 ret i64 %old
86}
87
88define i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {
89; CHECK: test_atomic_load_sub_i8:
90 %old = atomicrmw sub i8* @var8, i8 %offset seq_cst
91; CHECK: dmb ish
92; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
93; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
94
95; CHECK: .LBB{{[0-9]+}}_1:
96; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
97 ; w0 below is a reasonable guess but could change: it certainly comes into the
98 ; function there.
99; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
100; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000101; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000102; CHECK: dmb ish
103
104; CHECK: mov x0, x[[OLD]]
105 ret i8 %old
106}
107
108define i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {
109; CHECK: test_atomic_load_sub_i16:
110 %old = atomicrmw sub i16* @var16, i16 %offset seq_cst
111; CHECK: dmb ish
112; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
113; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
114
115; CHECK: .LBB{{[0-9]+}}_1:
116; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
117 ; w0 below is a reasonable guess but could change: it certainly comes into the
118 ; function there.
119; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
120; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000121; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000122; CHECK: dmb ish
123
124; CHECK: mov x0, x[[OLD]]
125 ret i16 %old
126}
127
128define i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {
129; CHECK: test_atomic_load_sub_i32:
130 %old = atomicrmw sub i32* @var32, i32 %offset seq_cst
131; CHECK: dmb ish
132; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
133; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
134
135; CHECK: .LBB{{[0-9]+}}_1:
136; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
137 ; w0 below is a reasonable guess but could change: it certainly comes into the
138 ; function there.
139; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
140; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000141; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000142; CHECK: dmb ish
143
144; CHECK: mov x0, x[[OLD]]
145 ret i32 %old
146}
147
148define i64 @test_atomic_load_sub_i64(i64 %offset) nounwind {
149; CHECK: test_atomic_load_sub_i64:
150 %old = atomicrmw sub i64* @var64, i64 %offset seq_cst
151; CHECK: dmb ish
152; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
153; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
154
155; CHECK: .LBB{{[0-9]+}}_1:
156; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
157 ; x0 below is a reasonable guess but could change: it certainly comes into the
158 ; function there.
159; CHECK-NEXT: sub [[NEW:x[0-9]+]], x[[OLD]], x0
160; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000161; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000162; CHECK: dmb ish
163
164; CHECK: mov x0, x[[OLD]]
165 ret i64 %old
166}
167
168define i8 @test_atomic_load_and_i8(i8 %offset) nounwind {
169; CHECK: test_atomic_load_and_i8:
170 %old = atomicrmw and i8* @var8, i8 %offset seq_cst
171; CHECK: dmb ish
172; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
173; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
174
175; CHECK: .LBB{{[0-9]+}}_1:
176; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
177 ; w0 below is a reasonable guess but could change: it certainly comes into the
178 ; function there.
179; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
180; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000181; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000182; CHECK: dmb ish
183
184; CHECK: mov x0, x[[OLD]]
185 ret i8 %old
186}
187
188define i16 @test_atomic_load_and_i16(i16 %offset) nounwind {
189; CHECK: test_atomic_load_and_i16:
190 %old = atomicrmw and i16* @var16, i16 %offset seq_cst
191; CHECK: dmb ish
192; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
193; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
194
195; CHECK: .LBB{{[0-9]+}}_1:
196; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
197 ; w0 below is a reasonable guess but could change: it certainly comes into the
198 ; function there.
199; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
200; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000201; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000202; CHECK: dmb ish
203
204; CHECK: mov x0, x[[OLD]]
205 ret i16 %old
206}
207
208define i32 @test_atomic_load_and_i32(i32 %offset) nounwind {
209; CHECK: test_atomic_load_and_i32:
210 %old = atomicrmw and i32* @var32, i32 %offset seq_cst
211; CHECK: dmb ish
212; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
213; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
214
215; CHECK: .LBB{{[0-9]+}}_1:
216; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
217 ; w0 below is a reasonable guess but could change: it certainly comes into the
218 ; function there.
219; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
220; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000221; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000222; CHECK: dmb ish
223
224; CHECK: mov x0, x[[OLD]]
225 ret i32 %old
226}
227
228define i64 @test_atomic_load_and_i64(i64 %offset) nounwind {
229; CHECK: test_atomic_load_and_i64:
230 %old = atomicrmw and i64* @var64, i64 %offset seq_cst
231; CHECK: dmb ish
232; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
233; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
234
235; CHECK: .LBB{{[0-9]+}}_1:
236; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
237 ; x0 below is a reasonable guess but could change: it certainly comes into the
238 ; function there.
239; CHECK-NEXT: and [[NEW:x[0-9]+]], x[[OLD]], x0
240; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000241; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000242; CHECK: dmb ish
243
244; CHECK: mov x0, x[[OLD]]
245 ret i64 %old
246}
247
248define i8 @test_atomic_load_or_i8(i8 %offset) nounwind {
249; CHECK: test_atomic_load_or_i8:
250 %old = atomicrmw or i8* @var8, i8 %offset seq_cst
251; CHECK: dmb ish
252; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
253; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
254
255; CHECK: .LBB{{[0-9]+}}_1:
256; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
257 ; w0 below is a reasonable guess but could change: it certainly comes into the
258 ; function there.
259; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
260; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000261; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000262; CHECK: dmb ish
263
264; CHECK: mov x0, x[[OLD]]
265 ret i8 %old
266}
267
268define i16 @test_atomic_load_or_i16(i16 %offset) nounwind {
269; CHECK: test_atomic_load_or_i16:
270 %old = atomicrmw or i16* @var16, i16 %offset seq_cst
271; CHECK: dmb ish
272; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
273; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
274
275; CHECK: .LBB{{[0-9]+}}_1:
276; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
277 ; w0 below is a reasonable guess but could change: it certainly comes into the
278 ; function there.
279; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
280; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000281; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000282; CHECK: dmb ish
283
284; CHECK: mov x0, x[[OLD]]
285 ret i16 %old
286}
287
288define i32 @test_atomic_load_or_i32(i32 %offset) nounwind {
289; CHECK: test_atomic_load_or_i32:
290 %old = atomicrmw or i32* @var32, i32 %offset seq_cst
291; CHECK: dmb ish
292; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
293; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
294
295; CHECK: .LBB{{[0-9]+}}_1:
296; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
297 ; w0 below is a reasonable guess but could change: it certainly comes into the
298 ; function there.
299; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
300; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000301; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000302; CHECK: dmb ish
303
304; CHECK: mov x0, x[[OLD]]
305 ret i32 %old
306}
307
308define i64 @test_atomic_load_or_i64(i64 %offset) nounwind {
309; CHECK: test_atomic_load_or_i64:
310 %old = atomicrmw or i64* @var64, i64 %offset seq_cst
311; CHECK: dmb ish
312; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
313; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
314
315; CHECK: .LBB{{[0-9]+}}_1:
316; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
317 ; x0 below is a reasonable guess but could change: it certainly comes into the
318 ; function there.
319; CHECK-NEXT: orr [[NEW:x[0-9]+]], x[[OLD]], x0
320; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000321; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000322; CHECK: dmb ish
323
324; CHECK: mov x0, x[[OLD]]
325 ret i64 %old
326}
327
328define i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {
329; CHECK: test_atomic_load_xor_i8:
330 %old = atomicrmw xor i8* @var8, i8 %offset seq_cst
331; CHECK: dmb ish
332; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
333; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
334
335; CHECK: .LBB{{[0-9]+}}_1:
336; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
337 ; w0 below is a reasonable guess but could change: it certainly comes into the
338 ; function there.
339; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
340; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000341; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000342; CHECK: dmb ish
343
344; CHECK: mov x0, x[[OLD]]
345 ret i8 %old
346}
347
348define i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {
349; CHECK: test_atomic_load_xor_i16:
350 %old = atomicrmw xor i16* @var16, i16 %offset seq_cst
351; CHECK: dmb ish
352; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
353; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
354
355; CHECK: .LBB{{[0-9]+}}_1:
356; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
357 ; w0 below is a reasonable guess but could change: it certainly comes into the
358 ; function there.
359; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
360; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000361; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000362; CHECK: dmb ish
363
364; CHECK: mov x0, x[[OLD]]
365 ret i16 %old
366}
367
368define i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {
369; CHECK: test_atomic_load_xor_i32:
370 %old = atomicrmw xor i32* @var32, i32 %offset seq_cst
371; CHECK: dmb ish
372; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
373; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
374
375; CHECK: .LBB{{[0-9]+}}_1:
376; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
377 ; w0 below is a reasonable guess but could change: it certainly comes into the
378 ; function there.
379; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
380; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000381; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000382; CHECK: dmb ish
383
384; CHECK: mov x0, x[[OLD]]
385 ret i32 %old
386}
387
388define i64 @test_atomic_load_xor_i64(i64 %offset) nounwind {
389; CHECK: test_atomic_load_xor_i64:
390 %old = atomicrmw xor i64* @var64, i64 %offset seq_cst
391; CHECK: dmb ish
392; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
393; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
394
395; CHECK: .LBB{{[0-9]+}}_1:
396; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
397 ; x0 below is a reasonable guess but could change: it certainly comes into the
398 ; function there.
399; CHECK-NEXT: eor [[NEW:x[0-9]+]], x[[OLD]], x0
400; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000401; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000402; CHECK: dmb ish
403
404; CHECK: mov x0, x[[OLD]]
405 ret i64 %old
406}
407
408define i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {
409; CHECK: test_atomic_load_xchg_i8:
410 %old = atomicrmw xchg i8* @var8, i8 %offset seq_cst
411; CHECK: dmb ish
412; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
413; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
414
415; CHECK: .LBB{{[0-9]+}}_1:
416; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
417 ; w0 below is a reasonable guess but could change: it certainly comes into the
418 ; function there.
419; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000420; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000421; CHECK: dmb ish
422
423; CHECK: mov x0, x[[OLD]]
424 ret i8 %old
425}
426
427define i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {
428; CHECK: test_atomic_load_xchg_i16:
429 %old = atomicrmw xchg i16* @var16, i16 %offset seq_cst
430; CHECK: dmb ish
431; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
432; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
433
434; CHECK: .LBB{{[0-9]+}}_1:
435; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
436 ; w0 below is a reasonable guess but could change: it certainly comes into the
437 ; function there.
438; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000439; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000440; CHECK: dmb ish
441
442; CHECK: mov x0, x[[OLD]]
443 ret i16 %old
444}
445
446define i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {
447; CHECK: test_atomic_load_xchg_i32:
448 %old = atomicrmw xchg i32* @var32, i32 %offset seq_cst
449; CHECK: dmb ish
450; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
451; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
452
453; CHECK: .LBB{{[0-9]+}}_1:
454; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
455 ; w0 below is a reasonable guess but could change: it certainly comes into the
456 ; function there.
457; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000458; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000459; CHECK: dmb ish
460
461; CHECK: mov x0, x[[OLD]]
462 ret i32 %old
463}
464
465define i64 @test_atomic_load_xchg_i64(i64 %offset) nounwind {
466; CHECK: test_atomic_load_xchg_i64:
467 %old = atomicrmw xchg i64* @var64, i64 %offset seq_cst
468; CHECK: dmb ish
469; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
470; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
471
472; CHECK: .LBB{{[0-9]+}}_1:
473; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
474 ; x0 below is a reasonable guess but could change: it certainly comes into the
475 ; function there.
476; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], x0, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000477; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000478; CHECK: dmb ish
479
480; CHECK: mov x0, x[[OLD]]
481 ret i64 %old
482}
483
484
485define i8 @test_atomic_load_min_i8(i8 %offset) nounwind {
486; CHECK: test_atomic_load_min_i8:
487 %old = atomicrmw min i8* @var8, i8 %offset seq_cst
488; CHECK: dmb ish
489; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
490; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
491
492; CHECK: .LBB{{[0-9]+}}_1:
493; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
494 ; w0 below is a reasonable guess but could change: it certainly comes into the
495 ; function there.
496; CHECK-NEXT: cmp w0, w[[OLD]], sxtb
497; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
498; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000499; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000500; CHECK: dmb ish
501
502; CHECK: mov x0, x[[OLD]]
503 ret i8 %old
504}
505
506define i16 @test_atomic_load_min_i16(i16 %offset) nounwind {
507; CHECK: test_atomic_load_min_i16:
508 %old = atomicrmw min i16* @var16, i16 %offset seq_cst
509; CHECK: dmb ish
510; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
511; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
512
513; CHECK: .LBB{{[0-9]+}}_1:
514; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
515 ; w0 below is a reasonable guess but could change: it certainly comes into the
516 ; function there.
517; CHECK-NEXT: cmp w0, w[[OLD]], sxth
518; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
519; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000520; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000521; CHECK: dmb ish
522
523; CHECK: mov x0, x[[OLD]]
524 ret i16 %old
525}
526
527define i32 @test_atomic_load_min_i32(i32 %offset) nounwind {
528; CHECK: test_atomic_load_min_i32:
529 %old = atomicrmw min i32* @var32, i32 %offset seq_cst
530; CHECK: dmb ish
531; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
532; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
533
534; CHECK: .LBB{{[0-9]+}}_1:
535; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
536 ; w0 below is a reasonable guess but could change: it certainly comes into the
537 ; function there.
538; CHECK-NEXT: cmp w0, w[[OLD]]
539; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
540; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000541; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000542; CHECK: dmb ish
543
544; CHECK: mov x0, x[[OLD]]
545 ret i32 %old
546}
547
548define i64 @test_atomic_load_min_i64(i64 %offset) nounwind {
549; CHECK: test_atomic_load_min_i64:
550 %old = atomicrmw min i64* @var64, i64 %offset seq_cst
551; CHECK: dmb ish
552; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
553; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
554
555; CHECK: .LBB{{[0-9]+}}_1:
556; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
557 ; x0 below is a reasonable guess but could change: it certainly comes into the
558 ; function there.
559; CHECK-NEXT: cmp x0, x[[OLD]]
560; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, gt
561; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000562; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000563; CHECK: dmb ish
564
565; CHECK: mov x0, x[[OLD]]
566 ret i64 %old
567}
568
569define i8 @test_atomic_load_max_i8(i8 %offset) nounwind {
570; CHECK: test_atomic_load_max_i8:
571 %old = atomicrmw max i8* @var8, i8 %offset seq_cst
572; CHECK: dmb ish
573; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
574; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
575
576; CHECK: .LBB{{[0-9]+}}_1:
577; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
578 ; w0 below is a reasonable guess but could change: it certainly comes into the
579 ; function there.
580; CHECK-NEXT: cmp w0, w[[OLD]], sxtb
581; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt
582; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000583; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000584; CHECK: dmb ish
585
586; CHECK: mov x0, x[[OLD]]
587 ret i8 %old
588}
589
590define i16 @test_atomic_load_max_i16(i16 %offset) nounwind {
591; CHECK: test_atomic_load_max_i16:
592 %old = atomicrmw max i16* @var16, i16 %offset seq_cst
593; CHECK: dmb ish
594; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
595; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
596
597; CHECK: .LBB{{[0-9]+}}_1:
598; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
599 ; w0 below is a reasonable guess but could change: it certainly comes into the
600 ; function there.
601; CHECK-NEXT: cmp w0, w[[OLD]], sxth
602; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt
603; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000604; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000605; CHECK: dmb ish
606
607; CHECK: mov x0, x[[OLD]]
608 ret i16 %old
609}
610
611define i32 @test_atomic_load_max_i32(i32 %offset) nounwind {
612; CHECK: test_atomic_load_max_i32:
613 %old = atomicrmw max i32* @var32, i32 %offset seq_cst
614; CHECK: dmb ish
615; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
616; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
617
618; CHECK: .LBB{{[0-9]+}}_1:
619; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
620 ; w0 below is a reasonable guess but could change: it certainly comes into the
621 ; function there.
622; CHECK-NEXT: cmp w0, w[[OLD]]
623; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt
624; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000625; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000626; CHECK: dmb ish
627
628; CHECK: mov x0, x[[OLD]]
629 ret i32 %old
630}
631
632define i64 @test_atomic_load_max_i64(i64 %offset) nounwind {
633; CHECK: test_atomic_load_max_i64:
634 %old = atomicrmw max i64* @var64, i64 %offset seq_cst
635; CHECK: dmb ish
636; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
637; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
638
639; CHECK: .LBB{{[0-9]+}}_1:
640; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
641 ; x0 below is a reasonable guess but could change: it certainly comes into the
642 ; function there.
643; CHECK-NEXT: cmp x0, x[[OLD]]
644; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lt
645; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000646; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000647; CHECK: dmb ish
648
649; CHECK: mov x0, x[[OLD]]
650 ret i64 %old
651}
652
653define i8 @test_atomic_load_umin_i8(i8 %offset) nounwind {
654; CHECK: test_atomic_load_umin_i8:
655 %old = atomicrmw umin i8* @var8, i8 %offset seq_cst
656; CHECK: dmb ish
657; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
658; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
659
660; CHECK: .LBB{{[0-9]+}}_1:
661; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
662 ; w0 below is a reasonable guess but could change: it certainly comes into the
663 ; function there.
664; CHECK-NEXT: cmp w0, w[[OLD]], uxtb
665; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
666; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000667; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000668; CHECK: dmb ish
669
670; CHECK: mov x0, x[[OLD]]
671 ret i8 %old
672}
673
674define i16 @test_atomic_load_umin_i16(i16 %offset) nounwind {
675; CHECK: test_atomic_load_umin_i16:
676 %old = atomicrmw umin i16* @var16, i16 %offset seq_cst
677; CHECK: dmb ish
678; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
679; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
680
681; CHECK: .LBB{{[0-9]+}}_1:
682; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
683 ; w0 below is a reasonable guess but could change: it certainly comes into the
684 ; function there.
685; CHECK-NEXT: cmp w0, w[[OLD]], uxth
686; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
687; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000688; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000689; CHECK: dmb ish
690
691; CHECK: mov x0, x[[OLD]]
692 ret i16 %old
693}
694
695define i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {
696; CHECK: test_atomic_load_umin_i32:
697 %old = atomicrmw umin i32* @var32, i32 %offset seq_cst
698; CHECK: dmb ish
699; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
700; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
701
702; CHECK: .LBB{{[0-9]+}}_1:
703; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
704 ; w0 below is a reasonable guess but could change: it certainly comes into the
705 ; function there.
706; CHECK-NEXT: cmp w0, w[[OLD]]
707; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
708; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000709; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000710; CHECK: dmb ish
711
712; CHECK: mov x0, x[[OLD]]
713 ret i32 %old
714}
715
716define i64 @test_atomic_load_umin_i64(i64 %offset) nounwind {
717; CHECK: test_atomic_load_umin_i64:
718 %old = atomicrmw umin i64* @var64, i64 %offset seq_cst
719; CHECK: dmb ish
720; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
721; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
722
723; CHECK: .LBB{{[0-9]+}}_1:
724; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
725 ; x0 below is a reasonable guess but could change: it certainly comes into the
726 ; function there.
727; CHECK-NEXT: cmp x0, x[[OLD]]
728; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, hi
729; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000730; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000731; CHECK: dmb ish
732
733; CHECK: mov x0, x[[OLD]]
734 ret i64 %old
735}
736
737define i8 @test_atomic_load_umax_i8(i8 %offset) nounwind {
738; CHECK: test_atomic_load_umax_i8:
739 %old = atomicrmw umax i8* @var8, i8 %offset seq_cst
740; CHECK: dmb ish
741; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
742; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
743
744; CHECK: .LBB{{[0-9]+}}_1:
745; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
746 ; w0 below is a reasonable guess but could change: it certainly comes into the
747 ; function there.
748; CHECK-NEXT: cmp w0, w[[OLD]], uxtb
749; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo
750; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000751; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000752; CHECK: dmb ish
753
754; CHECK: mov x0, x[[OLD]]
755 ret i8 %old
756}
757
758define i16 @test_atomic_load_umax_i16(i16 %offset) nounwind {
759; CHECK: test_atomic_load_umax_i16:
760 %old = atomicrmw umax i16* @var16, i16 %offset seq_cst
761; CHECK: dmb ish
762; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
763; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
764
765; CHECK: .LBB{{[0-9]+}}_1:
766; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
767 ; w0 below is a reasonable guess but could change: it certainly comes into the
768 ; function there.
769; CHECK-NEXT: cmp w0, w[[OLD]], uxth
770; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo
771; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000772; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000773; CHECK: dmb ish
774
775; CHECK: mov x0, x[[OLD]]
776 ret i16 %old
777}
778
779define i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {
780; CHECK: test_atomic_load_umax_i32:
781 %old = atomicrmw umax i32* @var32, i32 %offset seq_cst
782; CHECK: dmb ish
783; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
784; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
785
786; CHECK: .LBB{{[0-9]+}}_1:
787; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
788 ; w0 below is a reasonable guess but could change: it certainly comes into the
789 ; function there.
790; CHECK-NEXT: cmp w0, w[[OLD]]
791; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo
792; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000793; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000794; CHECK: dmb ish
795
796; CHECK: mov x0, x[[OLD]]
797 ret i32 %old
798}
799
800define i64 @test_atomic_load_umax_i64(i64 %offset) nounwind {
801; CHECK: test_atomic_load_umax_i64:
802 %old = atomicrmw umax i64* @var64, i64 %offset seq_cst
803; CHECK: dmb ish
804; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
805; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
806
807; CHECK: .LBB{{[0-9]+}}_1:
808; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
809 ; x0 below is a reasonable guess but could change: it certainly comes into the
810 ; function there.
811; CHECK-NEXT: cmp x0, x[[OLD]]
812; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lo
813; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000814; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
Tim Northovere0e3aef2013-01-31 12:12:40 +0000815; CHECK: dmb ish
816
817; CHECK: mov x0, x[[OLD]]
818 ret i64 %old
819}
820
821define i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind {
822; CHECK: test_atomic_cmpxchg_i8:
823 %old = cmpxchg i8* @var8, i8 %wanted, i8 %new seq_cst
824; CHECK: dmb ish
825; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
826; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
827
828; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
829; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
830 ; w0 below is a reasonable guess but could change: it certainly comes into the
831 ; function there.
832; CHECK-NEXT: cmp w[[OLD]], w0
833; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
834 ; As above, w1 is a reasonable guess.
835; CHECK: stxrb [[STATUS:w[0-9]+]], w1, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000836; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
Tim Northovere0e3aef2013-01-31 12:12:40 +0000837; CHECK: dmb ish
838
839; CHECK: mov x0, x[[OLD]]
840 ret i8 %old
841}
842
843define i16 @test_atomic_cmpxchg_i16(i16 %wanted, i16 %new) nounwind {
844; CHECK: test_atomic_cmpxchg_i16:
845 %old = cmpxchg i16* @var16, i16 %wanted, i16 %new seq_cst
846; CHECK: dmb ish
847; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
848; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
849
850; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
851; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
852 ; w0 below is a reasonable guess but could change: it certainly comes into the
853 ; function there.
854; CHECK-NEXT: cmp w[[OLD]], w0
855; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
856 ; As above, w1 is a reasonable guess.
857; CHECK: stxrh [[STATUS:w[0-9]+]], w1, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000858; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
Tim Northovere0e3aef2013-01-31 12:12:40 +0000859; CHECK: dmb ish
860
861; CHECK: mov x0, x[[OLD]]
862 ret i16 %old
863}
864
865define i32 @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {
866; CHECK: test_atomic_cmpxchg_i32:
867 %old = cmpxchg i32* @var32, i32 %wanted, i32 %new seq_cst
868; CHECK: dmb ish
869; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
870; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
871
872; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
873; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
874 ; w0 below is a reasonable guess but could change: it certainly comes into the
875 ; function there.
876; CHECK-NEXT: cmp w[[OLD]], w0
877; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
878 ; As above, w1 is a reasonable guess.
879; CHECK: stxr [[STATUS:w[0-9]+]], w1, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000880; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
Tim Northovere0e3aef2013-01-31 12:12:40 +0000881; CHECK: dmb ish
882
883; CHECK: mov x0, x[[OLD]]
884 ret i32 %old
885}
886
887define i64 @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
888; CHECK: test_atomic_cmpxchg_i64:
889 %old = cmpxchg i64* @var64, i64 %wanted, i64 %new seq_cst
890; CHECK: dmb ish
891; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
892; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
893
894; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
895; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
896 ; w0 below is a reasonable guess but could change: it certainly comes into the
897 ; function there.
898; CHECK-NEXT: cmp x[[OLD]], x0
899; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
900 ; As above, w1 is a reasonable guess.
901; CHECK: stxr [[STATUS:w[0-9]+]], x1, [x[[ADDR]]]
Tim Northover9fafdf62013-02-28 13:52:07 +0000902; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
Tim Northovere0e3aef2013-01-31 12:12:40 +0000903; CHECK: dmb ish
904
905; CHECK: mov x0, x[[OLD]]
906 ret i64 %old
907}
908
909define i8 @test_atomic_load_monotonic_i8() nounwind {
910; CHECK: test_atomic_load_monotonic_i8:
911 %val = load atomic i8* @var8 monotonic, align 1
912; CHECK-NOT: dmb
913; CHECK: adrp x[[HIADDR:[0-9]+]], var8
914; CHECK: ldrb w0, [x[[HIADDR]], #:lo12:var8]
915; CHECK-NOT: dmb
916
917 ret i8 %val
918}
919
920define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
921; CHECK: test_atomic_load_monotonic_regoff_i8:
922 %addr_int = add i64 %base, %off
923 %addr = inttoptr i64 %addr_int to i8*
924
925 %val = load atomic i8* %addr monotonic, align 1
926; CHECK-NOT: dmb
927; CHECK: ldrb w0, [x0, x1]
928; CHECK-NOT: dmb
929
930 ret i8 %val
931}
932
933define i8 @test_atomic_load_acquire_i8() nounwind {
934; CHECK: test_atomic_load_acquire_i8:
935 %val = load atomic i8* @var8 acquire, align 1
936; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
937; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
938
939; CHECK: ldarb w0, [x[[ADDR]]]
940 ret i8 %val
941}
942
943define i8 @test_atomic_load_seq_cst_i8() nounwind {
944; CHECK: test_atomic_load_seq_cst_i8:
945 %val = load atomic i8* @var8 seq_cst, align 1
946; CHECK: adrp x[[HIADDR:[0-9]+]], var8
947; CHECK: ldrb w0, [x[[HIADDR]], #:lo12:var8]
948; CHECK: dmb ish
949 ret i8 %val
950}
951
952define i16 @test_atomic_load_monotonic_i16() nounwind {
953; CHECK: test_atomic_load_monotonic_i16:
954 %val = load atomic i16* @var16 monotonic, align 2
955; CHECK-NOT: dmb
956; CHECK: adrp x[[HIADDR:[0-9]+]], var16
957; CHECK: ldrh w0, [x[[HIADDR]], #:lo12:var16]
958; CHECK-NOT: dmb
959
960 ret i16 %val
961}
962
963define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {
964; CHECK: test_atomic_load_monotonic_regoff_i32:
965 %addr_int = add i64 %base, %off
966 %addr = inttoptr i64 %addr_int to i32*
967
968 %val = load atomic i32* %addr monotonic, align 4
969; CHECK-NOT: dmb
970; CHECK: ldr w0, [x0, x1]
971; CHECK-NOT: dmb
972
973 ret i32 %val
974}
975
976define i64 @test_atomic_load_seq_cst_i64() nounwind {
977; CHECK: test_atomic_load_seq_cst_i64:
978 %val = load atomic i64* @var64 seq_cst, align 8
979; CHECK: adrp x[[HIADDR:[0-9]+]], var64
980; CHECK: ldr x0, [x[[HIADDR]], #:lo12:var64]
981; CHECK: dmb ish
982 ret i64 %val
983}
984
985define void @test_atomic_store_monotonic_i8(i8 %val) nounwind {
986; CHECK: test_atomic_store_monotonic_i8:
987 store atomic i8 %val, i8* @var8 monotonic, align 1
988; CHECK: adrp x[[HIADDR:[0-9]+]], var8
989; CHECK: strb w0, [x[[HIADDR]], #:lo12:var8]
990
991 ret void
992}
993
994define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {
995; CHECK: test_atomic_store_monotonic_regoff_i8:
996
997 %addr_int = add i64 %base, %off
998 %addr = inttoptr i64 %addr_int to i8*
999
1000 store atomic i8 %val, i8* %addr monotonic, align 1
1001; CHECK: strb w2, [x0, x1]
1002
1003 ret void
1004}
1005define void @test_atomic_store_release_i8(i8 %val) nounwind {
1006; CHECK: test_atomic_store_release_i8:
1007 store atomic i8 %val, i8* @var8 release, align 1
1008; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1009; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var8
1010; CHECK: stlrb w0, [x[[ADDR]]]
1011
1012 ret void
1013}
1014
1015define void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {
1016; CHECK: test_atomic_store_seq_cst_i8:
1017 store atomic i8 %val, i8* @var8 seq_cst, align 1
1018; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1019; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var8
1020; CHECK: stlrb w0, [x[[ADDR]]]
1021; CHECK: dmb ish
1022
1023 ret void
1024}
1025
1026define void @test_atomic_store_monotonic_i16(i16 %val) nounwind {
1027; CHECK: test_atomic_store_monotonic_i16:
1028 store atomic i16 %val, i16* @var16 monotonic, align 2
1029; CHECK: adrp x[[HIADDR:[0-9]+]], var16
1030; CHECK: strh w0, [x[[HIADDR]], #:lo12:var16]
1031
1032 ret void
1033}
1034
1035define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {
1036; CHECK: test_atomic_store_monotonic_regoff_i32:
1037
1038 %addr_int = add i64 %base, %off
1039 %addr = inttoptr i64 %addr_int to i32*
1040
1041 store atomic i32 %val, i32* %addr monotonic, align 4
1042; CHECK: str w2, [x0, x1]
1043
1044 ret void
1045}
1046
1047define void @test_atomic_store_release_i64(i64 %val) nounwind {
1048; CHECK: test_atomic_store_release_i64:
1049 store atomic i64 %val, i64* @var64 release, align 8
1050; CHECK: adrp [[HIADDR:x[0-9]+]], var64
1051; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var64
1052; CHECK: stlr x0, [x[[ADDR]]]
1053
1054 ret void
1055}