1 ; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s
2 ; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-REG %s
9 define i8 @test_atomic_load_add_i8(i8 %offset) nounwind {
10 ; CHECK-LABEL: test_atomic_load_add_i8:
11 %old = atomicrmw add i8* @var8, i8 %offset seq_cst
13 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
14 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
16 ; CHECK: .LBB{{[0-9]+}}_1:
17 ; CHECK-NEXT: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
18 ; w0 below is a reasonable guess but could change: it certainly comes into the
20 ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
21 ; CHECK-REG: add w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
22 ; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
23 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
24 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
27 ; CHECK: mov x0, x[[OLD]]
31 define i16 @test_atomic_load_add_i16(i16 %offset) nounwind {
32 ; CHECK-LABEL: test_atomic_load_add_i16:
33 %old = atomicrmw add i16* @var16, i16 %offset acquire
35 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
36 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
38 ; CHECK: .LBB{{[0-9]+}}_1:
39 ; CHECK-NEXT: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
40 ; w0 below is a reasonable guess but could change: it certainly comes into the
42 ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
43 ; CHECK-REG: add w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
44 ; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
45 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
46 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
49 ; CHECK: mov x0, x[[OLD]]
53 define i32 @test_atomic_load_add_i32(i32 %offset) nounwind {
54 ; CHECK-LABEL: test_atomic_load_add_i32:
55 %old = atomicrmw add i32* @var32, i32 %offset release
57 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
58 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
60 ; CHECK: .LBB{{[0-9]+}}_1:
61 ; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
62 ; w0 below is a reasonable guess but could change: it certainly comes into the
64 ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
65 ; CHECK-REG: add w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
66 ; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
67 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
68 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
71 ; CHECK: mov x0, x[[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-NEXT: 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-REG: add x[[NEW:[0-9]+]], x{{[0-9]+}}, x0
88 ; CHECK-REG-NOT: stxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
89 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
90 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
93 ; CHECK: mov x0, x[[OLD]]
97 define i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {
98 ; CHECK-LABEL: test_atomic_load_sub_i8:
99 %old = atomicrmw sub i8* @var8, i8 %offset monotonic
101 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
102 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
104 ; CHECK: .LBB{{[0-9]+}}_1:
105 ; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
106 ; w0 below is a reasonable guess but could change: it certainly comes into the
108 ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
109 ; CHECK-REG: sub w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
110 ; CHECK-REG-NOT: stxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
111 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
112 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
115 ; CHECK: mov x0, x[[OLD]]
119 define i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {
120 ; CHECK-LABEL: test_atomic_load_sub_i16:
121 %old = atomicrmw sub i16* @var16, i16 %offset release
123 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
124 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
126 ; CHECK: .LBB{{[0-9]+}}_1:
127 ; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
128 ; w0 below is a reasonable guess but could change: it certainly comes into the
130 ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
131 ; CHECK-REG: sub w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
132 ; CHECK-REG-NOT: stlxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
133 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
134 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
137 ; CHECK: mov x0, x[[OLD]]
141 define i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {
142 ; CHECK-LABEL: test_atomic_load_sub_i32:
143 %old = atomicrmw sub i32* @var32, i32 %offset acquire
145 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
146 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
148 ; CHECK: .LBB{{[0-9]+}}_1:
149 ; CHECK-NEXT: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
150 ; w0 below is a reasonable guess but could change: it certainly comes into the
152 ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
153 ; CHECK-REG: sub w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
154 ; CHECK-REG-NOT: stxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
155 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
156 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
159 ; CHECK: mov x0, x[[OLD]]
163 define i64 @test_atomic_load_sub_i64(i64 %offset) nounwind {
164 ; CHECK-LABEL: test_atomic_load_sub_i64:
165 %old = atomicrmw sub i64* @var64, i64 %offset seq_cst
167 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
168 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
170 ; CHECK: .LBB{{[0-9]+}}_1:
171 ; CHECK-NEXT: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
172 ; x0 below is a reasonable guess but could change: it certainly comes into the
174 ; CHECK-NEXT: sub [[NEW:x[0-9]+]], x[[OLD]], x0
175 ; CHECK-REG: sub x[[NEW:[0-9]+]], x{{[0-9]+}}, x0
176 ; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
177 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
178 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
181 ; CHECK: mov x0, x[[OLD]]
185 define i8 @test_atomic_load_and_i8(i8 %offset) nounwind {
186 ; CHECK-LABEL: test_atomic_load_and_i8:
187 %old = atomicrmw and i8* @var8, i8 %offset release
189 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
190 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
192 ; CHECK: .LBB{{[0-9]+}}_1:
193 ; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
194 ; w0 below is a reasonable guess but could change: it certainly comes into the
196 ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
197 ; CHECK-REG: and w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
198 ; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
199 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
200 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
203 ; CHECK: mov x0, x[[OLD]]
207 define i16 @test_atomic_load_and_i16(i16 %offset) nounwind {
208 ; CHECK-LABEL: test_atomic_load_and_i16:
209 %old = atomicrmw and i16* @var16, i16 %offset monotonic
211 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
212 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
214 ; CHECK: .LBB{{[0-9]+}}_1:
215 ; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
216 ; w0 below is a reasonable guess but could change: it certainly comes into the
218 ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
219 ; CHECK-REG: and w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
220 ; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
221 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
222 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
225 ; CHECK: mov x0, x[[OLD]]
229 define i32 @test_atomic_load_and_i32(i32 %offset) nounwind {
230 ; CHECK-LABEL: test_atomic_load_and_i32:
231 %old = atomicrmw and i32* @var32, i32 %offset seq_cst
233 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
234 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
236 ; CHECK: .LBB{{[0-9]+}}_1:
237 ; CHECK-NEXT: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
238 ; w0 below is a reasonable guess but could change: it certainly comes into the
240 ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
241 ; CHECK-REG: and w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
242 ; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
243 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
244 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
247 ; CHECK: mov x0, x[[OLD]]
251 define i64 @test_atomic_load_and_i64(i64 %offset) nounwind {
252 ; CHECK-LABEL: test_atomic_load_and_i64:
253 %old = atomicrmw and i64* @var64, i64 %offset acquire
255 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
256 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
258 ; CHECK: .LBB{{[0-9]+}}_1:
259 ; CHECK-NEXT: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
260 ; x0 below is a reasonable guess but could change: it certainly comes into the
262 ; CHECK-NEXT: and [[NEW:x[0-9]+]], x[[OLD]], x0
263 ; CHECK-REG: and x[[NEW:[0-9]+]], x{{[0-9]+}}, x0
264 ; CHECK-REG-NOT: stxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
265 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
266 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
269 ; CHECK: mov x0, x[[OLD]]
273 define i8 @test_atomic_load_or_i8(i8 %offset) nounwind {
274 ; CHECK-LABEL: test_atomic_load_or_i8:
275 %old = atomicrmw or i8* @var8, i8 %offset seq_cst
277 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
278 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
280 ; CHECK: .LBB{{[0-9]+}}_1:
281 ; CHECK-NEXT: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
282 ; w0 below is a reasonable guess but could change: it certainly comes into the
284 ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
285 ; CHECK-REG: orr w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
286 ; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
287 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
288 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
291 ; CHECK: mov x0, x[[OLD]]
295 define i16 @test_atomic_load_or_i16(i16 %offset) nounwind {
296 ; CHECK-LABEL: test_atomic_load_or_i16:
297 %old = atomicrmw or i16* @var16, i16 %offset monotonic
299 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
300 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
302 ; CHECK: .LBB{{[0-9]+}}_1:
303 ; CHECK-NEXT: ldxrh 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-REG: orr w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
308 ; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
309 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
310 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
313 ; CHECK: mov x0, x[[OLD]]
317 define i32 @test_atomic_load_or_i32(i32 %offset) nounwind {
318 ; CHECK-LABEL: test_atomic_load_or_i32:
319 %old = atomicrmw or i32* @var32, i32 %offset acquire
321 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
322 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
324 ; CHECK: .LBB{{[0-9]+}}_1:
325 ; CHECK-NEXT: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
326 ; w0 below is a reasonable guess but could change: it certainly comes into the
328 ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
329 ; CHECK-REG: orr w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
330 ; CHECK-REG-NOT: stxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
331 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
332 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
335 ; CHECK: mov x0, x[[OLD]]
339 define i64 @test_atomic_load_or_i64(i64 %offset) nounwind {
340 ; CHECK-LABEL: test_atomic_load_or_i64:
341 %old = atomicrmw or i64* @var64, i64 %offset release
343 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
344 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
346 ; CHECK: .LBB{{[0-9]+}}_1:
347 ; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
348 ; x0 below is a reasonable guess but could change: it certainly comes into the
350 ; CHECK-NEXT: orr [[NEW:x[0-9]+]], x[[OLD]], x0
351 ; CHECK-REG: orr x[[NEW:[0-9]+]], x{{[0-9]+}}, x0
352 ; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
353 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
354 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
357 ; CHECK: mov x0, x[[OLD]]
361 define i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {
362 ; CHECK-LABEL: test_atomic_load_xor_i8:
363 %old = atomicrmw xor i8* @var8, i8 %offset acquire
365 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
366 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
368 ; CHECK: .LBB{{[0-9]+}}_1:
369 ; CHECK-NEXT: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
370 ; w0 below is a reasonable guess but could change: it certainly comes into the
372 ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
373 ; CHECK-REG: eor w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
374 ; CHECK-REG-NOT: stxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
375 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
376 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
379 ; CHECK: mov x0, x[[OLD]]
383 define i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {
384 ; CHECK-LABEL: test_atomic_load_xor_i16:
385 %old = atomicrmw xor i16* @var16, i16 %offset release
387 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
388 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
390 ; CHECK: .LBB{{[0-9]+}}_1:
391 ; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
392 ; w0 below is a reasonable guess but could change: it certainly comes into the
394 ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
395 ; CHECK-REG: eor w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
396 ; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
397 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
398 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
401 ; CHECK: mov x0, x[[OLD]]
405 define i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {
406 ; CHECK-LABEL: test_atomic_load_xor_i32:
407 %old = atomicrmw xor i32* @var32, i32 %offset seq_cst
409 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
410 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
412 ; CHECK: .LBB{{[0-9]+}}_1:
413 ; CHECK-NEXT: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
414 ; w0 below is a reasonable guess but could change: it certainly comes into the
416 ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
417 ; CHECK-REG: eor w[[NEW:[0-9]+]], w{{[0-9]+}}, w0
418 ; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
419 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
420 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
423 ; CHECK: mov x0, x[[OLD]]
427 define i64 @test_atomic_load_xor_i64(i64 %offset) nounwind {
428 ; CHECK-LABEL: test_atomic_load_xor_i64:
429 %old = atomicrmw xor i64* @var64, i64 %offset monotonic
431 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
432 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
434 ; CHECK: .LBB{{[0-9]+}}_1:
435 ; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
436 ; x0 below is a reasonable guess but could change: it certainly comes into the
438 ; CHECK-NEXT: eor [[NEW:x[0-9]+]], x[[OLD]], x0
439 ; CHECK-REG: eor x[[NEW:[0-9]+]], x{{[0-9]+}}, x0
440 ; CHECK-REG-NOT: stxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
441 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
442 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
445 ; CHECK: mov x0, x[[OLD]]
449 define i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {
450 ; CHECK-LABEL: test_atomic_load_xchg_i8:
451 %old = atomicrmw xchg i8* @var8, i8 %offset monotonic
453 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
454 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
456 ; CHECK: .LBB{{[0-9]+}}_1:
457 ; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
458 ; w0 below is a reasonable guess but could change: it certainly comes into the
460 ; CHECK-REG-NOT: stxrb w0, w0, [x{{[0-9]+}}]
461 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
462 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
465 ; CHECK: mov x0, x[[OLD]]
469 define i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {
470 ; CHECK-LABEL: test_atomic_load_xchg_i16:
471 %old = atomicrmw xchg i16* @var16, i16 %offset seq_cst
473 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
474 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
476 ; CHECK: .LBB{{[0-9]+}}_1:
477 ; CHECK-NEXT: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
478 ; w0 below is a reasonable guess but could change: it certainly comes into the
480 ; CHECK-REG-NOT: stlxrh w0, w0, [x{{[0-9]+}}]
481 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
482 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
485 ; CHECK: mov x0, x[[OLD]]
489 define i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {
490 ; CHECK-LABEL: test_atomic_load_xchg_i32:
491 %old = atomicrmw xchg i32* @var32, i32 %offset release
493 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
494 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
496 ; CHECK: .LBB{{[0-9]+}}_1:
497 ; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
498 ; w0 below is a reasonable guess but could change: it certainly comes into the
500 ; CHECK-REG-NOT: stlxr w0, w0, [x{{[0-9]+}}]
501 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
502 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
505 ; CHECK: mov x0, x[[OLD]]
509 define i64 @test_atomic_load_xchg_i64(i64 %offset) nounwind {
510 ; CHECK-LABEL: test_atomic_load_xchg_i64:
511 %old = atomicrmw xchg i64* @var64, i64 %offset acquire
513 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
514 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
516 ; CHECK: .LBB{{[0-9]+}}_1:
517 ; CHECK-NEXT: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
518 ; x0 below is a reasonable guess but could change: it certainly comes into the
520 ; CHECK-REG-NOT: stxr w0, x0, [x{{[0-9]+}}]
521 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], x0, [x[[ADDR]]]
522 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
525 ; CHECK: mov x0, x[[OLD]]
530 define i8 @test_atomic_load_min_i8(i8 %offset) nounwind {
531 ; CHECK-LABEL: test_atomic_load_min_i8:
532 %old = atomicrmw min i8* @var8, i8 %offset acquire
534 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
535 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
537 ; CHECK: .LBB{{[0-9]+}}_1:
538 ; CHECK-NEXT: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
539 ; w0 below is a reasonable guess but could change: it certainly comes into the
541 ; CHECK-NEXT: cmp w0, w[[OLD]], sxtb
542 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
543 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, gt
544 ; CHECK-REG-NOT: stxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
545 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
546 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
549 ; CHECK: mov x0, x[[OLD]]
553 define i16 @test_atomic_load_min_i16(i16 %offset) nounwind {
554 ; CHECK-LABEL: test_atomic_load_min_i16:
555 %old = atomicrmw min i16* @var16, i16 %offset release
557 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
558 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
560 ; CHECK: .LBB{{[0-9]+}}_1:
561 ; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
562 ; w0 below is a reasonable guess but could change: it certainly comes into the
564 ; CHECK-NEXT: cmp w0, w[[OLD]], sxth
565 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
566 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, gt
567 ; CHECK-REG-NOT: stlxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
568 ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
569 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
572 ; CHECK: mov x0, x[[OLD]]
576 define i32 @test_atomic_load_min_i32(i32 %offset) nounwind {
577 ; CHECK-LABEL: test_atomic_load_min_i32:
578 %old = atomicrmw min i32* @var32, i32 %offset monotonic
580 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
581 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
583 ; CHECK: .LBB{{[0-9]+}}_1:
584 ; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
585 ; w0 below is a reasonable guess but could change: it certainly comes into the
587 ; CHECK-NEXT: cmp w0, w[[OLD]]
588 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
589 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, gt
590 ; CHECK-REG-NOT: stxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
591 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
592 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
595 ; CHECK: mov x0, x[[OLD]]
599 define i64 @test_atomic_load_min_i64(i64 %offset) nounwind {
600 ; CHECK-LABEL: test_atomic_load_min_i64:
601 %old = atomicrmw min i64* @var64, i64 %offset seq_cst
603 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
604 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
606 ; CHECK: .LBB{{[0-9]+}}_1:
607 ; CHECK-NEXT: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
608 ; x0 below is a reasonable guess but could change: it certainly comes into the
610 ; CHECK-NEXT: cmp x0, x[[OLD]]
611 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, gt
612 ; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, gt
613 ; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
614 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
615 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
618 ; CHECK: mov x0, x[[OLD]]
622 define i8 @test_atomic_load_max_i8(i8 %offset) nounwind {
623 ; CHECK-LABEL: test_atomic_load_max_i8:
624 %old = atomicrmw max i8* @var8, i8 %offset seq_cst
626 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
627 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
629 ; CHECK: .LBB{{[0-9]+}}_1:
630 ; CHECK-NEXT: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
631 ; w0 below is a reasonable guess but could change: it certainly comes into the
633 ; CHECK-NEXT: cmp w0, w[[OLD]], sxtb
634 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt
635 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lt
636 ; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
637 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
638 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
641 ; CHECK: mov x0, x[[OLD]]
645 define i16 @test_atomic_load_max_i16(i16 %offset) nounwind {
646 ; CHECK-LABEL: test_atomic_load_max_i16:
647 %old = atomicrmw max i16* @var16, i16 %offset acquire
649 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
650 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
652 ; CHECK: .LBB{{[0-9]+}}_1:
653 ; CHECK-NEXT: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
654 ; w0 below is a reasonable guess but could change: it certainly comes into the
656 ; CHECK-NEXT: cmp w0, w[[OLD]], sxth
657 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt
658 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lt
659 ; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
660 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
661 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
664 ; CHECK: mov x0, x[[OLD]]
668 define i32 @test_atomic_load_max_i32(i32 %offset) nounwind {
669 ; CHECK-LABEL: test_atomic_load_max_i32:
670 %old = atomicrmw max i32* @var32, i32 %offset release
672 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
673 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
675 ; CHECK: .LBB{{[0-9]+}}_1:
676 ; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
677 ; w0 below is a reasonable guess but could change: it certainly comes into the
679 ; CHECK-NEXT: cmp w0, w[[OLD]]
680 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt
681 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lt
682 ; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
683 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
684 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
687 ; CHECK: mov x0, x[[OLD]]
691 define i64 @test_atomic_load_max_i64(i64 %offset) nounwind {
692 ; CHECK-LABEL: test_atomic_load_max_i64:
693 %old = atomicrmw max i64* @var64, i64 %offset monotonic
695 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
696 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
698 ; CHECK: .LBB{{[0-9]+}}_1:
699 ; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
700 ; x0 below is a reasonable guess but could change: it certainly comes into the
702 ; CHECK-NEXT: cmp x0, x[[OLD]]
703 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lt
704 ; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, lt
705 ; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
706 ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
707 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
710 ; CHECK: mov x0, x[[OLD]]
714 define i8 @test_atomic_load_umin_i8(i8 %offset) nounwind {
715 ; CHECK-LABEL: test_atomic_load_umin_i8:
716 %old = atomicrmw umin i8* @var8, i8 %offset monotonic
718 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
719 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
721 ; CHECK: .LBB{{[0-9]+}}_1:
722 ; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
723 ; w0 below is a reasonable guess but could change: it certainly comes into the
725 ; CHECK-NEXT: cmp w0, w[[OLD]], uxtb
726 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
727 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, hi
728 ; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
729 ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
730 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
733 ; CHECK: mov x0, x[[OLD]]
737 define i16 @test_atomic_load_umin_i16(i16 %offset) nounwind {
738 ; CHECK-LABEL: test_atomic_load_umin_i16:
739 %old = atomicrmw umin i16* @var16, i16 %offset acquire
741 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
742 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
744 ; CHECK: .LBB{{[0-9]+}}_1:
745 ; CHECK-NEXT: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
746 ; w0 below is a reasonable guess but could change: it certainly comes into the
748 ; CHECK-NEXT: cmp w0, w[[OLD]], uxth
749 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
750 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, hi
751 ; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
752 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
753 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
756 ; CHECK: mov x0, x[[OLD]]
760 define i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {
761 ; CHECK-LABEL: test_atomic_load_umin_i32:
762 %old = atomicrmw umin i32* @var32, i32 %offset seq_cst
764 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
765 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
767 ; CHECK: .LBB{{[0-9]+}}_1:
768 ; CHECK-NEXT: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
769 ; w0 below is a reasonable guess but could change: it certainly comes into the
771 ; CHECK-NEXT: cmp w0, w[[OLD]]
772 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
773 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, hi
774 ; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
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 i64 @test_atomic_load_umin_i64(i64 %offset) nounwind {
784 ; CHECK-LABEL: test_atomic_load_umin_i64:
785 %old = atomicrmw umin i64* @var64, i64 %offset acq_rel
787 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
788 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
790 ; CHECK: .LBB{{[0-9]+}}_1:
791 ; CHECK-NEXT: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
792 ; x0 below is a reasonable guess but could change: it certainly comes into the
794 ; CHECK-NEXT: cmp x0, x[[OLD]]
795 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, hi
796 ; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, hi
797 ; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
798 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
799 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
802 ; CHECK: mov x0, x[[OLD]]
806 define i8 @test_atomic_load_umax_i8(i8 %offset) nounwind {
807 ; CHECK-LABEL: test_atomic_load_umax_i8:
808 %old = atomicrmw umax i8* @var8, i8 %offset acq_rel
810 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
811 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
813 ; CHECK: .LBB{{[0-9]+}}_1:
814 ; CHECK-NEXT: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
815 ; w0 below is a reasonable guess but could change: it certainly comes into the
817 ; CHECK-NEXT: cmp w0, w[[OLD]], uxtb
818 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo
819 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lo
820 ; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
821 ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
822 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
825 ; CHECK: mov x0, x[[OLD]]
829 define i16 @test_atomic_load_umax_i16(i16 %offset) nounwind {
830 ; CHECK-LABEL: test_atomic_load_umax_i16:
831 %old = atomicrmw umax i16* @var16, i16 %offset monotonic
833 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
834 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
836 ; CHECK: .LBB{{[0-9]+}}_1:
837 ; CHECK-NEXT: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
838 ; w0 below is a reasonable guess but could change: it certainly comes into the
840 ; CHECK-NEXT: cmp w0, w[[OLD]], uxth
841 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo
842 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lo
843 ; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
844 ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
845 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
848 ; CHECK: mov x0, x[[OLD]]
852 define i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {
853 ; CHECK-LABEL: test_atomic_load_umax_i32:
854 %old = atomicrmw umax i32* @var32, i32 %offset seq_cst
856 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
857 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
859 ; CHECK: .LBB{{[0-9]+}}_1:
860 ; CHECK-NEXT: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
861 ; w0 below is a reasonable guess but could change: it certainly comes into the
863 ; CHECK-NEXT: cmp w0, w[[OLD]]
864 ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo
865 ; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lo
866 ; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}]
867 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
868 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
871 ; CHECK: mov x0, x[[OLD]]
875 define i64 @test_atomic_load_umax_i64(i64 %offset) nounwind {
876 ; CHECK-LABEL: test_atomic_load_umax_i64:
877 %old = atomicrmw umax i64* @var64, i64 %offset release
879 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
880 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
882 ; CHECK: .LBB{{[0-9]+}}_1:
883 ; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
884 ; x0 below is a reasonable guess but could change: it certainly comes into the
886 ; CHECK-NEXT: cmp x0, x[[OLD]]
887 ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lo
888 ; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, lo
889 ; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}]
890 ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
891 ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
894 ; CHECK: mov x0, x[[OLD]]
898 define i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind {
899 ; CHECK-LABEL: test_atomic_cmpxchg_i8:
900 %old = cmpxchg i8* @var8, i8 %wanted, i8 %new acquire
902 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
903 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
905 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
906 ; CHECK-NEXT: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
907 ; w0 below is a reasonable guess but could change: it certainly comes into the
909 ; CHECK-NEXT: cmp w[[OLD]], w0
910 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
911 ; As above, w1 is a reasonable guess.
912 ; CHECK-REG-NOT: stxrb w1, w1, [x{{[0-9]+}}]
913 ; CHECK: stxrb [[STATUS:w[0-9]+]], w1, [x[[ADDR]]]
914 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
917 ; CHECK: mov x0, x[[OLD]]
921 define i16 @test_atomic_cmpxchg_i16(i16 %wanted, i16 %new) nounwind {
922 ; CHECK-LABEL: test_atomic_cmpxchg_i16:
923 %old = cmpxchg i16* @var16, i16 %wanted, i16 %new seq_cst
925 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
926 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var16
928 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
929 ; CHECK-NEXT: ldaxrh 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 ; As above, w1 is a reasonable guess.
935 ; CHECK-REG-NOT: stlxrh w1, w1, [x{{[0-9]+}}]
936 ; CHECK: stlxrh [[STATUS:w[0-9]+]], w1, [x[[ADDR]]]
937 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
940 ; CHECK: mov x0, x[[OLD]]
944 define i32 @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {
945 ; CHECK-LABEL: test_atomic_cmpxchg_i32:
946 %old = cmpxchg i32* @var32, i32 %wanted, i32 %new release
948 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
949 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var32
951 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
952 ; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
953 ; w0 below is a reasonable guess but could change: it certainly comes into the
955 ; CHECK-NEXT: cmp w[[OLD]], w0
956 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
957 ; As above, w1 is a reasonable guess.
958 ; CHECK-REG-NOT: stlxr w1, w1, [x{{[0-9]+}}]
959 ; CHECK: stlxr [[STATUS:w[0-9]+]], w1, [x[[ADDR]]]
960 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
963 ; CHECK: mov x0, x[[OLD]]
967 define i64 @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
968 ; CHECK-LABEL: test_atomic_cmpxchg_i64:
969 %old = cmpxchg i64* @var64, i64 %wanted, i64 %new monotonic
971 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
972 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var64
974 ; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
975 ; CHECK-NEXT: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
976 ; w0 below is a reasonable guess but could change: it certainly comes into the
978 ; CHECK-NEXT: cmp x[[OLD]], x0
979 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
980 ; As above, w1 is a reasonable guess.
981 ; CHECK-REG-NOT: stxr w1, x1, [x{{[0-9]+}}]
982 ; CHECK: stxr [[STATUS:w[0-9]+]], x1, [x[[ADDR]]]
983 ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
986 ; CHECK: mov x0, x[[OLD]]
990 define i8 @test_atomic_load_monotonic_i8() nounwind {
991 ; CHECK-LABEL: test_atomic_load_monotonic_i8:
992 %val = load atomic i8* @var8 monotonic, align 1
994 ; CHECK: adrp x[[HIADDR:[0-9]+]], var8
995 ; CHECK: ldrb w0, [x[[HIADDR]], #:lo12:var8]
1001 define i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
1002 ; CHECK-LABEL: test_atomic_load_monotonic_regoff_i8:
1003 %addr_int = add i64 %base, %off
1004 %addr = inttoptr i64 %addr_int to i8*
1006 %val = load atomic i8* %addr monotonic, align 1
1008 ; CHECK: ldrb w0, [x0, x1]
1014 define i8 @test_atomic_load_acquire_i8() nounwind {
1015 ; CHECK-LABEL: test_atomic_load_acquire_i8:
1016 %val = load atomic i8* @var8 acquire, align 1
1018 ; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
1020 ; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], #:lo12:var8
1022 ; CHECK: ldarb w0, [x[[ADDR]]]
1027 define i8 @test_atomic_load_seq_cst_i8() nounwind {
1028 ; CHECK-LABEL: test_atomic_load_seq_cst_i8:
1029 %val = load atomic i8* @var8 seq_cst, align 1
1031 ; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1033 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var8
1035 ; CHECK: ldarb w0, [x[[ADDR]]]
1040 define i16 @test_atomic_load_monotonic_i16() nounwind {
1041 ; CHECK-LABEL: test_atomic_load_monotonic_i16:
1042 %val = load atomic i16* @var16 monotonic, align 2
1044 ; CHECK: adrp x[[HIADDR:[0-9]+]], var16
1046 ; CHECK: ldrh w0, [x[[HIADDR]], #:lo12:var16]
1052 define i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {
1053 ; CHECK-LABEL: test_atomic_load_monotonic_regoff_i32:
1054 %addr_int = add i64 %base, %off
1055 %addr = inttoptr i64 %addr_int to i32*
1057 %val = load atomic i32* %addr monotonic, align 4
1059 ; CHECK: ldr w0, [x0, x1]
1065 define i64 @test_atomic_load_seq_cst_i64() nounwind {
1066 ; CHECK-LABEL: test_atomic_load_seq_cst_i64:
1067 %val = load atomic i64* @var64 seq_cst, align 8
1069 ; CHECK: adrp [[HIADDR:x[0-9]+]], var64
1071 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var64
1073 ; CHECK: ldar x0, [x[[ADDR]]]
1078 define void @test_atomic_store_monotonic_i8(i8 %val) nounwind {
1079 ; CHECK-LABEL: test_atomic_store_monotonic_i8:
1080 store atomic i8 %val, i8* @var8 monotonic, align 1
1081 ; CHECK: adrp x[[HIADDR:[0-9]+]], var8
1082 ; CHECK: strb w0, [x[[HIADDR]], #:lo12:var8]
1087 define void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {
1088 ; CHECK-LABEL: test_atomic_store_monotonic_regoff_i8:
1090 %addr_int = add i64 %base, %off
1091 %addr = inttoptr i64 %addr_int to i8*
1093 store atomic i8 %val, i8* %addr monotonic, align 1
1094 ; CHECK: strb w2, [x0, x1]
1098 define void @test_atomic_store_release_i8(i8 %val) nounwind {
1099 ; CHECK-LABEL: test_atomic_store_release_i8:
1100 store atomic i8 %val, i8* @var8 release, align 1
1102 ; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1104 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var8
1106 ; CHECK: stlrb w0, [x[[ADDR]]]
1111 define void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {
1112 ; CHECK-LABEL: test_atomic_store_seq_cst_i8:
1113 store atomic i8 %val, i8* @var8 seq_cst, align 1
1115 ; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1117 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var8
1119 ; CHECK: stlrb w0, [x[[ADDR]]]
1125 define void @test_atomic_store_monotonic_i16(i16 %val) nounwind {
1126 ; CHECK-LABEL: test_atomic_store_monotonic_i16:
1127 store atomic i16 %val, i16* @var16 monotonic, align 2
1129 ; CHECK: adrp x[[HIADDR:[0-9]+]], var16
1131 ; CHECK: strh w0, [x[[HIADDR]], #:lo12:var16]
1136 define void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {
1137 ; CHECK-LABEL: test_atomic_store_monotonic_regoff_i32:
1139 %addr_int = add i64 %base, %off
1140 %addr = inttoptr i64 %addr_int to i32*
1142 store atomic i32 %val, i32* %addr monotonic, align 4
1144 ; CHECK: str w2, [x0, x1]
1150 define void @test_atomic_store_release_i64(i64 %val) nounwind {
1151 ; CHECK-LABEL: test_atomic_store_release_i64:
1152 store atomic i64 %val, i64* @var64 release, align 8
1154 ; CHECK: adrp [[HIADDR:x[0-9]+]], var64
1156 ; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], #:lo12:var64
1158 ; CHECK: stlr x0, [x[[ADDR]]]