1 ; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK
2 ; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK-REG
5 ; Point of CHECK-REG is to make sure UNPREDICTABLE instructions aren't created
6 ; (i.e. reusing a register for status & data in store exclusive).
7 ; CHECK-REG-NOT: stlxrb w[[NEW:[0-9]+]], w[[NEW]], [x{{[0-9]+}}]
8 ; CHECK-REG-NOT: stlxrb w[[NEW:[0-9]+]], x[[NEW]], [x{{[0-9]+}}]
15 define i8 @test_atomic_load_add_i8(i8 %offset) nounwind {
16 ; CHECK-LABEL: test_atomic_load_add_i8:
17 %old = atomicrmw add i8* @var8, i8 %offset seq_cst
19 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
20 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
22 ; CHECK: .LBB{{[0-9]+}}_1:
23 ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
24 ; w0 below is a reasonable guess but could change: it certainly comes into the
26 ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
27 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
28 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
31 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
35 define i16 @test_atomic_load_add_i16(i16 %offset) nounwind {
36 ; CHECK-LABEL: test_atomic_load_add_i16:
37 %old = atomicrmw add i16* @var16, i16 %offset acquire
39 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
40 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
42 ; CHECK: .LBB{{[0-9]+}}_1:
43 ; ; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
44 ; w0 below is a reasonable guess but could change: it certainly comes into the
46 ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
47 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
48 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
51 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
55 define i32 @test_atomic_load_add_i32(i32 %offset) nounwind {
56 ; CHECK-LABEL: test_atomic_load_add_i32:
57 %old = atomicrmw add i32* @var32, i32 %offset release
59 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
60 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
62 ; CHECK: .LBB{{[0-9]+}}_1:
63 ; ; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
64 ; w0 below is a reasonable guess but could change: it certainly comes into the
66 ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
67 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
68 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
71 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
75 define i64 @test_atomic_load_add_i64(i64 %offset) nounwind {
76 ; CHECK-LABEL: test_atomic_load_add_i64:
77 %old = atomicrmw add i64* @var64, i64 %offset monotonic
79 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
80 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
82 ; CHECK: .LBB{{[0-9]+}}_1:
83 ; ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
84 ; x0 below is a reasonable guess but could change: it certainly comes into the
86 ; CHECK-NEXT: add [[NEW:x[0-9]+]], x[[OLD]], x0
87 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
88 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
91 ; CHECK: mov x0, x[[OLD]]
95 define i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {
96 ; CHECK-LABEL: test_atomic_load_sub_i8:
97 %old = atomicrmw sub i8* @var8, i8 %offset monotonic
99 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
100 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
102 ; CHECK: .LBB{{[0-9]+}}_1:
103 ; ; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
104 ; w0 below is a reasonable guess but could change: it certainly comes into the
106 ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
107 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
108 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
111 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
115 define i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {
116 ; CHECK-LABEL: test_atomic_load_sub_i16:
117 %old = atomicrmw sub i16* @var16, i16 %offset release
119 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
120 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
122 ; CHECK: .LBB{{[0-9]+}}_1:
123 ; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
124 ; w0 below is a reasonable guess but could change: it certainly comes into the
126 ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
127 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
128 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
131 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
135 define i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {
136 ; CHECK-LABEL: test_atomic_load_sub_i32:
137 %old = atomicrmw sub i32* @var32, i32 %offset acquire
139 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
140 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
142 ; CHECK: .LBB{{[0-9]+}}_1:
143 ; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
144 ; w0 below is a reasonable guess but could change: it certainly comes into the
146 ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
147 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
148 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
151 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
155 define i64 @test_atomic_load_sub_i64(i64 %offset) nounwind {
156 ; CHECK-LABEL: test_atomic_load_sub_i64:
157 %old = atomicrmw sub i64* @var64, i64 %offset seq_cst
159 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
160 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
162 ; CHECK: .LBB{{[0-9]+}}_1:
163 ; ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
164 ; x0 below is a reasonable guess but could change: it certainly comes into the
166 ; CHECK-NEXT: sub [[NEW:x[0-9]+]], x[[OLD]], x0
167 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
168 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
171 ; CHECK: mov x0, x[[OLD]]
175 define i8 @test_atomic_load_and_i8(i8 %offset) nounwind {
176 ; CHECK-LABEL: test_atomic_load_and_i8:
177 %old = atomicrmw and i8* @var8, i8 %offset release
179 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
180 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
182 ; CHECK: .LBB{{[0-9]+}}_1:
183 ; ; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
184 ; w0 below is a reasonable guess but could change: it certainly comes into the
186 ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
187 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
188 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
191 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
195 define i16 @test_atomic_load_and_i16(i16 %offset) nounwind {
196 ; CHECK-LABEL: test_atomic_load_and_i16:
197 %old = atomicrmw and i16* @var16, i16 %offset monotonic
199 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
200 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
202 ; CHECK: .LBB{{[0-9]+}}_1:
203 ; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
204 ; w0 below is a reasonable guess but could change: it certainly comes into the
206 ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
207 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
208 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
211 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
215 define i32 @test_atomic_load_and_i32(i32 %offset) nounwind {
216 ; CHECK-LABEL: test_atomic_load_and_i32:
217 %old = atomicrmw and i32* @var32, i32 %offset seq_cst
219 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
220 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
222 ; CHECK: .LBB{{[0-9]+}}_1:
223 ; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
224 ; w0 below is a reasonable guess but could change: it certainly comes into the
226 ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
227 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
228 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
231 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
235 define i64 @test_atomic_load_and_i64(i64 %offset) nounwind {
236 ; CHECK-LABEL: test_atomic_load_and_i64:
237 %old = atomicrmw and i64* @var64, i64 %offset acquire
239 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
240 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
242 ; CHECK: .LBB{{[0-9]+}}_1:
243 ; ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
244 ; x0 below is a reasonable guess but could change: it certainly comes into the
246 ; CHECK-NEXT: and [[NEW:x[0-9]+]], x[[OLD]], x0
247 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
248 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
251 ; CHECK: mov x0, x[[OLD]]
255 define i8 @test_atomic_load_or_i8(i8 %offset) nounwind {
256 ; CHECK-LABEL: test_atomic_load_or_i8:
257 %old = atomicrmw or i8* @var8, i8 %offset seq_cst
259 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
260 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
262 ; CHECK: .LBB{{[0-9]+}}_1:
263 ; ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
264 ; w0 below is a reasonable guess but could change: it certainly comes into the
266 ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
267 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
268 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
271 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
275 define i16 @test_atomic_load_or_i16(i16 %offset) nounwind {
276 ; CHECK-LABEL: test_atomic_load_or_i16:
277 %old = atomicrmw or i16* @var16, i16 %offset monotonic
279 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
280 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
282 ; CHECK: .LBB{{[0-9]+}}_1:
283 ; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
284 ; w0 below is a reasonable guess but could change: it certainly comes into the
286 ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
287 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
288 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
291 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
295 define i32 @test_atomic_load_or_i32(i32 %offset) nounwind {
296 ; CHECK-LABEL: test_atomic_load_or_i32:
297 %old = atomicrmw or i32* @var32, i32 %offset acquire
299 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
300 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
302 ; CHECK: .LBB{{[0-9]+}}_1:
303 ; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
304 ; w0 below is a reasonable guess but could change: it certainly comes into the
306 ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
307 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
308 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
311 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
315 define i64 @test_atomic_load_or_i64(i64 %offset) nounwind {
316 ; CHECK-LABEL: test_atomic_load_or_i64:
317 %old = atomicrmw or i64* @var64, i64 %offset release
319 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
320 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
322 ; CHECK: .LBB{{[0-9]+}}_1:
323 ; ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
324 ; x0 below is a reasonable guess but could change: it certainly comes into the
326 ; CHECK-NEXT: orr [[NEW:x[0-9]+]], x[[OLD]], x0
327 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
328 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
331 ; CHECK: mov x0, x[[OLD]]
335 define i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {
336 ; CHECK-LABEL: test_atomic_load_xor_i8:
337 %old = atomicrmw xor i8* @var8, i8 %offset acquire
339 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
340 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
342 ; CHECK: .LBB{{[0-9]+}}_1:
343 ; ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
344 ; w0 below is a reasonable guess but could change: it certainly comes into the
346 ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
347 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
348 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
351 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
355 define i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {
356 ; CHECK-LABEL: test_atomic_load_xor_i16:
357 %old = atomicrmw xor i16* @var16, i16 %offset release
359 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
360 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
362 ; CHECK: .LBB{{[0-9]+}}_1:
363 ; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
364 ; w0 below is a reasonable guess but could change: it certainly comes into the
366 ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
367 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
368 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
371 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
375 define i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {
376 ; CHECK-LABEL: test_atomic_load_xor_i32:
377 %old = atomicrmw xor i32* @var32, i32 %offset seq_cst
379 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
380 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
382 ; CHECK: .LBB{{[0-9]+}}_1:
383 ; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
384 ; w0 below is a reasonable guess but could change: it certainly comes into the
386 ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
387 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
388 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
391 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
395 define i64 @test_atomic_load_xor_i64(i64 %offset) nounwind {
396 ; CHECK-LABEL: test_atomic_load_xor_i64:
397 %old = atomicrmw xor i64* @var64, i64 %offset monotonic
399 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
400 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
402 ; CHECK: .LBB{{[0-9]+}}_1:
403 ; ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
404 ; x0 below is a reasonable guess but could change: it certainly comes into the
406 ; CHECK-NEXT: eor [[NEW:x[0-9]+]], x[[OLD]], x0
407 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
408 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
411 ; CHECK: mov x0, x[[OLD]]
415 define i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {
416 ; CHECK-LABEL: test_atomic_load_xchg_i8:
417 %old = atomicrmw xchg i8* @var8, i8 %offset monotonic
419 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
420 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
422 ; CHECK: .LBB{{[0-9]+}}_1:
423 ; ; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
424 ; w0 below is a reasonable guess but could change: it certainly comes into the
426 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
427 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
430 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
434 define i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {
435 ; CHECK-LABEL: test_atomic_load_xchg_i16:
436 %old = atomicrmw xchg i16* @var16, i16 %offset seq_cst
438 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
439 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
441 ; CHECK: .LBB{{[0-9]+}}_1:
442 ; ; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
443 ; w0 below is a reasonable guess but could change: it certainly comes into the
445 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
446 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
449 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
453 define i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {
454 ; CHECK-LABEL: test_atomic_load_xchg_i32:
455 %old = atomicrmw xchg i32* @var32, i32 %offset release
457 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
458 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
460 ; CHECK: .LBB{{[0-9]+}}_1:
461 ; ; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
462 ; w0 below is a reasonable guess but could change: it certainly comes into the
464 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
465 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
468 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
472 define i64 @test_atomic_load_xchg_i64(i64 %offset) nounwind {
473 ; CHECK-LABEL: test_atomic_load_xchg_i64:
474 %old = atomicrmw xchg i64* @var64, i64 %offset acquire
476 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
477 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
479 ; CHECK: .LBB{{[0-9]+}}_1:
480 ; ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
481 ; x0 below is a reasonable guess but could change: it certainly comes into the
483 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], x0, [x[[ADDR]]]
484 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
487 ; CHECK: mov x0, x[[OLD]]
492 define i8 @test_atomic_load_min_i8(i8 %offset) nounwind {
493 ; CHECK-LABEL: test_atomic_load_min_i8:
494 %old = atomicrmw min i8* @var8, i8 %offset acquire
496 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
497 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
499 ; CHECK: .LBB{{[0-9]+}}_1:
500 ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
501 ; w0 below is a reasonable guess but could change: it certainly comes into the
504 ; CHECK-NEXT: sxtb w[[OLD_EXT:[0-9]+]], w[[OLD]]
505 ; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxtb
506 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, le
508 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
509 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
512 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
516 define i16 @test_atomic_load_min_i16(i16 %offset) nounwind {
517 ; CHECK-LABEL: test_atomic_load_min_i16:
518 %old = atomicrmw min i16* @var16, i16 %offset release
520 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
521 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
523 ; CHECK: .LBB{{[0-9]+}}_1:
524 ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
525 ; w0 below is a reasonable guess but could change: it certainly comes into the
528 ; CHECK-NEXT: sxth w[[OLD_EXT:[0-9]+]], w[[OLD]]
529 ; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxth
530 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, le
533 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
534 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
537 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
541 define i32 @test_atomic_load_min_i32(i32 %offset) nounwind {
542 ; CHECK-LABEL: test_atomic_load_min_i32:
543 %old = atomicrmw min i32* @var32, i32 %offset monotonic
545 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
546 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
548 ; CHECK: .LBB{{[0-9]+}}_1:
549 ; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
550 ; w0 below is a reasonable guess but could change: it certainly comes into the
553 ; CHECK-NEXT: cmp w[[OLD]], w0
554 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, le
557 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
558 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
561 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
565 define i64 @test_atomic_load_min_i64(i64 %offset) nounwind {
566 ; CHECK-LABEL: test_atomic_load_min_i64:
567 %old = atomicrmw min i64* @var64, i64 %offset seq_cst
569 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
570 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
572 ; CHECK: .LBB{{[0-9]+}}_1:
573 ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
574 ; x0 below is a reasonable guess but could change: it certainly comes into the
577 ; CHECK-NEXT: cmp x[[OLD]], x0
578 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, le
581 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
582 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
585 ; CHECK: mov x0, x[[OLD]]
589 define i8 @test_atomic_load_max_i8(i8 %offset) nounwind {
590 ; CHECK-LABEL: test_atomic_load_max_i8:
591 %old = atomicrmw max i8* @var8, i8 %offset seq_cst
593 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
594 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
596 ; CHECK: .LBB{{[0-9]+}}_1:
597 ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
598 ; w0 below is a reasonable guess but could change: it certainly comes into the
601 ; CHECK-NEXT: sxtb w[[OLD_EXT:[0-9]+]], w[[OLD]]
602 ; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxtb
603 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
606 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
607 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
610 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
614 define i16 @test_atomic_load_max_i16(i16 %offset) nounwind {
615 ; CHECK-LABEL: test_atomic_load_max_i16:
616 %old = atomicrmw max i16* @var16, i16 %offset acquire
618 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
619 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
621 ; CHECK: .LBB{{[0-9]+}}_1:
622 ; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
623 ; w0 below is a reasonable guess but could change: it certainly comes into the
626 ; CHECK-NEXT: sxth w[[OLD_EXT:[0-9]+]], w[[OLD]]
627 ; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxth
628 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
631 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
632 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
635 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
639 define i32 @test_atomic_load_max_i32(i32 %offset) nounwind {
640 ; CHECK-LABEL: test_atomic_load_max_i32:
641 %old = atomicrmw max i32* @var32, i32 %offset release
643 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
644 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
646 ; CHECK: .LBB{{[0-9]+}}_1:
647 ; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
648 ; w0 below is a reasonable guess but could change: it certainly comes into the
651 ; CHECK-NEXT: cmp w[[OLD]], w0
652 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
655 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
656 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
659 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
663 define i64 @test_atomic_load_max_i64(i64 %offset) nounwind {
664 ; CHECK-LABEL: test_atomic_load_max_i64:
665 %old = atomicrmw max i64* @var64, i64 %offset monotonic
667 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
668 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
670 ; CHECK: .LBB{{[0-9]+}}_1:
671 ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
672 ; x0 below is a reasonable guess but could change: it certainly comes into the
675 ; CHECK-NEXT: cmp x[[OLD]], x0
676 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, gt
679 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
680 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
683 ; CHECK: mov x0, x[[OLD]]
687 define i8 @test_atomic_load_umin_i8(i8 %offset) nounwind {
688 ; CHECK-LABEL: test_atomic_load_umin_i8:
689 %old = atomicrmw umin i8* @var8, i8 %offset monotonic
691 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
692 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
694 ; CHECK: .LBB{{[0-9]+}}_1:
695 ; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
696 ; w0 below is a reasonable guess but could change: it certainly comes into the
699 ; CHECK-NEXT: cmp w[[OLD]], w0, uxtb
700 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, ls
703 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
704 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
707 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
711 define i16 @test_atomic_load_umin_i16(i16 %offset) nounwind {
712 ; CHECK-LABEL: test_atomic_load_umin_i16:
713 %old = atomicrmw umin i16* @var16, i16 %offset acquire
715 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
716 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
718 ; CHECK: .LBB{{[0-9]+}}_1:
719 ; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
720 ; w0 below is a reasonable guess but could change: it certainly comes into the
723 ; CHECK-NEXT: cmp w[[OLD]], w0, uxth
724 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, ls
727 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
728 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
731 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
735 define i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {
736 ; CHECK-LABEL: test_atomic_load_umin_i32:
737 %old = atomicrmw umin i32* @var32, i32 %offset seq_cst
739 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
740 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
742 ; CHECK: .LBB{{[0-9]+}}_1:
743 ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
744 ; w0 below is a reasonable guess but could change: it certainly comes into the
747 ; CHECK-NEXT: cmp w[[OLD]], w0
748 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, ls
751 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
752 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
755 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
759 define i64 @test_atomic_load_umin_i64(i64 %offset) nounwind {
760 ; CHECK-LABEL: test_atomic_load_umin_i64:
761 %old = atomicrmw umin i64* @var64, i64 %offset acq_rel
763 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
764 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
766 ; CHECK: .LBB{{[0-9]+}}_1:
767 ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
768 ; x0 below is a reasonable guess but could change: it certainly comes into the
771 ; CHECK-NEXT: cmp x[[OLD]], x0
772 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, ls
775 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
776 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
779 ; CHECK: mov x0, x[[OLD]]
783 define i8 @test_atomic_load_umax_i8(i8 %offset) nounwind {
784 ; CHECK-LABEL: test_atomic_load_umax_i8:
785 %old = atomicrmw umax i8* @var8, i8 %offset acq_rel
787 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
788 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
790 ; CHECK: .LBB{{[0-9]+}}_1:
791 ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
792 ; w0 below is a reasonable guess but could change: it certainly comes into the
795 ; CHECK-NEXT: cmp w[[OLD]], w0, uxtb
796 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
799 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
800 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
803 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
807 define i16 @test_atomic_load_umax_i16(i16 %offset) nounwind {
808 ; CHECK-LABEL: test_atomic_load_umax_i16:
809 %old = atomicrmw umax i16* @var16, i16 %offset monotonic
811 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
812 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
814 ; CHECK: .LBB{{[0-9]+}}_1:
815 ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
816 ; w0 below is a reasonable guess but could change: it certainly comes into the
819 ; CHECK-NEXT: cmp w[[OLD]], w0, uxth
820 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
823 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
824 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
827 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
831 define i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {
832 ; CHECK-LABEL: test_atomic_load_umax_i32:
833 %old = atomicrmw umax i32* @var32, i32 %offset seq_cst
835 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
836 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
838 ; CHECK: .LBB{{[0-9]+}}_1:
839 ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
840 ; w0 below is a reasonable guess but could change: it certainly comes into the
843 ; CHECK-NEXT: cmp w[[OLD]], w0
844 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
847 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
848 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
851 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
855 define i64 @test_atomic_load_umax_i64(i64 %offset) nounwind {
856 ; CHECK-LABEL: test_atomic_load_umax_i64:
857 %old = atomicrmw umax i64* @var64, i64 %offset release
859 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
860 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
862 ; CHECK: .LBB{{[0-9]+}}_1:
863 ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
864 ; x0 below is a reasonable guess but could change: it certainly comes into the
867 ; CHECK-NEXT: cmp x[[OLD]], x0
868 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, hi
871 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
872 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
875 ; CHECK: mov x0, x[[OLD]]
879 define i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind {
880 ; CHECK-LABEL: test_atomic_cmpxchg_i8:
881 %old = cmpxchg i8* @var8, i8 %wanted, i8 %new acquire acquire
883 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
884 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
886 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
887 ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
888 ; w0 below is a reasonable guess but could change: it certainly comes into the
890 ; CHECK-NEXT: cmp w[[OLD]], w0
891 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
892 ; CHECK: stxrb [[STATUS:w[0-9]+]], {{w[0-9]+}}, [x[[ADDR]]]
893 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
896 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
900 define i16 @test_atomic_cmpxchg_i16(i16 %wanted, i16 %new) nounwind {
901 ; CHECK-LABEL: test_atomic_cmpxchg_i16:
902 %old = cmpxchg i16* @var16, i16 %wanted, i16 %new seq_cst seq_cst
904 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
905 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
907 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
908 ; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
909 ; w0 below is a reasonable guess but could change: it certainly comes into the
911 ; CHECK-NEXT: cmp w[[OLD]], w0
912 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
913 ; CHECK: stlxrh [[STATUS:w[0-9]+]], {{w[0-9]+}}, [x[[ADDR]]]
914 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
917 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
921 define i32 @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {
922 ; CHECK-LABEL: test_atomic_cmpxchg_i32:
923 %old = cmpxchg i32* @var32, i32 %wanted, i32 %new release monotonic
925 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
926 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
928 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
929 ; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
930 ; w0 below is a reasonable guess but could change: it certainly comes into the
932 ; CHECK-NEXT: cmp w[[OLD]], w0
933 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
934 ; CHECK: stlxr [[STATUS:w[0-9]+]], {{w[0-9]+}}, [x[[ADDR]]]
935 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
938 ; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
942 define void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
943 ; CHECK-LABEL: test_atomic_cmpxchg_i64:
944 %old = cmpxchg i64* @var64, i64 %wanted, i64 %new monotonic monotonic
946 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
947 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
949 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
950 ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
951 ; w0 below is a reasonable guess but could change: it certainly comes into the
953 ; CHECK-NEXT: cmp x[[OLD]], x0
954 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
955 ; As above, w1 is a reasonable guess.
956 ; CHECK: stxr [[STATUS:w[0-9]+]], x1, [x[[ADDR]]]
957 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
960 ; CHECK: str x[[OLD]],
961 store i64 %old, i64* @var64
965 define i8 @test_atomic_load_monotonic_i8() nounwind {
966 ; CHECK-LABEL: test_atomic_load_monotonic_i8:
967 %val = load atomic i8* @var8 monotonic, align 1
969 ; CHECK: adrp x[[HIADDR:[0-9]+]], var8
970 ; CHECK: ldrb w0, [x[[HIADDR]], {{#?}}:lo12:var8]
976 define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
977 ; CHECK-LABEL: test_atomic_load_monotonic_regoff_i8:
978 %addr_int = add i64 %base, %off
979 %addr = inttoptr i64 %addr_int to i8*
981 %val = load atomic i8* %addr monotonic, align 1
983 ; CHECK: ldrb w0, [x0, x1]
989 define i8 @test_atomic_load_acquire_i8() nounwind {
990 ; CHECK-LABEL: test_atomic_load_acquire_i8:
991 %val = load atomic i8* @var8 acquire, align 1
993 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
995 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
997 ; CHECK: ldarb w0, [x[[ADDR]]]
1002 define i8 @test_atomic_load_seq_cst_i8() nounwind {
1003 ; CHECK-LABEL: test_atomic_load_seq_cst_i8:
1004 %val = load atomic i8* @var8 seq_cst, align 1
1006 ; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1008 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var8
1010 ; CHECK: ldarb w0, [x[[ADDR]]]
1015 define i16 @test_atomic_load_monotonic_i16() nounwind {
1016 ; CHECK-LABEL: test_atomic_load_monotonic_i16:
1017 %val = load atomic i16* @var16 monotonic, align 2
1019 ; CHECK: adrp x[[HIADDR:[0-9]+]], var16
1021 ; CHECK: ldrh w0, [x[[HIADDR]], {{#?}}:lo12:var16]
1027 define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {
1028 ; CHECK-LABEL: test_atomic_load_monotonic_regoff_i32:
1029 %addr_int = add i64 %base, %off
1030 %addr = inttoptr i64 %addr_int to i32*
1032 %val = load atomic i32* %addr monotonic, align 4
1034 ; CHECK: ldr w0, [x0, x1]
1040 define i64 @test_atomic_load_seq_cst_i64() nounwind {
1041 ; CHECK-LABEL: test_atomic_load_seq_cst_i64:
1042 %val = load atomic i64* @var64 seq_cst, align 8
1044 ; CHECK: adrp [[HIADDR:x[0-9]+]], var64
1046 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var64
1048 ; CHECK: ldar x0, [x[[ADDR]]]
1053 define void @test_atomic_store_monotonic_i8(i8 %val) nounwind {
1054 ; CHECK-LABEL: test_atomic_store_monotonic_i8:
1055 store atomic i8 %val, i8* @var8 monotonic, align 1
1056 ; CHECK: adrp x[[HIADDR:[0-9]+]], var8
1057 ; CHECK: strb w0, [x[[HIADDR]], {{#?}}:lo12:var8]
1062 define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {
1063 ; CHECK-LABEL: test_atomic_store_monotonic_regoff_i8:
1065 %addr_int = add i64 %base, %off
1066 %addr = inttoptr i64 %addr_int to i8*
1068 store atomic i8 %val, i8* %addr monotonic, align 1
1069 ; CHECK: strb w2, [x0, x1]
1073 define void @test_atomic_store_release_i8(i8 %val) nounwind {
1074 ; CHECK-LABEL: test_atomic_store_release_i8:
1075 store atomic i8 %val, i8* @var8 release, align 1
1077 ; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1079 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var8
1081 ; CHECK: stlrb w0, [x[[ADDR]]]
1086 define void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {
1087 ; CHECK-LABEL: test_atomic_store_seq_cst_i8:
1088 store atomic i8 %val, i8* @var8 seq_cst, align 1
1090 ; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1092 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var8
1094 ; CHECK: stlrb w0, [x[[ADDR]]]
1100 define void @test_atomic_store_monotonic_i16(i16 %val) nounwind {
1101 ; CHECK-LABEL: test_atomic_store_monotonic_i16:
1102 store atomic i16 %val, i16* @var16 monotonic, align 2
1104 ; CHECK: adrp x[[HIADDR:[0-9]+]], var16
1106 ; CHECK: strh w0, [x[[HIADDR]], {{#?}}:lo12:var16]
1111 define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {
1112 ; CHECK-LABEL: test_atomic_store_monotonic_regoff_i32:
1114 %addr_int = add i64 %base, %off
1115 %addr = inttoptr i64 %addr_int to i32*
1117 store atomic i32 %val, i32* %addr monotonic, align 4
1119 ; CHECK: str w2, [x0, x1]
1125 define void @test_atomic_store_release_i64(i64 %val) nounwind {
1126 ; CHECK-LABEL: test_atomic_store_release_i64:
1127 store atomic i64 %val, i64* @var64 release, align 8
1129 ; CHECK: adrp [[HIADDR:x[0-9]+]], var64
1131 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var64
1133 ; CHECK: stlr x0, [x[[ADDR]]]