xref: /aosp_15_r20/external/llvm/test/CodeGen/ARM/atomic-ops-v8.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=armv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-LE
2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=armebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-ARM --check-prefix=CHECK-ARM-BE
3*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumbv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE
4*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumbebv8-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker@var8 = global i8 0
7*9880d681SAndroid Build Coastguard Worker@var16 = global i16 0
8*9880d681SAndroid Build Coastguard Worker@var32 = global i32 0
9*9880d681SAndroid Build Coastguard Worker@var64 = global i64 0
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_add_i8(i8 %offset) nounwind {
12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i8:
13*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i8* @var8, i8 %offset seq_cst
14*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
15*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
16*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
17*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
20*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
21*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
22*9880d681SAndroid Build Coastguard Worker  ;  function there.
23*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
24*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
25*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
26*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
27*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
28*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
31*9880d681SAndroid Build Coastguard Worker   ret i8 %old
32*9880d681SAndroid Build Coastguard Worker}
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_add_i16(i16 %offset) nounwind {
35*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i16:
36*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i16* @var16, i16 %offset acquire
37*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
38*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
39*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
40*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
43*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
44*9880d681SAndroid Build Coastguard Worker  ; r0 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{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
47*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
48*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
49*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
50*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
51*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
54*9880d681SAndroid Build Coastguard Worker   ret i16 %old
55*9880d681SAndroid Build Coastguard Worker}
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_add_i32(i32 %offset) nounwind {
58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i32:
59*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i32* @var32, i32 %offset release
60*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
61*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
62*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
63*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
66*9880d681SAndroid Build Coastguard Worker; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
67*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
68*9880d681SAndroid Build Coastguard Worker  ;  function there.
69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
73*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
74*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
77*9880d681SAndroid Build Coastguard Worker   ret i32 %old
78*9880d681SAndroid Build Coastguard Worker}
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_add_i64(i64 %offset) nounwind {
81*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_add_i64:
82*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw add i64* @var64, i64 %offset monotonic
83*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
84*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
85*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
86*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
89*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
90*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
91*9880d681SAndroid Build Coastguard Worker  ; function there.
92*9880d681SAndroid Build Coastguard Worker; CHECK-LE-NEXT: adds{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
93*9880d681SAndroid Build Coastguard Worker; CHECK-LE-NEXT: adc{{(\.w)?}}  [[NEW2:r[0-9]+]], r[[OLD2]], r1
94*9880d681SAndroid Build Coastguard Worker; CHECK-BE-NEXT: adds{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
95*9880d681SAndroid Build Coastguard Worker; CHECK-BE-NEXT: adc{{(\.w)?}}  [[NEW1:r[0-9]+]], r[[OLD1]], r0
96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
97*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
98*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
99*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
100*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
103*9880d681SAndroid Build Coastguard Worker  store i64 %old, i64* @var64
104*9880d681SAndroid Build Coastguard Worker   ret void
105*9880d681SAndroid Build Coastguard Worker}
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_sub_i8(i8 %offset) nounwind {
108*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i8:
109*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i8* @var8, i8 %offset monotonic
110*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
111*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
112*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
113*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
116*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]
117*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
118*9880d681SAndroid Build Coastguard Worker  ;  function there.
119*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
120*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
121*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
122*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
123*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
124*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
127*9880d681SAndroid Build Coastguard Worker   ret i8 %old
128*9880d681SAndroid Build Coastguard Worker}
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_sub_i16(i16 %offset) nounwind {
131*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i16:
132*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i16* @var16, i16 %offset release
133*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
134*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
135*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
136*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
139*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
140*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
141*9880d681SAndroid Build Coastguard Worker  ;  function there.
142*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
143*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
144*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
145*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
146*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
147*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
150*9880d681SAndroid Build Coastguard Worker   ret i16 %old
151*9880d681SAndroid Build Coastguard Worker}
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_sub_i32(i32 %offset) nounwind {
154*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i32:
155*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i32* @var32, i32 %offset acquire
156*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
157*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
158*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
159*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
162*9880d681SAndroid Build Coastguard Worker; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
163*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
164*9880d681SAndroid Build Coastguard Worker  ;  function there.
165*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub{{s?}} [[NEW:r[0-9]+]], r[[OLD]], r0
166*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
167*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
168*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
169*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
170*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
173*9880d681SAndroid Build Coastguard Worker   ret i32 %old
174*9880d681SAndroid Build Coastguard Worker}
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_sub_i64(i64 %offset) nounwind {
177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_sub_i64:
178*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw sub i64* @var64, i64 %offset seq_cst
179*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
180*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
181*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
182*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
185*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
186*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
187*9880d681SAndroid Build Coastguard Worker  ; function there.
188*9880d681SAndroid Build Coastguard Worker; CHECK-LE-NEXT: subs{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
189*9880d681SAndroid Build Coastguard Worker; CHECK-LE-NEXT: sbc{{(\.w)?}}  [[NEW2:r[0-9]+]], r[[OLD2]], r1
190*9880d681SAndroid Build Coastguard Worker; CHECK-BE-NEXT: subs{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
191*9880d681SAndroid Build Coastguard Worker; CHECK-BE-NEXT: sbc{{(\.w)?}}  [[NEW1:r[0-9]+]], r[[OLD1]], r0
192*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
193*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
194*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
195*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
196*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
199*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
200*9880d681SAndroid Build Coastguard Worker   ret void
201*9880d681SAndroid Build Coastguard Worker}
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_and_i8(i8 %offset) nounwind {
204*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i8:
205*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i8* @var8, i8 %offset release
206*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
207*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
208*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
209*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
212*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]
213*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
214*9880d681SAndroid Build Coastguard Worker  ;  function there.
215*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
216*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
217*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
218*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
219*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
220*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
223*9880d681SAndroid Build Coastguard Worker   ret i8 %old
224*9880d681SAndroid Build Coastguard Worker}
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_and_i16(i16 %offset) nounwind {
227*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i16:
228*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i16* @var16, i16 %offset monotonic
229*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
230*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
231*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
232*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
235*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
236*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
237*9880d681SAndroid Build Coastguard Worker  ;  function there.
238*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
239*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
240*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
242*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
243*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
246*9880d681SAndroid Build Coastguard Worker   ret i16 %old
247*9880d681SAndroid Build Coastguard Worker}
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_and_i32(i32 %offset) nounwind {
250*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i32:
251*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i32* @var32, i32 %offset seq_cst
252*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
253*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
254*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
255*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
258*9880d681SAndroid Build Coastguard Worker; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
259*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
260*9880d681SAndroid Build Coastguard Worker  ;  function there.
261*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: and{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
262*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
263*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
264*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
265*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
266*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
269*9880d681SAndroid Build Coastguard Worker   ret i32 %old
270*9880d681SAndroid Build Coastguard Worker}
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_and_i64(i64 %offset) nounwind {
273*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_and_i64:
274*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw and i64* @var64, i64 %offset acquire
275*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
276*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
277*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
278*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
281*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
282*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
283*9880d681SAndroid Build Coastguard Worker  ; function there.
284*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
285*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
286*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: and{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
287*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: and{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
288*9880d681SAndroid Build Coastguard Worker; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
289*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
290*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
291*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
292*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
295*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
296*9880d681SAndroid Build Coastguard Worker   ret void
297*9880d681SAndroid Build Coastguard Worker}
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_or_i8(i8 %offset) nounwind {
300*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i8:
301*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i8* @var8, i8 %offset seq_cst
302*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
303*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
304*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
305*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
308*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
309*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
310*9880d681SAndroid Build Coastguard Worker  ;  function there.
311*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
312*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
313*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
314*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
315*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
316*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
317*9880d681SAndroid Build Coastguard Worker
318*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
319*9880d681SAndroid Build Coastguard Worker   ret i8 %old
320*9880d681SAndroid Build Coastguard Worker}
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_or_i16(i16 %offset) nounwind {
323*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i16:
324*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i16* @var16, i16 %offset monotonic
325*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
326*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
327*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
328*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
329*9880d681SAndroid Build Coastguard Worker
330*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
331*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
332*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
333*9880d681SAndroid Build Coastguard Worker  ;  function there.
334*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
335*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
336*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
337*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
338*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
339*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
340*9880d681SAndroid Build Coastguard Worker
341*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
342*9880d681SAndroid Build Coastguard Worker   ret i16 %old
343*9880d681SAndroid Build Coastguard Worker}
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_or_i32(i32 %offset) nounwind {
346*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i32:
347*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i32* @var32, i32 %offset acquire
348*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
349*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
350*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
351*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
354*9880d681SAndroid Build Coastguard Worker; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
355*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
356*9880d681SAndroid Build Coastguard Worker  ;  function there.
357*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orr{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
358*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
359*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
360*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
361*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
362*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
365*9880d681SAndroid Build Coastguard Worker   ret i32 %old
366*9880d681SAndroid Build Coastguard Worker}
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_or_i64(i64 %offset) nounwind {
369*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_or_i64:
370*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw or i64* @var64, i64 %offset release
371*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
372*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
373*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
374*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
375*9880d681SAndroid Build Coastguard Worker
376*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
377*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
378*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
379*9880d681SAndroid Build Coastguard Worker  ; function there.
380*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
381*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
382*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
383*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: orr{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
384*9880d681SAndroid Build Coastguard Worker; CHECK: stlexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
385*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
386*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
387*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
388*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
391*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
392*9880d681SAndroid Build Coastguard Worker   ret void
393*9880d681SAndroid Build Coastguard Worker}
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_xor_i8(i8 %offset) nounwind {
396*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i8:
397*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i8* @var8, i8 %offset acquire
398*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
399*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
400*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
401*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
404*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
405*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
406*9880d681SAndroid Build Coastguard Worker  ;  function there.
407*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
408*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
409*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
410*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
411*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
412*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
415*9880d681SAndroid Build Coastguard Worker   ret i8 %old
416*9880d681SAndroid Build Coastguard Worker}
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_xor_i16(i16 %offset) nounwind {
419*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i16:
420*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i16* @var16, i16 %offset release
421*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
422*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
423*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
424*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
425*9880d681SAndroid Build Coastguard Worker
426*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
427*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexh r[[OLD:[0-9]+]], [r[[ADDR]]]
428*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
429*9880d681SAndroid Build Coastguard Worker  ;  function there.
430*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
431*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
432*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
433*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
434*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
435*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
438*9880d681SAndroid Build Coastguard Worker   ret i16 %old
439*9880d681SAndroid Build Coastguard Worker}
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_xor_i32(i32 %offset) nounwind {
442*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i32:
443*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i32* @var32, i32 %offset seq_cst
444*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
445*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
446*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
447*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
450*9880d681SAndroid Build Coastguard Worker; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
451*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
452*9880d681SAndroid Build Coastguard Worker  ;  function there.
453*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: eor{{(\.w)?}} [[NEW:r[0-9]+]], r[[OLD]], r0
454*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], [[NEW]], [r[[ADDR]]]
455*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
456*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
457*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
458*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
459*9880d681SAndroid Build Coastguard Worker
460*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
461*9880d681SAndroid Build Coastguard Worker   ret i32 %old
462*9880d681SAndroid Build Coastguard Worker}
463*9880d681SAndroid Build Coastguard Worker
464*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_xor_i64(i64 %offset) nounwind {
465*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xor_i64:
466*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xor i64* @var64, i64 %offset monotonic
467*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
468*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
469*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
470*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
473*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexd r[[OLD1:[0-9]+]], r[[OLD2:[0-9]+]], [r[[ADDR]]]
474*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
475*9880d681SAndroid Build Coastguard Worker  ; function there.
476*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
477*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
478*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW2:r[0-9]+|lr]], r[[OLD2]], r1
479*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: eor{{(\.w)?}} [[NEW1:r[0-9]+|lr]], r[[OLD1]], r0
480*9880d681SAndroid Build Coastguard Worker; CHECK: strexd [[STATUS:r[0-9]+]], [[NEW1]], [[NEW2]], [r[[ADDR]]]
481*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
482*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
483*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
484*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker; CHECK: strd r[[OLD1]], r[[OLD2]], [r[[ADDR]]]
487*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
488*9880d681SAndroid Build Coastguard Worker   ret void
489*9880d681SAndroid Build Coastguard Worker}
490*9880d681SAndroid Build Coastguard Worker
491*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind {
492*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i8:
493*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i8* @var8, i8 %offset monotonic
494*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
495*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
496*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
497*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
498*9880d681SAndroid Build Coastguard Worker
499*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
500*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexb r[[OLD:[0-9]+]], [r[[ADDR]]]
501*9880d681SAndroid Build Coastguard Worker  ; r0 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; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]
504*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
505*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
506*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
507*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
508*9880d681SAndroid Build Coastguard Worker
509*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
510*9880d681SAndroid Build Coastguard Worker   ret i8 %old
511*9880d681SAndroid Build Coastguard Worker}
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind {
514*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i16:
515*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i16* @var16, i16 %offset seq_cst
516*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
517*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
518*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
519*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
522*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
523*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
524*9880d681SAndroid Build Coastguard Worker  ;  function there.
525*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]
526*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
527*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
528*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
529*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
530*9880d681SAndroid Build Coastguard Worker
531*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
532*9880d681SAndroid Build Coastguard Worker   ret i16 %old
533*9880d681SAndroid Build Coastguard Worker}
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind {
536*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i32:
537*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i32* @var32, i32 %offset release
538*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
539*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
540*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
541*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
542*9880d681SAndroid Build Coastguard Worker
543*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
544*9880d681SAndroid Build Coastguard Worker; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
545*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
546*9880d681SAndroid Build Coastguard Worker  ;  function there.
547*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r0, [r[[ADDR]]]
548*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
549*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
550*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
551*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
552*9880d681SAndroid Build Coastguard Worker
553*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
554*9880d681SAndroid Build Coastguard Worker   ret i32 %old
555*9880d681SAndroid Build Coastguard Worker}
556*9880d681SAndroid Build Coastguard Worker
557*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_xchg_i64(i64 %offset) nounwind {
558*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_xchg_i64:
559*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw xchg i64* @var64, i64 %offset acquire
560*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
561*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
562*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
563*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
564*9880d681SAndroid Build Coastguard Worker
565*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
566*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
567*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
568*9880d681SAndroid Build Coastguard Worker  ; function there.
569*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexd [[STATUS:r[0-9]+]], r0, r1, [r[[ADDR]]]
570*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
571*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
572*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
573*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
574*9880d681SAndroid Build Coastguard Worker
575*9880d681SAndroid Build Coastguard Worker; CHECK: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
576*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
577*9880d681SAndroid Build Coastguard Worker   ret void
578*9880d681SAndroid Build Coastguard Worker}
579*9880d681SAndroid Build Coastguard Worker
580*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_min_i8(i8 signext %offset) nounwind {
581*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i8:
582*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i8* @var8, i8 %offset acquire
583*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
584*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
585*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
586*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movt [[ADDR]], :upper16:var8
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
589*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
590*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxtb r[[OLDX:[0-9]+]], r[[OLD]]
591*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
592*9880d681SAndroid Build Coastguard Worker  ;  function there.
593*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLDX]], r0
594*9880d681SAndroid Build Coastguard Worker; Thumb mode: it le
595*9880d681SAndroid Build Coastguard Worker; CHECK:      movle r[[OLDX]], r[[OLD]]
596*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]]
597*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
598*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
599*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
600*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
601*9880d681SAndroid Build Coastguard Worker
602*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
603*9880d681SAndroid Build Coastguard Worker   ret i8 %old
604*9880d681SAndroid Build Coastguard Worker}
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_min_i16(i16 signext %offset) nounwind {
607*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i16:
608*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i16* @var16, i16 %offset release
609*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
610*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
611*9880d681SAndroid Build Coastguard Worker; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16
612*9880d681SAndroid Build Coastguard Worker; CHECK: movt [[ADDR]], :upper16:var16
613*9880d681SAndroid Build Coastguard Worker
614*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
615*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
616*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxth r[[OLDX:[0-9]+]], r[[OLD]]
617*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
618*9880d681SAndroid Build Coastguard Worker  ;  function there.
619*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLDX]], r0
620*9880d681SAndroid Build Coastguard Worker; Thumb mode: it le
621*9880d681SAndroid Build Coastguard Worker; CHECK:      movle r[[OLDX]], r[[OLD]]
622*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexh [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]
623*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
624*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
625*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
626*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
627*9880d681SAndroid Build Coastguard Worker
628*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
629*9880d681SAndroid Build Coastguard Worker   ret i16 %old
630*9880d681SAndroid Build Coastguard Worker}
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_min_i32(i32 %offset) nounwind {
633*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i32:
634*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i32* @var32, i32 %offset monotonic
635*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
636*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
637*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
638*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
639*9880d681SAndroid Build Coastguard Worker
640*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
641*9880d681SAndroid Build Coastguard Worker; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
642*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
643*9880d681SAndroid Build Coastguard Worker  ;  function there.
644*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
645*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
646*9880d681SAndroid Build Coastguard Worker; Thumb mode: it le
647*9880d681SAndroid Build Coastguard Worker; CHECK:      movle r[[NEW]], r[[OLD]]
648*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
649*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
650*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
651*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
652*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
653*9880d681SAndroid Build Coastguard Worker
654*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
655*9880d681SAndroid Build Coastguard Worker   ret i32 %old
656*9880d681SAndroid Build Coastguard Worker}
657*9880d681SAndroid Build Coastguard Worker
658*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_min_i64(i64 %offset) nounwind {
659*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_min_i64:
660*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw min i64* @var64, i64 %offset seq_cst
661*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
662*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
663*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
664*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
665*9880d681SAndroid Build Coastguard Worker
666*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
667*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
668*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
669*9880d681SAndroid Build Coastguard Worker  ; function there.
670*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
671*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
672*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
673*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
674*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
675*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
676*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movwge [[CMP:r[0-9]+|lr]], #1
677*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
678*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINHI]], [[OLD2]]
679*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
680*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINLO]], [[OLD1]]
681*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
682*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
683*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
684*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
685*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
686*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
689*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
690*9880d681SAndroid Build Coastguard Worker   ret void
691*9880d681SAndroid Build Coastguard Worker}
692*9880d681SAndroid Build Coastguard Worker
693*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_max_i8(i8 signext %offset) nounwind {
694*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i8:
695*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i8* @var8, i8 %offset seq_cst
696*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
697*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
698*9880d681SAndroid Build Coastguard Worker; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
699*9880d681SAndroid Build Coastguard Worker; CHECK: movt [[ADDR]], :upper16:var8
700*9880d681SAndroid Build Coastguard Worker
701*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
702*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
703*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxtb r[[OLDX:[0-9]+]], r[[OLD]]
704*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
705*9880d681SAndroid Build Coastguard Worker  ;  function there.
706*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLDX]], r0
707*9880d681SAndroid Build Coastguard Worker; Thumb mode: it gt
708*9880d681SAndroid Build Coastguard Worker; CHECK:      movgt r[[OLDX]], r[[OLD]]
709*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], r[[OLDX]], {{.*}}[[ADDR]]
710*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
711*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
712*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
713*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
714*9880d681SAndroid Build Coastguard Worker
715*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
716*9880d681SAndroid Build Coastguard Worker   ret i8 %old
717*9880d681SAndroid Build Coastguard Worker}
718*9880d681SAndroid Build Coastguard Worker
719*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_max_i16(i16 signext %offset) nounwind {
720*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i16:
721*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i16* @var16, i16 %offset acquire
722*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
723*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
724*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
725*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
726*9880d681SAndroid Build Coastguard Worker
727*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
728*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
729*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sxth r[[OLDX:[0-9]+]], r[[OLD]]
730*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
731*9880d681SAndroid Build Coastguard Worker  ;  function there.
732*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLDX]], r0
733*9880d681SAndroid Build Coastguard Worker; Thumb mode: it gt
734*9880d681SAndroid Build Coastguard Worker; CHECK:      movgt r[[OLDX]], r[[OLD]]
735*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[OLDX]], [r[[ADDR]]]
736*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
737*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
738*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
739*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
740*9880d681SAndroid Build Coastguard Worker
741*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
742*9880d681SAndroid Build Coastguard Worker   ret i16 %old
743*9880d681SAndroid Build Coastguard Worker}
744*9880d681SAndroid Build Coastguard Worker
745*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_max_i32(i32 %offset) nounwind {
746*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i32:
747*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i32* @var32, i32 %offset release
748*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
749*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
750*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
751*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
752*9880d681SAndroid Build Coastguard Worker
753*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
754*9880d681SAndroid Build Coastguard Worker; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
755*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
756*9880d681SAndroid Build Coastguard Worker  ;  function there.
757*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
758*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
759*9880d681SAndroid Build Coastguard Worker; Thumb mode: it gt
760*9880d681SAndroid Build Coastguard Worker; CHECK:      movgt r[[NEW]], r[[OLD]]
761*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
762*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
763*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
764*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
765*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
766*9880d681SAndroid Build Coastguard Worker
767*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
768*9880d681SAndroid Build Coastguard Worker   ret i32 %old
769*9880d681SAndroid Build Coastguard Worker}
770*9880d681SAndroid Build Coastguard Worker
771*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_max_i64(i64 %offset) nounwind {
772*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_max_i64:
773*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw max i64* @var64, i64 %offset monotonic
774*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
775*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
776*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
777*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
780*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
781*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
782*9880d681SAndroid Build Coastguard Worker  ; function there.
783*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
784*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
785*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
786*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
787*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
788*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
789*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movwlt [[CMP:r[0-9]+|lr]], #1
790*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
791*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINHI]], [[OLD2]]
792*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
793*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINLO]], [[OLD1]]
794*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: strexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
795*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB: strexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
796*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
797*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
798*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
799*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
800*9880d681SAndroid Build Coastguard Worker
801*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
802*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
803*9880d681SAndroid Build Coastguard Worker   ret void
804*9880d681SAndroid Build Coastguard Worker}
805*9880d681SAndroid Build Coastguard Worker
806*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_umin_i8(i8 zeroext %offset) nounwind {
807*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i8:
808*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i8* @var8, i8 %offset monotonic
809*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
810*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
811*9880d681SAndroid Build Coastguard Worker; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
812*9880d681SAndroid Build Coastguard Worker; CHECK: movt [[ADDR]], :upper16:var8
813*9880d681SAndroid Build Coastguard Worker
814*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
815*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
816*9880d681SAndroid Build Coastguard Worker  ; r0 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; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
819*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
820*9880d681SAndroid Build Coastguard Worker; Thumb mode: it ls
821*9880d681SAndroid Build Coastguard Worker; CHECK:      movls r[[NEW]], r[[OLD]]
822*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
823*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
824*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
825*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
826*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
827*9880d681SAndroid Build Coastguard Worker
828*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
829*9880d681SAndroid Build Coastguard Worker   ret i8 %old
830*9880d681SAndroid Build Coastguard Worker}
831*9880d681SAndroid Build Coastguard Worker
832*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_umin_i16(i16 zeroext %offset) nounwind {
833*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i16:
834*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i16* @var16, i16 %offset acquire
835*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
836*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
837*9880d681SAndroid Build Coastguard Worker; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16
838*9880d681SAndroid Build Coastguard Worker; CHECK: movt [[ADDR]], :upper16:var16
839*9880d681SAndroid Build Coastguard Worker
840*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
841*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
842*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
843*9880d681SAndroid Build Coastguard Worker  ;  function there.
844*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
845*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
846*9880d681SAndroid Build Coastguard Worker; Thumb mode: it ls
847*9880d681SAndroid Build Coastguard Worker; CHECK:      movls r[[NEW]], r[[OLD]]
848*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
849*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
850*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
851*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
852*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
853*9880d681SAndroid Build Coastguard Worker
854*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
855*9880d681SAndroid Build Coastguard Worker   ret i16 %old
856*9880d681SAndroid Build Coastguard Worker}
857*9880d681SAndroid Build Coastguard Worker
858*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_umin_i32(i32 %offset) nounwind {
859*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i32:
860*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i32* @var32, i32 %offset seq_cst
861*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
862*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
863*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
864*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
865*9880d681SAndroid Build Coastguard Worker
866*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
867*9880d681SAndroid Build Coastguard Worker; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
868*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
869*9880d681SAndroid Build Coastguard Worker  ;  function there.
870*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
871*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
872*9880d681SAndroid Build Coastguard Worker; Thumb mode: it ls
873*9880d681SAndroid Build Coastguard Worker; CHECK:      movls r[[NEW]], r[[OLD]]
874*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
875*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
876*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
877*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
878*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
879*9880d681SAndroid Build Coastguard Worker
880*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
881*9880d681SAndroid Build Coastguard Worker   ret i32 %old
882*9880d681SAndroid Build Coastguard Worker}
883*9880d681SAndroid Build Coastguard Worker
884*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_umin_i64(i64 %offset) nounwind {
885*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umin_i64:
886*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umin i64* @var64, i64 %offset seq_cst
887*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
888*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
889*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
890*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
891*9880d681SAndroid Build Coastguard Worker
892*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
893*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
894*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
895*9880d681SAndroid Build Coastguard Worker  ; function there.
896*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
897*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
898*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
899*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
900*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
901*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
902*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movwhs [[CMP:r[0-9]+|lr]], #1
903*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
904*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINHI]], [[OLD2]]
905*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
906*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINLO]], [[OLD1]]
907*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
908*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
909*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
910*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
911*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
912*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
913*9880d681SAndroid Build Coastguard Worker
914*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
915*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
916*9880d681SAndroid Build Coastguard Worker   ret void
917*9880d681SAndroid Build Coastguard Worker}
918*9880d681SAndroid Build Coastguard Worker
919*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_umax_i8(i8 zeroext %offset) nounwind {
920*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i8:
921*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i8* @var8, i8 %offset acq_rel
922*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
923*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
924*9880d681SAndroid Build Coastguard Worker; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var8
925*9880d681SAndroid Build Coastguard Worker; CHECK: movt [[ADDR]], :upper16:var8
926*9880d681SAndroid Build Coastguard Worker
927*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
928*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexb r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
929*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
930*9880d681SAndroid Build Coastguard Worker  ;  function there.
931*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
932*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
933*9880d681SAndroid Build Coastguard Worker; Thumb mode: it hi
934*9880d681SAndroid Build Coastguard Worker; CHECK:      movhi r[[NEW]], r[[OLD]]
935*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlexb [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
936*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
937*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
938*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
939*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
940*9880d681SAndroid Build Coastguard Worker
941*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
942*9880d681SAndroid Build Coastguard Worker   ret i8 %old
943*9880d681SAndroid Build Coastguard Worker}
944*9880d681SAndroid Build Coastguard Worker
945*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_umax_i16(i16 zeroext %offset) nounwind {
946*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i16:
947*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i16* @var16, i16 %offset monotonic
948*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
949*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
950*9880d681SAndroid Build Coastguard Worker; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var16
951*9880d681SAndroid Build Coastguard Worker; CHECK: movt [[ADDR]], :upper16:var16
952*9880d681SAndroid Build Coastguard Worker
953*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
954*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexh r[[OLD:[0-9]+]], {{.*}}[[ADDR]]
955*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
956*9880d681SAndroid Build Coastguard Worker  ;  function there.
957*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
958*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
959*9880d681SAndroid Build Coastguard Worker; Thumb mode: it hi
960*9880d681SAndroid Build Coastguard Worker; CHECK:      movhi r[[NEW]], r[[OLD]]
961*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: strexh [[STATUS:r[0-9]+]], r[[NEW]], {{.*}}[[ADDR]]
962*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
963*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
964*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
965*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
968*9880d681SAndroid Build Coastguard Worker   ret i16 %old
969*9880d681SAndroid Build Coastguard Worker}
970*9880d681SAndroid Build Coastguard Worker
971*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_umax_i32(i32 %offset) nounwind {
972*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i32:
973*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i32* @var32, i32 %offset seq_cst
974*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
975*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
976*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
977*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
978*9880d681SAndroid Build Coastguard Worker
979*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
980*9880d681SAndroid Build Coastguard Worker; CHECK: ldaex r[[OLD:[0-9]+]], [r[[ADDR]]]
981*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
982*9880d681SAndroid Build Coastguard Worker  ;  function there.
983*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r[[NEW:[0-9]+]], r0
984*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
985*9880d681SAndroid Build Coastguard Worker; Thumb mode: it hi
986*9880d681SAndroid Build Coastguard Worker; CHECK:      movhi r[[NEW]], r[[OLD]]
987*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stlex [[STATUS:r[0-9]+]], r[[NEW]], [r[[ADDR]]]
988*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
989*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
990*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
991*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
992*9880d681SAndroid Build Coastguard Worker
993*9880d681SAndroid Build Coastguard Worker; CHECK: mov r0, r[[OLD]]
994*9880d681SAndroid Build Coastguard Worker   ret i32 %old
995*9880d681SAndroid Build Coastguard Worker}
996*9880d681SAndroid Build Coastguard Worker
997*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_load_umax_i64(i64 %offset) nounwind {
998*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_umax_i64:
999*9880d681SAndroid Build Coastguard Worker   %old = atomicrmw umax i64* @var64, i64 %offset seq_cst
1000*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1001*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1002*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
1003*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
1004*9880d681SAndroid Build Coastguard Worker
1005*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
1006*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
1007*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
1008*9880d681SAndroid Build Coastguard Worker  ; function there.
1009*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
1010*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
1011*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
1012*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
1013*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
1014*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
1015*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movwlo [[CMP:r[0-9]+|lr]], #1
1016*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
1017*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINHI]], [[OLD2]]
1018*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
1019*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: movne [[MINLO]], [[OLD1]]
1020*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: stlexd [[STATUS:r[0-9]+]], [[MINLO]], [[MINHI]], [r[[ADDR]]]
1021*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB: stlexd [[STATUS:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}}, [r[[ADDR]]]
1022*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
1023*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1024*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1025*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1026*9880d681SAndroid Build Coastguard Worker
1027*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
1028*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
1029*9880d681SAndroid Build Coastguard Worker   ret void
1030*9880d681SAndroid Build Coastguard Worker}
1031*9880d681SAndroid Build Coastguard Worker
1032*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_cmpxchg_i8(i8 zeroext %wanted, i8 zeroext %new) nounwind {
1033*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i8:
1034*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i8* @var8, i8 %wanted, i8 %new acquire acquire
1035*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i8, i1 } %pair, 0
1036*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1037*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1038*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movw r[[ADDR:[0-9]+]], :lower16:var8
1039*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movt r[[ADDR]], :upper16:var8
1040*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB-DAG: mov r[[WANTED:[0-9]+]], r0
1041*9880d681SAndroid Build Coastguard Worker
1042*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
1043*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexb r[[OLD:[0-9]+]], [r[[ADDR]]]
1044*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
1045*9880d681SAndroid Build Coastguard Worker  ;  function there.
1046*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-NEXT:   cmp r[[OLD]], r0
1047*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB-NEXT: cmp r[[OLD]], r[[WANTED]]
1048*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1049*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: BB#2:
1050*9880d681SAndroid Build Coastguard Worker  ; As above, r1 is a reasonable guess.
1051*9880d681SAndroid Build Coastguard Worker; CHECK: strexb [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]
1052*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
1053*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1054*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b .LBB{{[0-9]+}}_4
1055*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_3:
1056*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: clrex
1057*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_4:
1058*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1059*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1060*9880d681SAndroid Build Coastguard Worker
1061*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov r0, r[[OLD]]
1062*9880d681SAndroid Build Coastguard Worker   ret i8 %old
1063*9880d681SAndroid Build Coastguard Worker}
1064*9880d681SAndroid Build Coastguard Worker
1065*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_cmpxchg_i16(i16 zeroext %wanted, i16 zeroext %new) nounwind {
1066*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i16:
1067*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i16* @var16, i16 %wanted, i16 %new seq_cst seq_cst
1068*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i16, i1 } %pair, 0
1069*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1070*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1071*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movw r[[ADDR:[0-9]+]], :lower16:var16
1072*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: movt r[[ADDR]], :upper16:var16
1073*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB-DAG: mov r[[WANTED:[0-9]+]], r0
1074*9880d681SAndroid Build Coastguard Worker
1075*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
1076*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexh r[[OLD:[0-9]+]], [r[[ADDR]]]
1077*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
1078*9880d681SAndroid Build Coastguard Worker  ;  function there.
1079*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-NEXT:   cmp r[[OLD]], r0
1080*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB-NEXT: cmp r[[OLD]], r[[WANTED]]
1081*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1082*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: BB#2:
1083*9880d681SAndroid Build Coastguard Worker  ; As above, r1 is a reasonable guess.
1084*9880d681SAndroid Build Coastguard Worker; CHECK: stlexh [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]
1085*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
1086*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1087*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b .LBB{{[0-9]+}}_4
1088*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_3:
1089*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: clrex
1090*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_4:
1091*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1092*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1093*9880d681SAndroid Build Coastguard Worker
1094*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mov r0, r[[OLD]]
1095*9880d681SAndroid Build Coastguard Worker   ret i16 %old
1096*9880d681SAndroid Build Coastguard Worker}
1097*9880d681SAndroid Build Coastguard Worker
1098*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind {
1099*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i32:
1100*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i32* @var32, i32 %wanted, i32 %new release monotonic
1101*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i32, i1 } %pair, 0
1102*9880d681SAndroid Build Coastguard Worker   store i32 %old, i32* @var32
1103*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1104*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1105*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var32
1106*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var32
1107*9880d681SAndroid Build Coastguard Worker
1108*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
1109*9880d681SAndroid Build Coastguard Worker; CHECK: ldrex r[[OLD:[0-9]+]], [r[[ADDR]]]
1110*9880d681SAndroid Build Coastguard Worker  ; r0 below is a reasonable guess but could change: it certainly comes into the
1111*9880d681SAndroid Build Coastguard Worker  ;  function there.
1112*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp r[[OLD]], r0
1113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: BB#2:
1115*9880d681SAndroid Build Coastguard Worker  ; As above, r1 is a reasonable guess.
1116*9880d681SAndroid Build Coastguard Worker; CHECK: stlex [[STATUS:r[0-9]+]], r1, [r[[ADDR]]]
1117*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
1118*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1119*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b .LBB{{[0-9]+}}_4
1120*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_3:
1121*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: clrex
1122*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_4:
1123*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1124*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1125*9880d681SAndroid Build Coastguard Worker
1126*9880d681SAndroid Build Coastguard Worker; CHECK: str{{(.w)?}} r[[OLD]],
1127*9880d681SAndroid Build Coastguard Worker   ret void
1128*9880d681SAndroid Build Coastguard Worker}
1129*9880d681SAndroid Build Coastguard Worker
1130*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind {
1131*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_cmpxchg_i64:
1132*9880d681SAndroid Build Coastguard Worker   %pair = cmpxchg i64* @var64, i64 %wanted, i64 %new monotonic monotonic
1133*9880d681SAndroid Build Coastguard Worker   %old = extractvalue { i64, i1 } %pair, 0
1134*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1135*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1136*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
1137*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
1138*9880d681SAndroid Build Coastguard Worker
1139*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
1140*9880d681SAndroid Build Coastguard Worker; CHECK: ldrexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
1141*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
1142*9880d681SAndroid Build Coastguard Worker  ; function there.
1143*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0
1144*9880d681SAndroid Build Coastguard Worker; CHECK-LE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1
1145*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-LE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
1146*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB-LE: orrs{{(\.w)?}} {{(r[0-9]+, )?}}[[MISMATCH_HI]], [[MISMATCH_LO]]
1147*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_HI:r[0-9]+|lr]], [[OLD2]], r1
1148*9880d681SAndroid Build Coastguard Worker; CHECK-BE-DAG: eor{{(\.w)?}} [[MISMATCH_LO:r[0-9]+|lr]], [[OLD1]], r0
1149*9880d681SAndroid Build Coastguard Worker; CHECK-ARM-BE: orrs{{(\.w)?}} {{r[0-9]+}}, [[MISMATCH_HI]], [[MISMATCH_LO]]
1150*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB-BE: orrs{{(\.w)?}} {{(r[0-9]+, )?}}[[MISMATCH_LO]], [[MISMATCH_HI]]
1151*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_3
1152*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: BB#2:
1153*9880d681SAndroid Build Coastguard Worker  ; As above, r2, r3 is a reasonable guess.
1154*9880d681SAndroid Build Coastguard Worker; CHECK: strexd [[STATUS:r[0-9]+]], r2, r3, [r[[ADDR]]]
1155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
1156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b .LBB{{[0-9]+}}_4
1158*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_3:
1159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: clrex
1160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .LBB{{[0-9]+}}_4:
1161*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1162*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1163*9880d681SAndroid Build Coastguard Worker
1164*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: strd [[OLD1]], [[OLD2]], [r[[ADDR]]]
1165*9880d681SAndroid Build Coastguard Worker   store i64 %old, i64* @var64
1166*9880d681SAndroid Build Coastguard Worker   ret void
1167*9880d681SAndroid Build Coastguard Worker}
1168*9880d681SAndroid Build Coastguard Worker
1169*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_monotonic_i8() nounwind {
1170*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_i8:
1171*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* @var8 monotonic, align 1
1172*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1173*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1174*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1175*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
1176*9880d681SAndroid Build Coastguard Worker; CHECK: ldrb r0, [r[[ADDR]]]
1177*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1178*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1179*9880d681SAndroid Build Coastguard Worker
1180*9880d681SAndroid Build Coastguard Worker  ret i8 %val
1181*9880d681SAndroid Build Coastguard Worker}
1182*9880d681SAndroid Build Coastguard Worker
1183*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_monotonic_regoff_i8(i64 %base, i64 %off) nounwind {
1184*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_regoff_i8:
1185*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
1186*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i8*
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* %addr monotonic, align 1
1189*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1190*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1191*9880d681SAndroid Build Coastguard Worker; CHECK-LE: ldrb r0, [r0, r2]
1192*9880d681SAndroid Build Coastguard Worker; CHECK-BE: ldrb r0, [r1, r3]
1193*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1194*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1195*9880d681SAndroid Build Coastguard Worker
1196*9880d681SAndroid Build Coastguard Worker  ret i8 %val
1197*9880d681SAndroid Build Coastguard Worker}
1198*9880d681SAndroid Build Coastguard Worker
1199*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_acquire_i8() nounwind {
1200*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_acquire_i8:
1201*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* @var8 acquire, align 1
1202*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1203*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1204*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1205*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1206*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1207*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
1208*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1209*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1210*9880d681SAndroid Build Coastguard Worker; CHECK: ldab r0, [r[[ADDR]]]
1211*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1212*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1213*9880d681SAndroid Build Coastguard Worker  ret i8 %val
1214*9880d681SAndroid Build Coastguard Worker}
1215*9880d681SAndroid Build Coastguard Worker
1216*9880d681SAndroid Build Coastguard Workerdefine i8 @test_atomic_load_seq_cst_i8() nounwind {
1217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_seq_cst_i8:
1218*9880d681SAndroid Build Coastguard Worker  %val = load atomic i8, i8* @var8 seq_cst, align 1
1219*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1220*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1221*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1222*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1223*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1224*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
1225*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1226*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1227*9880d681SAndroid Build Coastguard Worker; CHECK: ldab r0, [r[[ADDR]]]
1228*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1229*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1230*9880d681SAndroid Build Coastguard Worker  ret i8 %val
1231*9880d681SAndroid Build Coastguard Worker}
1232*9880d681SAndroid Build Coastguard Worker
1233*9880d681SAndroid Build Coastguard Workerdefine i16 @test_atomic_load_monotonic_i16() nounwind {
1234*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_i16:
1235*9880d681SAndroid Build Coastguard Worker  %val = load atomic i16, i16* @var16 monotonic, align 2
1236*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1237*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1238*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
1239*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1240*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1241*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
1242*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1243*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1244*9880d681SAndroid Build Coastguard Worker; CHECK: ldrh r0, [r[[ADDR]]]
1245*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1246*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker  ret i16 %val
1249*9880d681SAndroid Build Coastguard Worker}
1250*9880d681SAndroid Build Coastguard Worker
1251*9880d681SAndroid Build Coastguard Workerdefine i32 @test_atomic_load_monotonic_regoff_i32(i64 %base, i64 %off) nounwind {
1252*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_monotonic_regoff_i32:
1253*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
1254*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i32*
1255*9880d681SAndroid Build Coastguard Worker
1256*9880d681SAndroid Build Coastguard Worker  %val = load atomic i32, i32* %addr monotonic, align 4
1257*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1258*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1259*9880d681SAndroid Build Coastguard Worker; CHECK-LE: ldr r0, [r0, r2]
1260*9880d681SAndroid Build Coastguard Worker; CHECK-BE: ldr r0, [r1, r3]
1261*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1262*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1263*9880d681SAndroid Build Coastguard Worker
1264*9880d681SAndroid Build Coastguard Worker  ret i32 %val
1265*9880d681SAndroid Build Coastguard Worker}
1266*9880d681SAndroid Build Coastguard Worker
1267*9880d681SAndroid Build Coastguard Workerdefine i64 @test_atomic_load_seq_cst_i64() nounwind {
1268*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_load_seq_cst_i64:
1269*9880d681SAndroid Build Coastguard Worker  %val = load atomic i64, i64* @var64 seq_cst, align 8
1270*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1271*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1272*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var64
1273*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1274*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1275*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var64
1276*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1277*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1278*9880d681SAndroid Build Coastguard Worker; CHECK: ldaexd r0, r1, [r[[ADDR]]]
1279*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1280*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1281*9880d681SAndroid Build Coastguard Worker  ret i64 %val
1282*9880d681SAndroid Build Coastguard Worker}
1283*9880d681SAndroid Build Coastguard Worker
1284*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_i8(i8 %val) nounwind {
1285*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_i8:
1286*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* @var8 monotonic, align 1
1287*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1288*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
1289*9880d681SAndroid Build Coastguard Worker; CHECK: strb r0, [r[[ADDR]]]
1290*9880d681SAndroid Build Coastguard Worker
1291*9880d681SAndroid Build Coastguard Worker  ret void
1292*9880d681SAndroid Build Coastguard Worker}
1293*9880d681SAndroid Build Coastguard Worker
1294*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_regoff_i8(i64 %base, i64 %off, i8 %val) nounwind {
1295*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_regoff_i8:
1296*9880d681SAndroid Build Coastguard Worker
1297*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
1298*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i8*
1299*9880d681SAndroid Build Coastguard Worker
1300*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* %addr monotonic, align 1
1301*9880d681SAndroid Build Coastguard Worker; CHECK-LE: ldr{{b?(\.w)?}} [[VAL:r[0-9]+]], [sp]
1302*9880d681SAndroid Build Coastguard Worker; CHECK-LE: strb [[VAL]], [r0, r2]
1303*9880d681SAndroid Build Coastguard Worker; CHECK-BE: ldrb{{(\.w)?}} [[VAL:r[0-9]+]], [sp, #3]
1304*9880d681SAndroid Build Coastguard Worker; CHECK-BE: strb [[VAL]], [r1, r3]
1305*9880d681SAndroid Build Coastguard Worker
1306*9880d681SAndroid Build Coastguard Worker  ret void
1307*9880d681SAndroid Build Coastguard Worker}
1308*9880d681SAndroid Build Coastguard Worker
1309*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_release_i8(i8 %val) nounwind {
1310*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_release_i8:
1311*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* @var8 release, align 1
1312*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1313*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1314*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1315*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1316*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1317*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
1318*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1319*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1320*9880d681SAndroid Build Coastguard Worker; CHECK: stlb r0, [r[[ADDR]]]
1321*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1322*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1323*9880d681SAndroid Build Coastguard Worker  ret void
1324*9880d681SAndroid Build Coastguard Worker}
1325*9880d681SAndroid Build Coastguard Worker
1326*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_seq_cst_i8(i8 %val) nounwind {
1327*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_seq_cst_i8:
1328*9880d681SAndroid Build Coastguard Worker  store atomic i8 %val, i8* @var8 seq_cst, align 1
1329*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1330*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1331*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var8
1332*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1333*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1334*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var8
1335*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1336*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1337*9880d681SAndroid Build Coastguard Worker; CHECK: stlb r0, [r[[ADDR]]]
1338*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1339*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1340*9880d681SAndroid Build Coastguard Worker  ret void
1341*9880d681SAndroid Build Coastguard Worker}
1342*9880d681SAndroid Build Coastguard Worker
1343*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_i16(i16 %val) nounwind {
1344*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_i16:
1345*9880d681SAndroid Build Coastguard Worker  store atomic i16 %val, i16* @var16 monotonic, align 2
1346*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1347*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1348*9880d681SAndroid Build Coastguard Worker; CHECK: movw r[[ADDR:[0-9]+]], :lower16:var16
1349*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1350*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1351*9880d681SAndroid Build Coastguard Worker; CHECK: movt r[[ADDR]], :upper16:var16
1352*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1353*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1354*9880d681SAndroid Build Coastguard Worker; CHECK: strh r0, [r[[ADDR]]]
1355*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1356*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1357*9880d681SAndroid Build Coastguard Worker  ret void
1358*9880d681SAndroid Build Coastguard Worker}
1359*9880d681SAndroid Build Coastguard Worker
1360*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_monotonic_regoff_i32(i64 %base, i64 %off, i32 %val) nounwind {
1361*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_monotonic_regoff_i32:
1362*9880d681SAndroid Build Coastguard Worker
1363*9880d681SAndroid Build Coastguard Worker  %addr_int = add i64 %base, %off
1364*9880d681SAndroid Build Coastguard Worker  %addr = inttoptr i64 %addr_int to i32*
1365*9880d681SAndroid Build Coastguard Worker
1366*9880d681SAndroid Build Coastguard Worker  store atomic i32 %val, i32* %addr monotonic, align 4
1367*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1368*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1369*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[VAL:r[0-9]+]], [sp]
1370*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1371*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1372*9880d681SAndroid Build Coastguard Worker; CHECK-LE: str [[VAL]], [r0, r2]
1373*9880d681SAndroid Build Coastguard Worker; CHECK-BE: str [[VAL]], [r1, r3]
1374*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1375*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1376*9880d681SAndroid Build Coastguard Worker
1377*9880d681SAndroid Build Coastguard Worker  ret void
1378*9880d681SAndroid Build Coastguard Worker}
1379*9880d681SAndroid Build Coastguard Worker
1380*9880d681SAndroid Build Coastguard Workerdefine void @test_atomic_store_release_i64(i64 %val) nounwind {
1381*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_atomic_store_release_i64:
1382*9880d681SAndroid Build Coastguard Worker  store atomic i64 %val, i64* @var64 release, align 8
1383*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1384*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1385*9880d681SAndroid Build Coastguard Worker; CHECK: movw [[ADDR:r[0-9]+|lr]], :lower16:var64
1386*9880d681SAndroid Build Coastguard Worker; CHECK: movt [[ADDR]], :upper16:var64
1387*9880d681SAndroid Build Coastguard Worker
1388*9880d681SAndroid Build Coastguard Worker; CHECK: .LBB{{[0-9]+}}_1:
1389*9880d681SAndroid Build Coastguard Worker  ; r0, r1 below is a reasonable guess but could change: it certainly comes into the
1390*9880d681SAndroid Build Coastguard Worker  ; function there.
1391*9880d681SAndroid Build Coastguard Worker; CHECK: stlexd [[STATUS:r[0-9]+]], r0, r1, {{.*}}[[ADDR]]
1392*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[STATUS]], #0
1393*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne .LBB{{[0-9]+}}_1
1394*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: dmb
1395*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mcr
1396*9880d681SAndroid Build Coastguard Worker
1397*9880d681SAndroid Build Coastguard Worker  ret void
1398*9880d681SAndroid Build Coastguard Worker}
1399*9880d681SAndroid Build Coastguard Worker
1400*9880d681SAndroid Build Coastguard Workerdefine i32 @not.barriers(i32* %var, i1 %cond) {
1401*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: not.barriers:
1402*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %atomic_ver, label %simple_ver
1403*9880d681SAndroid Build Coastguard Workersimple_ver:
1404*9880d681SAndroid Build Coastguard Worker  %oldval = load i32, i32* %var
1405*9880d681SAndroid Build Coastguard Worker  %newval = add nsw i32 %oldval, -1
1406*9880d681SAndroid Build Coastguard Worker  store i32 %newval, i32* %var
1407*9880d681SAndroid Build Coastguard Worker  br label %somewhere
1408*9880d681SAndroid Build Coastguard Workeratomic_ver:
1409*9880d681SAndroid Build Coastguard Worker  fence seq_cst
1410*9880d681SAndroid Build Coastguard Worker  %val = atomicrmw add i32* %var, i32 -1 monotonic
1411*9880d681SAndroid Build Coastguard Worker  fence seq_cst
1412*9880d681SAndroid Build Coastguard Worker  br label %somewhere
1413*9880d681SAndroid Build Coastguard Worker; CHECK: dmb
1414*9880d681SAndroid Build Coastguard Worker; CHECK: ldrex
1415*9880d681SAndroid Build Coastguard Worker; CHECK: dmb
1416*9880d681SAndroid Build Coastguard Worker  ; The key point here is that the second dmb isn't immediately followed by the
1417*9880d681SAndroid Build Coastguard Worker  ; simple_ver basic block, which LLVM attempted to do when DMB had been marked
1418*9880d681SAndroid Build Coastguard Worker  ; with isBarrier. For now, look for something that looks like "somewhere".
1419*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: {{mov|bx}}
1420*9880d681SAndroid Build Coastguard Workersomewhere:
1421*9880d681SAndroid Build Coastguard Worker  %combined = phi i32 [ %val, %atomic_ver ], [ %newval, %simple_ver]
1422*9880d681SAndroid Build Coastguard Worker  ret i32 %combined
1423*9880d681SAndroid Build Coastguard Worker}
1424