xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/atomic-ops.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK-REG
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; Point of CHECK-REG is to make sure UNPREDICTABLE instructions aren't created
6*9880d681SAndroid Build Coastguard Worker; (i.e. reusing a register for status & data in store exclusive).
7*9880d681SAndroid Build Coastguard Worker; CHECK-REG-NOT: stlxrb w[[NEW:[0-9]+]], w[[NEW]], [x{{[0-9]+}}]
8*9880d681SAndroid Build Coastguard Worker; CHECK-REG-NOT: stlxrb w[[NEW:[0-9]+]], x[[NEW]], [x{{[0-9]+}}]
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker@var8 = global i8 0
11*9880d681SAndroid Build Coastguard Worker@var16 = global i16 0
12*9880d681SAndroid Build Coastguard Worker@var32 = global i32 0
13*9880d681SAndroid Build Coastguard Worker@var64 = global i64 0
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_add_i8(i8 %offset) nounwind {
16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i8:
17*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i8* @var8, i8 %offset seq_cst
18*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
19*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
20*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
23*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
24*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
25*9880d681SAndroid Build Coastguard Worker  ;  function there.
26*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
27*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
28*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
29*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
32*9880d681SAndroid Build Coastguard Worker   ret i8 %old
33*9880d681SAndroid Build Coastguard Worker}
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_add_i16(i16 %offset) nounwind {
36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i16:
37*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i16* @var16, i16 %offset acquire
38*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
39*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
40*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
43*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
44*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
45*9880d681SAndroid Build Coastguard Worker  ;  function there.
46*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
47*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
48*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
49*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
52*9880d681SAndroid Build Coastguard Worker   ret i16 %old
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_add_i32(i32 %offset) nounwind {
56*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i32:
57*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i32* @var32, i32 %offset release
58*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
59*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
60*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
63*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
64*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
65*9880d681SAndroid Build Coastguard Worker  ;  function there.
66*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0
67*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
69*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
72*9880d681SAndroid Build Coastguard Worker   ret i32 %old
73*9880d681SAndroid Build Coastguard Worker}
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_add_i64(i64 %offset) nounwind {
76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i64:
77*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i64* @var64, i64 %offset monotonic
78*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
79*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
80*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
83*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
84*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
85*9880d681SAndroid Build Coastguard Worker  ; function there.
86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW:x[0-9]+]], x[[OLD]], x0
87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
89*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
92*9880d681SAndroid Build Coastguard Worker   ret i64 %old
93*9880d681SAndroid Build Coastguard Worker}
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {
96*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i8:
97*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i8* @var8, i8 %offset monotonic
98*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
99*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
100*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
103*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
104*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
105*9880d681SAndroid Build Coastguard Worker  ;  function there.
106*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
109*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
112*9880d681SAndroid Build Coastguard Worker   ret i8 %old
113*9880d681SAndroid Build Coastguard Worker}
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {
116*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i16:
117*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i16* @var16, i16 %offset release
118*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
119*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
120*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
123*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
124*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
125*9880d681SAndroid Build Coastguard Worker  ;  function there.
126*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
127*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
128*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
129*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
132*9880d681SAndroid Build Coastguard Worker   ret i16 %old
133*9880d681SAndroid Build Coastguard Worker}
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {
136*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i32:
137*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i32* @var32, i32 %offset acquire
138*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
139*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
140*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
143*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
144*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
145*9880d681SAndroid Build Coastguard Worker  ;  function there.
146*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0
147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
149*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
152*9880d681SAndroid Build Coastguard Worker   ret i32 %old
153*9880d681SAndroid Build Coastguard Worker}
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_sub_i64(i64 %offset) nounwind {
156*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i64:
157*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i64* @var64, i64 %offset seq_cst
158*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
159*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
160*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
163*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
164*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
165*9880d681SAndroid Build Coastguard Worker  ; function there.
166*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[NEW:x[0-9]+]], x[[OLD]], x0
167*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
168*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
169*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
172*9880d681SAndroid Build Coastguard Worker   ret i64 %old
173*9880d681SAndroid Build Coastguard Worker}
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_and_i8(i8 %offset) nounwind {
176*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i8:
177*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i8* @var8, i8 %offset release
178*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
179*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
180*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
183*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
184*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
185*9880d681SAndroid Build Coastguard Worker  ;  function there.
186*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
188*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
189*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
192*9880d681SAndroid Build Coastguard Worker   ret i8 %old
193*9880d681SAndroid Build Coastguard Worker}
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_and_i16(i16 %offset) nounwind {
196*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i16:
197*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i16* @var16, i16 %offset monotonic
198*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
199*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
200*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
203*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
204*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
205*9880d681SAndroid Build Coastguard Worker  ;  function there.
206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
209*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
212*9880d681SAndroid Build Coastguard Worker   ret i16 %old
213*9880d681SAndroid Build Coastguard Worker}
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_and_i32(i32 %offset) nounwind {
216*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i32:
217*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i32* @var32, i32 %offset seq_cst
218*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
219*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
220*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
223*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
224*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
225*9880d681SAndroid Build Coastguard Worker  ;  function there.
226*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0
227*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
228*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
229*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
232*9880d681SAndroid Build Coastguard Worker   ret i32 %old
233*9880d681SAndroid Build Coastguard Worker}
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_and_i64(i64 %offset) nounwind {
236*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i64:
237*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i64* @var64, i64 %offset acquire
238*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
239*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
240*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
243*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
244*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
245*9880d681SAndroid Build Coastguard Worker  ; function there.
246*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and [[NEW:x[0-9]+]], x[[OLD]], x0
247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
249*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
252*9880d681SAndroid Build Coastguard Worker   ret i64 %old
253*9880d681SAndroid Build Coastguard Worker}
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_or_i8(i8 %offset) nounwind {
256*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i8:
257*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i8* @var8, i8 %offset seq_cst
258*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
259*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
260*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
263*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
264*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
265*9880d681SAndroid Build Coastguard Worker  ;  function there.
266*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
267*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
268*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
269*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
272*9880d681SAndroid Build Coastguard Worker   ret i8 %old
273*9880d681SAndroid Build Coastguard Worker}
274*9880d681SAndroid Build Coastguard Worker
275*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_or_i16(i16 %offset) nounwind {
276*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i16:
277*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i16* @var16, i16 %offset monotonic
278*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
279*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
280*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
283*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
284*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
285*9880d681SAndroid Build Coastguard Worker  ;  function there.
286*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
287*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
288*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
289*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
292*9880d681SAndroid Build Coastguard Worker   ret i16 %old
293*9880d681SAndroid Build Coastguard Worker}
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_or_i32(i32 %offset) nounwind {
296*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i32:
297*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i32* @var32, i32 %offset acquire
298*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
299*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
300*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
303*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
304*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
305*9880d681SAndroid Build Coastguard Worker  ;  function there.
306*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0
307*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
308*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
309*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
312*9880d681SAndroid Build Coastguard Worker   ret i32 %old
313*9880d681SAndroid Build Coastguard Worker}
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_or_i64(i64 %offset) nounwind {
316*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i64:
317*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i64* @var64, i64 %offset release
318*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
319*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
320*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
323*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
324*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
325*9880d681SAndroid Build Coastguard Worker  ; function there.
326*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr [[NEW:x[0-9]+]], x[[OLD]], x0
327*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
328*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
329*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
330*9880d681SAndroid Build Coastguard Worker
331*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
332*9880d681SAndroid Build Coastguard Worker   ret i64 %old
333*9880d681SAndroid Build Coastguard Worker}
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {
336*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i8:
337*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i8* @var8, i8 %offset acquire
338*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
339*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
340*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
343*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
344*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
345*9880d681SAndroid Build Coastguard Worker  ;  function there.
346*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
347*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
348*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
349*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
352*9880d681SAndroid Build Coastguard Worker   ret i8 %old
353*9880d681SAndroid Build Coastguard Worker}
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {
356*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i16:
357*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i16* @var16, i16 %offset release
358*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
359*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
360*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
363*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
364*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
365*9880d681SAndroid Build Coastguard Worker  ;  function there.
366*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
367*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
368*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
369*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
370*9880d681SAndroid Build Coastguard Worker
371*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
372*9880d681SAndroid Build Coastguard Worker   ret i16 %old
373*9880d681SAndroid Build Coastguard Worker}
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {
376*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i32:
377*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i32* @var32, i32 %offset seq_cst
378*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
379*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
380*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
383*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
384*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
385*9880d681SAndroid Build Coastguard Worker  ;  function there.
386*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0
387*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
388*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
389*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
392*9880d681SAndroid Build Coastguard Worker   ret i32 %old
393*9880d681SAndroid Build Coastguard Worker}
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_xor_i64(i64 %offset) nounwind {
396*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i64:
397*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i64* @var64, i64 %offset monotonic
398*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
399*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
400*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
401*9880d681SAndroid Build Coastguard Worker
402*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
403*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
404*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
405*9880d681SAndroid Build Coastguard Worker  ; function there.
406*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: eor [[NEW:x[0-9]+]], x[[OLD]], x0
407*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
408*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
409*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
412*9880d681SAndroid Build Coastguard Worker   ret i64 %old
413*9880d681SAndroid Build Coastguard Worker}
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {
416*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i8:
417*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i8* @var8, i8 %offset monotonic
418*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
419*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
420*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
423*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
424*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
425*9880d681SAndroid Build Coastguard Worker  ; function there.
426*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
427*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
428*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
429*9880d681SAndroid Build Coastguard Worker
430*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
431*9880d681SAndroid Build Coastguard Worker   ret i8 %old
432*9880d681SAndroid Build Coastguard Worker}
433*9880d681SAndroid Build Coastguard Worker
434*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {
435*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i16:
436*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i16* @var16, i16 %offset seq_cst
437*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
438*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
439*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
442*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
443*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
444*9880d681SAndroid Build Coastguard Worker  ; function there.
445*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
446*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
447*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
450*9880d681SAndroid Build Coastguard Worker   ret i16 %old
451*9880d681SAndroid Build Coastguard Worker}
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {
454*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i32:
455*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i32* @var32, i32 %offset release
456*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
457*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
458*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
459*9880d681SAndroid Build Coastguard Worker
460*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
461*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
462*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
463*9880d681SAndroid Build Coastguard Worker  ;  function there.
464*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], w0, [x[[ADDR]]]
465*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
466*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
469*9880d681SAndroid Build Coastguard Worker   ret i32 %old
470*9880d681SAndroid Build Coastguard Worker}
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_xchg_i64(i64 %offset) nounwind {
473*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i64:
474*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i64* @var64, i64 %offset acquire
475*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
476*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
477*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
480*9880d681SAndroid Build Coastguard Worker; ; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
481*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
482*9880d681SAndroid Build Coastguard Worker  ; function there.
483*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], x0, [x[[ADDR]]]
484*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
485*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
488*9880d681SAndroid Build Coastguard Worker   ret i64 %old
489*9880d681SAndroid Build Coastguard Worker}
490*9880d681SAndroid Build Coastguard Worker
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_min_i8(i8 %offset) nounwind {
493*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i8:
494*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i8* @var8, i8 %offset acquire
495*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
496*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
497*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
498*9880d681SAndroid Build Coastguard Worker
499*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
500*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
501*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
502*9880d681SAndroid Build Coastguard Worker  ;  function there.
503*9880d681SAndroid Build Coastguard Worker
504*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxtb w[[OLD_EXT:[0-9]+]], w[[OLD]]
505*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxtb
506*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, le
507*9880d681SAndroid Build Coastguard Worker
508*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
509*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
510*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
511*9880d681SAndroid Build Coastguard Worker
512*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD_EXT]]
513*9880d681SAndroid Build Coastguard Worker   ret i8 %old
514*9880d681SAndroid Build Coastguard Worker}
515*9880d681SAndroid Build Coastguard Worker
516*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_min_i16(i16 %offset) nounwind {
517*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i16:
518*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i16* @var16, i16 %offset release
519*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
520*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
521*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
524*9880d681SAndroid Build Coastguard Worker; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
525*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
526*9880d681SAndroid Build Coastguard Worker  ;  function there.
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxth w[[OLD_EXT:[0-9]+]], w[[OLD]]
529*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxth
530*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, le
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker
533*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
534*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
535*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
536*9880d681SAndroid Build Coastguard Worker
537*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD_EXT]]
538*9880d681SAndroid Build Coastguard Worker   ret i16 %old
539*9880d681SAndroid Build Coastguard Worker}
540*9880d681SAndroid Build Coastguard Worker
541*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_min_i32(i32 %offset) nounwind {
542*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i32:
543*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i32* @var32, i32 %offset monotonic
544*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
545*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
546*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
549*9880d681SAndroid Build Coastguard Worker; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
550*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
551*9880d681SAndroid Build Coastguard Worker  ;  function there.
552*9880d681SAndroid Build Coastguard Worker
553*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0
554*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, le
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Worker
557*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
558*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
559*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
560*9880d681SAndroid Build Coastguard Worker
561*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
562*9880d681SAndroid Build Coastguard Worker   ret i32 %old
563*9880d681SAndroid Build Coastguard Worker}
564*9880d681SAndroid Build Coastguard Worker
565*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_min_i64(i64 %offset) nounwind {
566*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i64:
567*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i64* @var64, i64 %offset seq_cst
568*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
569*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
570*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
571*9880d681SAndroid Build Coastguard Worker
572*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
573*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
574*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
575*9880d681SAndroid Build Coastguard Worker  ; function there.
576*9880d681SAndroid Build Coastguard Worker
577*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x[[OLD]], x0
578*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, le
579*9880d681SAndroid Build Coastguard Worker
580*9880d681SAndroid Build Coastguard Worker
581*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
582*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
583*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
584*9880d681SAndroid Build Coastguard Worker
585*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
586*9880d681SAndroid Build Coastguard Worker   ret i64 %old
587*9880d681SAndroid Build Coastguard Worker}
588*9880d681SAndroid Build Coastguard Worker
589*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_max_i8(i8 %offset) nounwind {
590*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i8:
591*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i8* @var8, i8 %offset seq_cst
592*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
593*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
594*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
595*9880d681SAndroid Build Coastguard Worker
596*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
597*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
598*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
599*9880d681SAndroid Build Coastguard Worker  ;  function there.
600*9880d681SAndroid Build Coastguard Worker
601*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxtb w[[OLD_EXT:[0-9]+]], w[[OLD]]
602*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxtb
603*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
604*9880d681SAndroid Build Coastguard Worker
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
607*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
608*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
609*9880d681SAndroid Build Coastguard Worker
610*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD_EXT]]
611*9880d681SAndroid Build Coastguard Worker   ret i8 %old
612*9880d681SAndroid Build Coastguard Worker}
613*9880d681SAndroid Build Coastguard Worker
614*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_max_i16(i16 %offset) nounwind {
615*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i16:
616*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i16* @var16, i16 %offset acquire
617*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
618*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
619*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
620*9880d681SAndroid Build Coastguard Worker
621*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
622*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
623*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
624*9880d681SAndroid Build Coastguard Worker  ;  function there.
625*9880d681SAndroid Build Coastguard Worker
626*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxth w[[OLD_EXT:[0-9]+]], w[[OLD]]
627*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD_EXT]], w0, sxth
628*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker
631*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
632*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
633*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
634*9880d681SAndroid Build Coastguard Worker
635*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD_EXT]]
636*9880d681SAndroid Build Coastguard Worker   ret i16 %old
637*9880d681SAndroid Build Coastguard Worker}
638*9880d681SAndroid Build Coastguard Worker
639*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_max_i32(i32 %offset) nounwind {
640*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i32:
641*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i32* @var32, i32 %offset release
642*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
643*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
644*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
645*9880d681SAndroid Build Coastguard Worker
646*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
647*9880d681SAndroid Build Coastguard Worker; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
648*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
649*9880d681SAndroid Build Coastguard Worker  ;  function there.
650*9880d681SAndroid Build Coastguard Worker
651*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0
652*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt
653*9880d681SAndroid Build Coastguard Worker
654*9880d681SAndroid Build Coastguard Worker
655*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
656*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
657*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
660*9880d681SAndroid Build Coastguard Worker   ret i32 %old
661*9880d681SAndroid Build Coastguard Worker}
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_max_i64(i64 %offset) nounwind {
664*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i64:
665*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i64* @var64, i64 %offset monotonic
666*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
667*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
668*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
669*9880d681SAndroid Build Coastguard Worker
670*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
671*9880d681SAndroid Build Coastguard Worker; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
672*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
673*9880d681SAndroid Build Coastguard Worker  ; function there.
674*9880d681SAndroid Build Coastguard Worker
675*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x[[OLD]], x0
676*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, gt
677*9880d681SAndroid Build Coastguard Worker
678*9880d681SAndroid Build Coastguard Worker
679*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
680*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
681*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
682*9880d681SAndroid Build Coastguard Worker
683*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
684*9880d681SAndroid Build Coastguard Worker   ret i64 %old
685*9880d681SAndroid Build Coastguard Worker}
686*9880d681SAndroid Build Coastguard Worker
687*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_umin_i8(i8 %offset) nounwind {
688*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i8:
689*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i8* @var8, i8 %offset monotonic
690*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
691*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
692*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
693*9880d681SAndroid Build Coastguard Worker
694*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
695*9880d681SAndroid Build Coastguard Worker; CHECK: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
696*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
697*9880d681SAndroid Build Coastguard Worker  ;  function there.
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0, uxtb
700*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, ls
701*9880d681SAndroid Build Coastguard Worker
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
704*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
705*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
706*9880d681SAndroid Build Coastguard Worker
707*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
708*9880d681SAndroid Build Coastguard Worker   ret i8 %old
709*9880d681SAndroid Build Coastguard Worker}
710*9880d681SAndroid Build Coastguard Worker
711*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_umin_i16(i16 %offset) nounwind {
712*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i16:
713*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i16* @var16, i16 %offset acquire
714*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
715*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
716*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
717*9880d681SAndroid Build Coastguard Worker
718*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
719*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
720*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
721*9880d681SAndroid Build Coastguard Worker  ;  function there.
722*9880d681SAndroid Build Coastguard Worker
723*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0, uxth
724*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, ls
725*9880d681SAndroid Build Coastguard Worker
726*9880d681SAndroid Build Coastguard Worker
727*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
728*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
729*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
730*9880d681SAndroid Build Coastguard Worker
731*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
732*9880d681SAndroid Build Coastguard Worker   ret i16 %old
733*9880d681SAndroid Build Coastguard Worker}
734*9880d681SAndroid Build Coastguard Worker
735*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {
736*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i32:
737*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i32* @var32, i32 %offset seq_cst
738*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
739*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
740*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
741*9880d681SAndroid Build Coastguard Worker
742*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
743*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
744*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
745*9880d681SAndroid Build Coastguard Worker  ;  function there.
746*9880d681SAndroid Build Coastguard Worker
747*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0
748*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, ls
749*9880d681SAndroid Build Coastguard Worker
750*9880d681SAndroid Build Coastguard Worker
751*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
752*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
753*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
754*9880d681SAndroid Build Coastguard Worker
755*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
756*9880d681SAndroid Build Coastguard Worker   ret i32 %old
757*9880d681SAndroid Build Coastguard Worker}
758*9880d681SAndroid Build Coastguard Worker
759*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_umin_i64(i64 %offset) nounwind {
760*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i64:
761*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i64* @var64, i64 %offset acq_rel
762*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
763*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
764*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
765*9880d681SAndroid Build Coastguard Worker
766*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
767*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]]
768*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
769*9880d681SAndroid Build Coastguard Worker  ; function there.
770*9880d681SAndroid Build Coastguard Worker
771*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x[[OLD]], x0
772*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, ls
773*9880d681SAndroid Build Coastguard Worker
774*9880d681SAndroid Build Coastguard Worker
775*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
776*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
777*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
780*9880d681SAndroid Build Coastguard Worker   ret i64 %old
781*9880d681SAndroid Build Coastguard Worker}
782*9880d681SAndroid Build Coastguard Worker
783*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_umax_i8(i8 %offset) nounwind {
784*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i8:
785*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i8* @var8, i8 %offset acq_rel
786*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
787*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
788*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
789*9880d681SAndroid Build Coastguard Worker
790*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
791*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
792*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
793*9880d681SAndroid Build Coastguard Worker  ;  function there.
794*9880d681SAndroid Build Coastguard Worker
795*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0, uxtb
796*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
797*9880d681SAndroid Build Coastguard Worker
798*9880d681SAndroid Build Coastguard Worker
799*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
800*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
801*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
802*9880d681SAndroid Build Coastguard Worker
803*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
804*9880d681SAndroid Build Coastguard Worker   ret i8 %old
805*9880d681SAndroid Build Coastguard Worker}
806*9880d681SAndroid Build Coastguard Worker
807*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_umax_i16(i16 %offset) nounwind {
808*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i16:
809*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i16* @var16, i16 %offset monotonic
810*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
811*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
812*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
813*9880d681SAndroid Build Coastguard Worker
814*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
815*9880d681SAndroid Build Coastguard Worker; CHECK: ldxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
816*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
817*9880d681SAndroid Build Coastguard Worker  ;  function there.
818*9880d681SAndroid Build Coastguard Worker
819*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0, uxth
820*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
821*9880d681SAndroid Build Coastguard Worker
822*9880d681SAndroid Build Coastguard Worker
823*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
824*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
825*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
826*9880d681SAndroid Build Coastguard Worker
827*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
828*9880d681SAndroid Build Coastguard Worker   ret i16 %old
829*9880d681SAndroid Build Coastguard Worker}
830*9880d681SAndroid Build Coastguard Worker
831*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {
832*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i32:
833*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i32* @var32, i32 %offset seq_cst
834*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
835*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
836*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
837*9880d681SAndroid Build Coastguard Worker
838*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
839*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxr w[[OLD:[0-9]+]], [x[[ADDR]]]
840*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
841*9880d681SAndroid Build Coastguard Worker  ;  function there.
842*9880d681SAndroid Build Coastguard Worker
843*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0
844*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi
845*9880d681SAndroid Build Coastguard Worker
846*9880d681SAndroid Build Coastguard Worker
847*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
848*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
849*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
850*9880d681SAndroid Build Coastguard Worker
851*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
852*9880d681SAndroid Build Coastguard Worker   ret i32 %old
853*9880d681SAndroid Build Coastguard Worker}
854*9880d681SAndroid Build Coastguard Worker
855*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_umax_i64(i64 %offset) nounwind {
856*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i64:
857*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i64* @var64, i64 %offset release
858*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
859*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
860*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
861*9880d681SAndroid Build Coastguard Worker
862*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
863*9880d681SAndroid Build Coastguard Worker; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
864*9880d681SAndroid Build Coastguard Worker  ; x0 below is a reasonable guess but could change: it certainly comes into the
865*9880d681SAndroid Build Coastguard Worker  ; function there.
866*9880d681SAndroid Build Coastguard Worker
867*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x[[OLD]], x0
868*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, hi
869*9880d681SAndroid Build Coastguard Worker
870*9880d681SAndroid Build Coastguard Worker
871*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]]
872*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1
873*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
874*9880d681SAndroid Build Coastguard Worker
875*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x[[OLD]]
876*9880d681SAndroid Build Coastguard Worker   ret i64 %old
877*9880d681SAndroid Build Coastguard Worker}
878*9880d681SAndroid Build Coastguard Worker
879*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind {
880*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i8:
881*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i8* @var8, i8 %wanted, i8 %new acquire acquire
882*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i8, i1 } %pair, 0
883*9880d681SAndroid Build Coastguard Worker
884*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
885*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
886*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
887*9880d681SAndroid Build Coastguard Worker
888*9880d681SAndroid Build Coastguard Worker; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
889*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrb w[[OLD:[0-9]+]], [x[[ADDR]]]
890*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
891*9880d681SAndroid Build Coastguard Worker  ;  function there.
892*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0
893*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
894*9880d681SAndroid Build Coastguard Worker; CHECK: stxrb [[STATUS:w[0-9]+]], {{w[0-9]+}}, [x[[ADDR]]]
895*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
896*9880d681SAndroid Build Coastguard Worker; CHECK: [[GET_OUT]]:
897*9880d681SAndroid Build Coastguard Worker; CHECK: clrex
898*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
899*9880d681SAndroid Build Coastguard Worker
900*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
901*9880d681SAndroid Build Coastguard Worker   ret i8 %old
902*9880d681SAndroid Build Coastguard Worker}
903*9880d681SAndroid Build Coastguard Worker
904*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_cmpxchg_i16(i16 %wanted, i16 %new) nounwind {
905*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i16:
906*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i16* @var16, i16 %wanted, i16 %new seq_cst seq_cst
907*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i16, i1 } %pair, 0
908*9880d681SAndroid Build Coastguard Worker
909*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
910*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var16
911*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var16
912*9880d681SAndroid Build Coastguard Worker
913*9880d681SAndroid Build Coastguard Worker; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
914*9880d681SAndroid Build Coastguard Worker; CHECK: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]]
915*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
916*9880d681SAndroid Build Coastguard Worker  ;  function there.
917*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w0
918*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
919*9880d681SAndroid Build Coastguard Worker; CHECK: stlxrh [[STATUS:w[0-9]+]], {{w[0-9]+}}, [x[[ADDR]]]
920*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
921*9880d681SAndroid Build Coastguard Worker; CHECK: [[GET_OUT]]:
922*9880d681SAndroid Build Coastguard Worker; CHECK: clrex
923*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
924*9880d681SAndroid Build Coastguard Worker
925*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}0, {{[xw]}}[[OLD]]
926*9880d681SAndroid Build Coastguard Worker   ret i16 %old
927*9880d681SAndroid Build Coastguard Worker}
928*9880d681SAndroid Build Coastguard Worker
929*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {
930*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i32:
931*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i32* @var32, i32 %wanted, i32 %new release monotonic
932*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i32, i1 } %pair, 0
933*9880d681SAndroid Build Coastguard Worker
934*9880d681SAndroid Build Coastguard Worker; CHECK: mov {{[xw]}}[[WANTED:[0-9]+]], {{[xw]}}0
935*9880d681SAndroid Build Coastguard Worker
936*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
937*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var32
938*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var32
939*9880d681SAndroid Build Coastguard Worker
940*9880d681SAndroid Build Coastguard Worker; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
941*9880d681SAndroid Build Coastguard Worker; CHECK: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]]
942*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w[[OLD]], w[[WANTED]]
943*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
944*9880d681SAndroid Build Coastguard Worker; CHECK: stlxr [[STATUS:w[0-9]+]], {{w[0-9]+}}, [x[[ADDR]]]
945*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
946*9880d681SAndroid Build Coastguard Worker; CHECK: [[GET_OUT]]:
947*9880d681SAndroid Build Coastguard Worker; CHECK: clrex
948*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
949*9880d681SAndroid Build Coastguard Worker   ret i32 %old
950*9880d681SAndroid Build Coastguard Worker}
951*9880d681SAndroid Build Coastguard Worker
952*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
953*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i64:
954*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i64* @var64, i64 %wanted, i64 %new monotonic monotonic
955*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i64, i1 } %pair, 0
956*9880d681SAndroid Build Coastguard Worker
957*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
958*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var64
959*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var64
960*9880d681SAndroid Build Coastguard Worker
961*9880d681SAndroid Build Coastguard Worker; CHECK: [[STARTAGAIN:.LBB[0-9]+_[0-9]+]]:
962*9880d681SAndroid Build Coastguard Worker; CHECK: ldxr x[[OLD:[0-9]+]], [x[[ADDR]]]
963*9880d681SAndroid Build Coastguard Worker  ; w0 below is a reasonable guess but could change: it certainly comes into the
964*9880d681SAndroid Build Coastguard Worker  ;  function there.
965*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp x[[OLD]], x0
966*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]]
967*9880d681SAndroid Build Coastguard Worker  ; As above, w1 is a reasonable guess.
968*9880d681SAndroid Build Coastguard Worker; CHECK: stxr [[STATUS:w[0-9]+]], x1, [x[[ADDR]]]
969*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]]
970*9880d681SAndroid Build Coastguard Worker; CHECK: [[GET_OUT]]:
971*9880d681SAndroid Build Coastguard Worker; CHECK: clrex
972*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
973*9880d681SAndroid Build Coastguard Worker
974*9880d681SAndroid Build Coastguard Worker; CHECK: str x[[OLD]],
975*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
976*9880d681SAndroid Build Coastguard Worker   ret void
977*9880d681SAndroid Build Coastguard Worker}
978*9880d681SAndroid Build Coastguard Worker
979*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_monotonic_i8() nounwind {
980*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_i8:
981*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* @var8 monotonic, align 1
982*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
983*9880d681SAndroid Build Coastguard Worker; CHECK: adrp x[[HIADDR:[0-9]+]], var8
984*9880d681SAndroid Build Coastguard Worker; CHECK: ldrb w0, [x[[HIADDR]], {{#?}}:lo12:var8]
985*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
986*9880d681SAndroid Build Coastguard Worker
987*9880d681SAndroid Build Coastguard Worker  ret i8 %val
988*9880d681SAndroid Build Coastguard Worker}
989*9880d681SAndroid Build Coastguard Worker
990*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
991*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_regoff_i8:
992*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
993*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i8*
994*9880d681SAndroid Build Coastguard Worker
995*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* %addr monotonic, align 1
996*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
997*9880d681SAndroid Build Coastguard Worker; CHECK: ldrb w0, [x0, x1]
998*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
999*9880d681SAndroid Build Coastguard Worker
1000*9880d681SAndroid Build Coastguard Worker  ret i8 %val
1001*9880d681SAndroid Build Coastguard Worker}
1002*9880d681SAndroid Build Coastguard Worker
1003*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_acquire_i8() nounwind {
1004*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_acquire_i8:
1005*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* @var8 acquire, align 1
1006*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1007*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[TMPADDR:x[0-9]+]], var8
1008*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1009*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[TMPADDR]], {{#?}}:lo12:var8
1010*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1011*9880d681SAndroid Build Coastguard Worker; CHECK: ldarb w0, [x[[ADDR]]]
1012*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1013*9880d681SAndroid Build Coastguard Worker  ret i8 %val
1014*9880d681SAndroid Build Coastguard Worker}
1015*9880d681SAndroid Build Coastguard Worker
1016*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_seq_cst_i8() nounwind {
1017*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_seq_cst_i8:
1018*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* @var8 seq_cst, align 1
1019*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1020*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1021*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1022*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var8
1023*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1024*9880d681SAndroid Build Coastguard Worker; CHECK: ldarb w0, [x[[ADDR]]]
1025*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1026*9880d681SAndroid Build Coastguard Worker  ret i8 %val
1027*9880d681SAndroid Build Coastguard Worker}
1028*9880d681SAndroid Build Coastguard Worker
1029*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_monotonic_i16() nounwind {
1030*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_i16:
1031*9880d681SAndroid Build Coastguard Worker  %val = load atomic i16, i16* @var16 monotonic, align 2
1032*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1033*9880d681SAndroid Build Coastguard Worker; CHECK: adrp x[[HIADDR:[0-9]+]], var16
1034*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1035*9880d681SAndroid Build Coastguard Worker; CHECK: ldrh w0, [x[[HIADDR]], {{#?}}:lo12:var16]
1036*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1037*9880d681SAndroid Build Coastguard Worker
1038*9880d681SAndroid Build Coastguard Worker  ret i16 %val
1039*9880d681SAndroid Build Coastguard Worker}
1040*9880d681SAndroid Build Coastguard Worker
1041*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {
1042*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_regoff_i32:
1043*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
1044*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i32*
1045*9880d681SAndroid Build Coastguard Worker
1046*9880d681SAndroid Build Coastguard Worker  %val = load atomic i32, i32* %addr monotonic, align 4
1047*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1048*9880d681SAndroid Build Coastguard Worker; CHECK: ldr w0, [x0, x1]
1049*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1050*9880d681SAndroid Build Coastguard Worker
1051*9880d681SAndroid Build Coastguard Worker  ret i32 %val
1052*9880d681SAndroid Build Coastguard Worker}
1053*9880d681SAndroid Build Coastguard Worker
1054*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_seq_cst_i64() nounwind {
1055*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_seq_cst_i64:
1056*9880d681SAndroid Build Coastguard Worker  %val = load atomic i64, i64* @var64 seq_cst, align 8
1057*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1058*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[HIADDR:x[0-9]+]], var64
1059*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1060*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var64
1061*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1062*9880d681SAndroid Build Coastguard Worker; CHECK: ldar x0, [x[[ADDR]]]
1063*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1064*9880d681SAndroid Build Coastguard Worker  ret i64 %val
1065*9880d681SAndroid Build Coastguard Worker}
1066*9880d681SAndroid Build Coastguard Worker
1067*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_i8(i8 %val) nounwind {
1068*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_i8:
1069*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* @var8 monotonic, align 1
1070*9880d681SAndroid Build Coastguard Worker; CHECK: adrp x[[HIADDR:[0-9]+]], var8
1071*9880d681SAndroid Build Coastguard Worker; CHECK: strb w0, [x[[HIADDR]], {{#?}}:lo12:var8]
1072*9880d681SAndroid Build Coastguard Worker
1073*9880d681SAndroid Build Coastguard Worker  ret void
1074*9880d681SAndroid Build Coastguard Worker}
1075*9880d681SAndroid Build Coastguard Worker
1076*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {
1077*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_regoff_i8:
1078*9880d681SAndroid Build Coastguard Worker
1079*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
1080*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i8*
1081*9880d681SAndroid Build Coastguard Worker
1082*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* %addr monotonic, align 1
1083*9880d681SAndroid Build Coastguard Worker; CHECK: strb w2, [x0, x1]
1084*9880d681SAndroid Build Coastguard Worker
1085*9880d681SAndroid Build Coastguard Worker  ret void
1086*9880d681SAndroid Build Coastguard Worker}
1087*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_release_i8(i8 %val) nounwind {
1088*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_release_i8:
1089*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* @var8 release, align 1
1090*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1091*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1092*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1093*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var8
1094*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1095*9880d681SAndroid Build Coastguard Worker; CHECK: stlrb w0, [x[[ADDR]]]
1096*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1097*9880d681SAndroid Build Coastguard Worker  ret void
1098*9880d681SAndroid Build Coastguard Worker}
1099*9880d681SAndroid Build Coastguard Worker
1100*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {
1101*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_seq_cst_i8:
1102*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* @var8 seq_cst, align 1
1103*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1104*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[HIADDR:x[0-9]+]], var8
1105*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1106*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var8
1107*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1108*9880d681SAndroid Build Coastguard Worker; CHECK: stlrb w0, [x[[ADDR]]]
1109*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1110*9880d681SAndroid Build Coastguard Worker
1111*9880d681SAndroid Build Coastguard Worker  ret void
1112*9880d681SAndroid Build Coastguard Worker}
1113*9880d681SAndroid Build Coastguard Worker
1114*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_i16(i16 %val) nounwind {
1115*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_i16:
1116*9880d681SAndroid Build Coastguard Worker  store atomic i16 %val, i16* @var16 monotonic, align 2
1117*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1118*9880d681SAndroid Build Coastguard Worker; CHECK: adrp x[[HIADDR:[0-9]+]], var16
1119*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1120*9880d681SAndroid Build Coastguard Worker; CHECK: strh w0, [x[[HIADDR]], {{#?}}:lo12:var16]
1121*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1122*9880d681SAndroid Build Coastguard Worker  ret void
1123*9880d681SAndroid Build Coastguard Worker}
1124*9880d681SAndroid Build Coastguard Worker
1125*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {
1126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_regoff_i32:
1127*9880d681SAndroid Build Coastguard Worker
1128*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
1129*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i32*
1130*9880d681SAndroid Build Coastguard Worker
1131*9880d681SAndroid Build Coastguard Worker  store atomic i32 %val, i32* %addr monotonic, align 4
1132*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1133*9880d681SAndroid Build Coastguard Worker; CHECK: str w2, [x0, x1]
1134*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1135*9880d681SAndroid Build Coastguard Worker
1136*9880d681SAndroid Build Coastguard Worker  ret void
1137*9880d681SAndroid Build Coastguard Worker}
1138*9880d681SAndroid Build Coastguard Worker
1139*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_release_i64(i64 %val) nounwind {
1140*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_release_i64:
1141*9880d681SAndroid Build Coastguard Worker  store atomic i64 %val, i64* @var64 release, align 8
1142*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1143*9880d681SAndroid Build Coastguard Worker; CHECK: adrp [[HIADDR:x[0-9]+]], var64
1144*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1145*9880d681SAndroid Build Coastguard Worker; CHECK: add x[[ADDR:[0-9]+]], [[HIADDR]], {{#?}}:lo12:var64
1146*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1147*9880d681SAndroid Build Coastguard Worker; CHECK: stlr x0, [x[[ADDR]]]
1148*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1149*9880d681SAndroid Build Coastguard Worker  ret void
1150*9880d681SAndroid Build Coastguard Worker}
1151