xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/atomic_mi.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | FileCheck %s --check-prefix X64
2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=i686-unknown-unknown -verify-machineinstrs | FileCheck %s --check-prefix X32
3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=slow-incdec -verify-machineinstrs | FileCheck %s --check-prefix SLOW_INC
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; This file checks that atomic (non-seq_cst) stores of immediate values are
6*9880d681SAndroid Build Coastguard Worker; done in one mov instruction and not 2. More precisely, it makes sure that the
7*9880d681SAndroid Build Coastguard Worker; immediate is not first copied uselessly into a register.
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker; Similarily, it checks that a binary operation of an immediate with an atomic
10*9880d681SAndroid Build Coastguard Worker; variable that is stored back in that variable is done as a single instruction.
11*9880d681SAndroid Build Coastguard Worker; For example: x.store(42 + x.load(memory_order_acquire), memory_order_release)
12*9880d681SAndroid Build Coastguard Worker; should be just an add instruction, instead of loading x into a register, doing
13*9880d681SAndroid Build Coastguard Worker; an add and storing the result back.
14*9880d681SAndroid Build Coastguard Worker; The binary operations supported are currently add, and, or, xor.
15*9880d681SAndroid Build Coastguard Worker; sub is not supported because they are translated by an addition of the
16*9880d681SAndroid Build Coastguard Worker; negated immediate.
17*9880d681SAndroid Build Coastguard Worker;
18*9880d681SAndroid Build Coastguard Worker; We also check the same patterns:
19*9880d681SAndroid Build Coastguard Worker; - For inc/dec.
20*9880d681SAndroid Build Coastguard Worker; - For register instead of immediate operands.
21*9880d681SAndroid Build Coastguard Worker; - For floating point operations.
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker; seq_cst stores are left as (lock) xchgl, but we try to check every other
24*9880d681SAndroid Build Coastguard Worker; attribute at least once.
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker; Please note that these operations do not require the lock prefix: only
27*9880d681SAndroid Build Coastguard Worker; sequentially consistent stores require this kind of protection on X86.
28*9880d681SAndroid Build Coastguard Worker; And even for seq_cst operations, llvm uses the xchg instruction which has
29*9880d681SAndroid Build Coastguard Worker; an implicit lock prefix, so making it explicit is not required.
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workerdefine void @store_atomic_imm_8(i8* %p) {
32*9880d681SAndroid Build Coastguard Worker; X64-LABEL: store_atomic_imm_8:
33*9880d681SAndroid Build Coastguard Worker; X64: movb
34*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
35*9880d681SAndroid Build Coastguard Worker; X32-LABEL: store_atomic_imm_8:
36*9880d681SAndroid Build Coastguard Worker; X32: movb
37*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
38*9880d681SAndroid Build Coastguard Worker  store atomic i8 42, i8* %p release, align 1
39*9880d681SAndroid Build Coastguard Worker  ret void
40*9880d681SAndroid Build Coastguard Worker}
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Workerdefine void @store_atomic_imm_16(i16* %p) {
43*9880d681SAndroid Build Coastguard Worker; X64-LABEL: store_atomic_imm_16:
44*9880d681SAndroid Build Coastguard Worker; X64: movw
45*9880d681SAndroid Build Coastguard Worker; X64-NOT: movw
46*9880d681SAndroid Build Coastguard Worker; X32-LABEL: store_atomic_imm_16:
47*9880d681SAndroid Build Coastguard Worker; X32: movw
48*9880d681SAndroid Build Coastguard Worker; X32-NOT: movw
49*9880d681SAndroid Build Coastguard Worker  store atomic i16 42, i16* %p monotonic, align 2
50*9880d681SAndroid Build Coastguard Worker  ret void
51*9880d681SAndroid Build Coastguard Worker}
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Workerdefine void @store_atomic_imm_32(i32* %p) {
54*9880d681SAndroid Build Coastguard Worker; X64-LABEL: store_atomic_imm_32:
55*9880d681SAndroid Build Coastguard Worker; X64: movl
56*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
57*9880d681SAndroid Build Coastguard Worker;   On 32 bits, there is an extra movl for each of those functions
58*9880d681SAndroid Build Coastguard Worker;   (probably for alignment reasons).
59*9880d681SAndroid Build Coastguard Worker; X32-LABEL: store_atomic_imm_32:
60*9880d681SAndroid Build Coastguard Worker; X32: movl 4(%esp), %eax
61*9880d681SAndroid Build Coastguard Worker; X32: movl
62*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
63*9880d681SAndroid Build Coastguard Worker  store atomic i32 42, i32* %p release, align 4
64*9880d681SAndroid Build Coastguard Worker  ret void
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Workerdefine void @store_atomic_imm_64(i64* %p) {
68*9880d681SAndroid Build Coastguard Worker; X64-LABEL: store_atomic_imm_64:
69*9880d681SAndroid Build Coastguard Worker; X64: movq
70*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
71*9880d681SAndroid Build Coastguard Worker;   These are implemented with a CAS loop on 32 bit architectures, and thus
72*9880d681SAndroid Build Coastguard Worker;   cannot be optimized in the same way as the others.
73*9880d681SAndroid Build Coastguard Worker; X32-LABEL: store_atomic_imm_64:
74*9880d681SAndroid Build Coastguard Worker; X32: cmpxchg8b
75*9880d681SAndroid Build Coastguard Worker  store atomic i64 42, i64* %p release, align 8
76*9880d681SAndroid Build Coastguard Worker  ret void
77*9880d681SAndroid Build Coastguard Worker}
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker; If an immediate is too big to fit in 32 bits, it cannot be store in one mov,
80*9880d681SAndroid Build Coastguard Worker; even on X64, one must use movabsq that can only target a register.
81*9880d681SAndroid Build Coastguard Workerdefine void @store_atomic_imm_64_big(i64* %p) {
82*9880d681SAndroid Build Coastguard Worker; X64-LABEL: store_atomic_imm_64_big:
83*9880d681SAndroid Build Coastguard Worker; X64: movabsq
84*9880d681SAndroid Build Coastguard Worker; X64: movq
85*9880d681SAndroid Build Coastguard Worker  store atomic i64 100000000000, i64* %p monotonic, align 8
86*9880d681SAndroid Build Coastguard Worker  ret void
87*9880d681SAndroid Build Coastguard Worker}
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker; It would be incorrect to replace a lock xchgl by a movl
90*9880d681SAndroid Build Coastguard Workerdefine void @store_atomic_imm_32_seq_cst(i32* %p) {
91*9880d681SAndroid Build Coastguard Worker; X64-LABEL: store_atomic_imm_32_seq_cst:
92*9880d681SAndroid Build Coastguard Worker; X64: xchgl
93*9880d681SAndroid Build Coastguard Worker; X32-LABEL: store_atomic_imm_32_seq_cst:
94*9880d681SAndroid Build Coastguard Worker; X32: xchgl
95*9880d681SAndroid Build Coastguard Worker  store atomic i32 42, i32* %p seq_cst, align 4
96*9880d681SAndroid Build Coastguard Worker  ret void
97*9880d681SAndroid Build Coastguard Worker}
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker; ----- ADD -----
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Workerdefine void @add_8i(i8* %p) {
102*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_8i:
103*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
104*9880d681SAndroid Build Coastguard Worker; X64: addb
105*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
106*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_8i:
107*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
108*9880d681SAndroid Build Coastguard Worker; X32: addb
109*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
110*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p seq_cst, align 1
111*9880d681SAndroid Build Coastguard Worker  %2 = add i8 %1, 2
112*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
113*9880d681SAndroid Build Coastguard Worker  ret void
114*9880d681SAndroid Build Coastguard Worker}
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Workerdefine void @add_8r(i8* %p, i8 %v) {
117*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_8r:
118*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
119*9880d681SAndroid Build Coastguard Worker; X64: addb
120*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
121*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_8r:
122*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
123*9880d681SAndroid Build Coastguard Worker; X32: addb
124*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
125*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p seq_cst, align 1
126*9880d681SAndroid Build Coastguard Worker  %2 = add i8 %1, %v
127*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
128*9880d681SAndroid Build Coastguard Worker  ret void
129*9880d681SAndroid Build Coastguard Worker}
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Workerdefine void @add_16i(i16* %p) {
132*9880d681SAndroid Build Coastguard Worker;   Currently the transformation is not done on 16 bit accesses, as the backend
133*9880d681SAndroid Build Coastguard Worker;   treat 16 bit arithmetic as expensive on X86/X86_64.
134*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_16i:
135*9880d681SAndroid Build Coastguard Worker; X64-NOT: addw
136*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_16i:
137*9880d681SAndroid Build Coastguard Worker; X32-NOT: addw
138*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
139*9880d681SAndroid Build Coastguard Worker  %2 = add i16 %1, 2
140*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
141*9880d681SAndroid Build Coastguard Worker  ret void
142*9880d681SAndroid Build Coastguard Worker}
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Workerdefine void @add_16r(i16* %p, i16 %v) {
145*9880d681SAndroid Build Coastguard Worker;   Currently the transformation is not done on 16 bit accesses, as the backend
146*9880d681SAndroid Build Coastguard Worker;   treat 16 bit arithmetic as expensive on X86/X86_64.
147*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_16r:
148*9880d681SAndroid Build Coastguard Worker; X64-NOT: addw
149*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_16r:
150*9880d681SAndroid Build Coastguard Worker; X32-NOT: addw [.*], (
151*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
152*9880d681SAndroid Build Coastguard Worker  %2 = add i16 %1, %v
153*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
154*9880d681SAndroid Build Coastguard Worker  ret void
155*9880d681SAndroid Build Coastguard Worker}
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Workerdefine void @add_32i(i32* %p) {
158*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_32i:
159*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
160*9880d681SAndroid Build Coastguard Worker; X64: addl
161*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
162*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_32i:
163*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
164*9880d681SAndroid Build Coastguard Worker; X32: addl
165*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
166*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
167*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, 2
168*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p monotonic, align 4
169*9880d681SAndroid Build Coastguard Worker  ret void
170*9880d681SAndroid Build Coastguard Worker}
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Workerdefine void @add_32r(i32* %p, i32 %v) {
173*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_32r:
174*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
175*9880d681SAndroid Build Coastguard Worker; X64: addl
176*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
177*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_32r:
178*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
179*9880d681SAndroid Build Coastguard Worker; X32: addl
180*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
181*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
182*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, %v
183*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p monotonic, align 4
184*9880d681SAndroid Build Coastguard Worker  ret void
185*9880d681SAndroid Build Coastguard Worker}
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker; The following is a corner case where the load is added to itself. The pattern
188*9880d681SAndroid Build Coastguard Worker; matching should not fold this. We only test with 32-bit add, but the same
189*9880d681SAndroid Build Coastguard Worker; applies to other sizes and operations.
190*9880d681SAndroid Build Coastguard Workerdefine void @add_32r_self(i32* %p) {
191*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_32r_self:
192*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
193*9880d681SAndroid Build Coastguard Worker; X64: movl (%[[M:[a-z]+]]), %[[R:[a-z]+]]
194*9880d681SAndroid Build Coastguard Worker; X64: addl %[[R]], %[[R]]
195*9880d681SAndroid Build Coastguard Worker; X64: movl %[[R]], (%[[M]])
196*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_32r_self:
197*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
198*9880d681SAndroid Build Coastguard Worker; X32: movl (%[[M:[a-z]+]]), %[[R:[a-z]+]]
199*9880d681SAndroid Build Coastguard Worker; X32: addl %[[R]], %[[R]]
200*9880d681SAndroid Build Coastguard Worker; X32: movl %[[R]], (%[[M]])
201*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
202*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, %1
203*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p monotonic, align 4
204*9880d681SAndroid Build Coastguard Worker  ret void
205*9880d681SAndroid Build Coastguard Worker}
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker; The following is a corner case where the load's result is returned. The
208*9880d681SAndroid Build Coastguard Worker; optimizer isn't allowed to duplicate the load because it's atomic.
209*9880d681SAndroid Build Coastguard Workerdefine i32 @add_32r_ret_load(i32* %p, i32 %v) {
210*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_32r_ret_load:
211*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
212*9880d681SAndroid Build Coastguard Worker; X64:      movl (%rdi), %eax
213*9880d681SAndroid Build Coastguard Worker; X64-NEXT: addl %eax, %esi
214*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movl %esi, (%rdi)
215*9880d681SAndroid Build Coastguard Worker; X64-NEXT: retq
216*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_32r_ret_load:
217*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
218*9880d681SAndroid Build Coastguard Worker; X32:      movl 4(%esp), %[[P:[a-z]+]]
219*9880d681SAndroid Build Coastguard Worker; X32-NEXT: movl (%[[P]]),
220*9880d681SAndroid Build Coastguard Worker; X32-NOT: %[[P]]
221*9880d681SAndroid Build Coastguard Worker; More code here, we just don't want it to load from P.
222*9880d681SAndroid Build Coastguard Worker; X32: movl %{{.*}}, (%[[P]])
223*9880d681SAndroid Build Coastguard Worker; X32-NEXT: retl
224*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
225*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, %v
226*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p monotonic, align 4
227*9880d681SAndroid Build Coastguard Worker  ret i32 %1
228*9880d681SAndroid Build Coastguard Worker}
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Workerdefine void @add_64i(i64* %p) {
231*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_64i:
232*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
233*9880d681SAndroid Build Coastguard Worker; X64: addq
234*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
235*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'addq'.
236*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_64i:
237*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
238*9880d681SAndroid Build Coastguard Worker  %2 = add i64 %1, 2
239*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
240*9880d681SAndroid Build Coastguard Worker  ret void
241*9880d681SAndroid Build Coastguard Worker}
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Workerdefine void @add_64r(i64* %p, i64 %v) {
244*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_64r:
245*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
246*9880d681SAndroid Build Coastguard Worker; X64: addq
247*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
248*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'addq'.
249*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_64r:
250*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
251*9880d681SAndroid Build Coastguard Worker  %2 = add i64 %1, %v
252*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
253*9880d681SAndroid Build Coastguard Worker  ret void
254*9880d681SAndroid Build Coastguard Worker}
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Workerdefine void @add_32i_seq_cst(i32* %p) {
257*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_32i_seq_cst:
258*9880d681SAndroid Build Coastguard Worker; X64: xchgl
259*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_32i_seq_cst:
260*9880d681SAndroid Build Coastguard Worker; X32: xchgl
261*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
262*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, 2
263*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
264*9880d681SAndroid Build Coastguard Worker  ret void
265*9880d681SAndroid Build Coastguard Worker}
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Workerdefine void @add_32r_seq_cst(i32* %p, i32 %v) {
268*9880d681SAndroid Build Coastguard Worker; X64-LABEL: add_32r_seq_cst:
269*9880d681SAndroid Build Coastguard Worker; X64: xchgl
270*9880d681SAndroid Build Coastguard Worker; X32-LABEL: add_32r_seq_cst:
271*9880d681SAndroid Build Coastguard Worker; X32: xchgl
272*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
273*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, %v
274*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
275*9880d681SAndroid Build Coastguard Worker  ret void
276*9880d681SAndroid Build Coastguard Worker}
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker; ----- AND -----
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Workerdefine void @and_8i(i8* %p) {
281*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_8i:
282*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
283*9880d681SAndroid Build Coastguard Worker; X64: andb
284*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
285*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_8i:
286*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
287*9880d681SAndroid Build Coastguard Worker; X32: andb
288*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
289*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p monotonic, align 1
290*9880d681SAndroid Build Coastguard Worker  %2 = and i8 %1, 2
291*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
292*9880d681SAndroid Build Coastguard Worker  ret void
293*9880d681SAndroid Build Coastguard Worker}
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Workerdefine void @and_8r(i8* %p, i8 %v) {
296*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_8r:
297*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
298*9880d681SAndroid Build Coastguard Worker; X64: andb
299*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
300*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_8r:
301*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
302*9880d681SAndroid Build Coastguard Worker; X32: andb
303*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
304*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p monotonic, align 1
305*9880d681SAndroid Build Coastguard Worker  %2 = and i8 %1, %v
306*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
307*9880d681SAndroid Build Coastguard Worker  ret void
308*9880d681SAndroid Build Coastguard Worker}
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Workerdefine void @and_16i(i16* %p) {
311*9880d681SAndroid Build Coastguard Worker;   Currently the transformation is not done on 16 bit accesses, as the backend
312*9880d681SAndroid Build Coastguard Worker;   treat 16 bit arithmetic as expensive on X86/X86_64.
313*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_16i:
314*9880d681SAndroid Build Coastguard Worker; X64-NOT: andw
315*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_16i:
316*9880d681SAndroid Build Coastguard Worker; X32-NOT: andw
317*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
318*9880d681SAndroid Build Coastguard Worker  %2 = and i16 %1, 2
319*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
320*9880d681SAndroid Build Coastguard Worker  ret void
321*9880d681SAndroid Build Coastguard Worker}
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Workerdefine void @and_16r(i16* %p, i16 %v) {
324*9880d681SAndroid Build Coastguard Worker;   Currently the transformation is not done on 16 bit accesses, as the backend
325*9880d681SAndroid Build Coastguard Worker;   treat 16 bit arithmetic as expensive on X86/X86_64.
326*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_16r:
327*9880d681SAndroid Build Coastguard Worker; X64-NOT: andw
328*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_16r:
329*9880d681SAndroid Build Coastguard Worker; X32-NOT: andw [.*], (
330*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
331*9880d681SAndroid Build Coastguard Worker  %2 = and i16 %1, %v
332*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
333*9880d681SAndroid Build Coastguard Worker  ret void
334*9880d681SAndroid Build Coastguard Worker}
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Workerdefine void @and_32i(i32* %p) {
337*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_32i:
338*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
339*9880d681SAndroid Build Coastguard Worker; X64: andl
340*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
341*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_32i:
342*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
343*9880d681SAndroid Build Coastguard Worker; X32: andl
344*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
345*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
346*9880d681SAndroid Build Coastguard Worker  %2 = and i32 %1, 2
347*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p release, align 4
348*9880d681SAndroid Build Coastguard Worker  ret void
349*9880d681SAndroid Build Coastguard Worker}
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Workerdefine void @and_32r(i32* %p, i32 %v) {
352*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_32r:
353*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
354*9880d681SAndroid Build Coastguard Worker; X64: andl
355*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
356*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_32r:
357*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
358*9880d681SAndroid Build Coastguard Worker; X32: andl
359*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
360*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
361*9880d681SAndroid Build Coastguard Worker  %2 = and i32 %1, %v
362*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p release, align 4
363*9880d681SAndroid Build Coastguard Worker  ret void
364*9880d681SAndroid Build Coastguard Worker}
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Workerdefine void @and_64i(i64* %p) {
367*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_64i:
368*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
369*9880d681SAndroid Build Coastguard Worker; X64: andq
370*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
371*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'andq'.
372*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_64i:
373*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
374*9880d681SAndroid Build Coastguard Worker  %2 = and i64 %1, 2
375*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
376*9880d681SAndroid Build Coastguard Worker  ret void
377*9880d681SAndroid Build Coastguard Worker}
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Workerdefine void @and_64r(i64* %p, i64 %v) {
380*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_64r:
381*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
382*9880d681SAndroid Build Coastguard Worker; X64: andq
383*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
384*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'andq'.
385*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_64r:
386*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
387*9880d681SAndroid Build Coastguard Worker  %2 = and i64 %1, %v
388*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
389*9880d681SAndroid Build Coastguard Worker  ret void
390*9880d681SAndroid Build Coastguard Worker}
391*9880d681SAndroid Build Coastguard Worker
392*9880d681SAndroid Build Coastguard Workerdefine void @and_32i_seq_cst(i32* %p) {
393*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_32i_seq_cst:
394*9880d681SAndroid Build Coastguard Worker; X64: xchgl
395*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_32i_seq_cst:
396*9880d681SAndroid Build Coastguard Worker; X32: xchgl
397*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
398*9880d681SAndroid Build Coastguard Worker  %2 = and i32 %1, 2
399*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
400*9880d681SAndroid Build Coastguard Worker  ret void
401*9880d681SAndroid Build Coastguard Worker}
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Workerdefine void @and_32r_seq_cst(i32* %p, i32 %v) {
404*9880d681SAndroid Build Coastguard Worker; X64-LABEL: and_32r_seq_cst:
405*9880d681SAndroid Build Coastguard Worker; X64: xchgl
406*9880d681SAndroid Build Coastguard Worker; X32-LABEL: and_32r_seq_cst:
407*9880d681SAndroid Build Coastguard Worker; X32: xchgl
408*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
409*9880d681SAndroid Build Coastguard Worker  %2 = and i32 %1, %v
410*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
411*9880d681SAndroid Build Coastguard Worker  ret void
412*9880d681SAndroid Build Coastguard Worker}
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker; ----- OR -----
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Workerdefine void @or_8i(i8* %p) {
417*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_8i:
418*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
419*9880d681SAndroid Build Coastguard Worker; X64: orb
420*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
421*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_8i:
422*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
423*9880d681SAndroid Build Coastguard Worker; X32: orb
424*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
425*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p acquire, align 1
426*9880d681SAndroid Build Coastguard Worker  %2 = or i8 %1, 2
427*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
428*9880d681SAndroid Build Coastguard Worker  ret void
429*9880d681SAndroid Build Coastguard Worker}
430*9880d681SAndroid Build Coastguard Worker
431*9880d681SAndroid Build Coastguard Workerdefine void @or_8r(i8* %p, i8 %v) {
432*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_8r:
433*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
434*9880d681SAndroid Build Coastguard Worker; X64: orb
435*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
436*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_8r:
437*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
438*9880d681SAndroid Build Coastguard Worker; X32: orb
439*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
440*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p acquire, align 1
441*9880d681SAndroid Build Coastguard Worker  %2 = or i8 %1, %v
442*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
443*9880d681SAndroid Build Coastguard Worker  ret void
444*9880d681SAndroid Build Coastguard Worker}
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Workerdefine void @or_16i(i16* %p) {
447*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_16i:
448*9880d681SAndroid Build Coastguard Worker; X64-NOT: orw
449*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_16i:
450*9880d681SAndroid Build Coastguard Worker; X32-NOT: orw
451*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
452*9880d681SAndroid Build Coastguard Worker  %2 = or i16 %1, 2
453*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
454*9880d681SAndroid Build Coastguard Worker  ret void
455*9880d681SAndroid Build Coastguard Worker}
456*9880d681SAndroid Build Coastguard Worker
457*9880d681SAndroid Build Coastguard Workerdefine void @or_16r(i16* %p, i16 %v) {
458*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_16r:
459*9880d681SAndroid Build Coastguard Worker; X64-NOT: orw
460*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_16r:
461*9880d681SAndroid Build Coastguard Worker; X32-NOT: orw [.*], (
462*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
463*9880d681SAndroid Build Coastguard Worker  %2 = or i16 %1, %v
464*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
465*9880d681SAndroid Build Coastguard Worker  ret void
466*9880d681SAndroid Build Coastguard Worker}
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Workerdefine void @or_32i(i32* %p) {
469*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_32i:
470*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
471*9880d681SAndroid Build Coastguard Worker; X64: orl
472*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
473*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_32i:
474*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
475*9880d681SAndroid Build Coastguard Worker; X32: orl
476*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
477*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
478*9880d681SAndroid Build Coastguard Worker  %2 = or i32 %1, 2
479*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p release, align 4
480*9880d681SAndroid Build Coastguard Worker  ret void
481*9880d681SAndroid Build Coastguard Worker}
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Workerdefine void @or_32r(i32* %p, i32 %v) {
484*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_32r:
485*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
486*9880d681SAndroid Build Coastguard Worker; X64: orl
487*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
488*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_32r:
489*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
490*9880d681SAndroid Build Coastguard Worker; X32: orl
491*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
492*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
493*9880d681SAndroid Build Coastguard Worker  %2 = or i32 %1, %v
494*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p release, align 4
495*9880d681SAndroid Build Coastguard Worker  ret void
496*9880d681SAndroid Build Coastguard Worker}
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Workerdefine void @or_64i(i64* %p) {
499*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_64i:
500*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
501*9880d681SAndroid Build Coastguard Worker; X64: orq
502*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
503*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'orq'.
504*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_64i:
505*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
506*9880d681SAndroid Build Coastguard Worker  %2 = or i64 %1, 2
507*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
508*9880d681SAndroid Build Coastguard Worker  ret void
509*9880d681SAndroid Build Coastguard Worker}
510*9880d681SAndroid Build Coastguard Worker
511*9880d681SAndroid Build Coastguard Workerdefine void @or_64r(i64* %p, i64 %v) {
512*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_64r:
513*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
514*9880d681SAndroid Build Coastguard Worker; X64: orq
515*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
516*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'orq'.
517*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_64r:
518*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
519*9880d681SAndroid Build Coastguard Worker  %2 = or i64 %1, %v
520*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
521*9880d681SAndroid Build Coastguard Worker  ret void
522*9880d681SAndroid Build Coastguard Worker}
523*9880d681SAndroid Build Coastguard Worker
524*9880d681SAndroid Build Coastguard Workerdefine void @or_32i_seq_cst(i32* %p) {
525*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_32i_seq_cst:
526*9880d681SAndroid Build Coastguard Worker; X64: xchgl
527*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_32i_seq_cst:
528*9880d681SAndroid Build Coastguard Worker; X32: xchgl
529*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
530*9880d681SAndroid Build Coastguard Worker  %2 = or i32 %1, 2
531*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
532*9880d681SAndroid Build Coastguard Worker  ret void
533*9880d681SAndroid Build Coastguard Worker}
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard Workerdefine void @or_32r_seq_cst(i32* %p, i32 %v) {
536*9880d681SAndroid Build Coastguard Worker; X64-LABEL: or_32r_seq_cst:
537*9880d681SAndroid Build Coastguard Worker; X64: xchgl
538*9880d681SAndroid Build Coastguard Worker; X32-LABEL: or_32r_seq_cst:
539*9880d681SAndroid Build Coastguard Worker; X32: xchgl
540*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
541*9880d681SAndroid Build Coastguard Worker  %2 = or i32 %1, %v
542*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
543*9880d681SAndroid Build Coastguard Worker  ret void
544*9880d681SAndroid Build Coastguard Worker}
545*9880d681SAndroid Build Coastguard Worker
546*9880d681SAndroid Build Coastguard Worker; ----- XOR -----
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Workerdefine void @xor_8i(i8* %p) {
549*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_8i:
550*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
551*9880d681SAndroid Build Coastguard Worker; X64: xorb
552*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
553*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_8i:
554*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
555*9880d681SAndroid Build Coastguard Worker; X32: xorb
556*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
557*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p acquire, align 1
558*9880d681SAndroid Build Coastguard Worker  %2 = xor i8 %1, 2
559*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
560*9880d681SAndroid Build Coastguard Worker  ret void
561*9880d681SAndroid Build Coastguard Worker}
562*9880d681SAndroid Build Coastguard Worker
563*9880d681SAndroid Build Coastguard Workerdefine void @xor_8r(i8* %p, i8 %v) {
564*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_8r:
565*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
566*9880d681SAndroid Build Coastguard Worker; X64: xorb
567*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
568*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_8r:
569*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
570*9880d681SAndroid Build Coastguard Worker; X32: xorb
571*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
572*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p acquire, align 1
573*9880d681SAndroid Build Coastguard Worker  %2 = xor i8 %1, %v
574*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
575*9880d681SAndroid Build Coastguard Worker  ret void
576*9880d681SAndroid Build Coastguard Worker}
577*9880d681SAndroid Build Coastguard Worker
578*9880d681SAndroid Build Coastguard Workerdefine void @xor_16i(i16* %p) {
579*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_16i:
580*9880d681SAndroid Build Coastguard Worker; X64-NOT: xorw
581*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_16i:
582*9880d681SAndroid Build Coastguard Worker; X32-NOT: xorw
583*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
584*9880d681SAndroid Build Coastguard Worker  %2 = xor i16 %1, 2
585*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
586*9880d681SAndroid Build Coastguard Worker  ret void
587*9880d681SAndroid Build Coastguard Worker}
588*9880d681SAndroid Build Coastguard Worker
589*9880d681SAndroid Build Coastguard Workerdefine void @xor_16r(i16* %p, i16 %v) {
590*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_16r:
591*9880d681SAndroid Build Coastguard Worker; X64-NOT: xorw
592*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_16r:
593*9880d681SAndroid Build Coastguard Worker; X32-NOT: xorw [.*], (
594*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
595*9880d681SAndroid Build Coastguard Worker  %2 = xor i16 %1, %v
596*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
597*9880d681SAndroid Build Coastguard Worker  ret void
598*9880d681SAndroid Build Coastguard Worker}
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Workerdefine void @xor_32i(i32* %p) {
601*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_32i:
602*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
603*9880d681SAndroid Build Coastguard Worker; X64: xorl
604*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
605*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_32i:
606*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
607*9880d681SAndroid Build Coastguard Worker; X32: xorl
608*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
609*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
610*9880d681SAndroid Build Coastguard Worker  %2 = xor i32 %1, 2
611*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p release, align 4
612*9880d681SAndroid Build Coastguard Worker  ret void
613*9880d681SAndroid Build Coastguard Worker}
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Workerdefine void @xor_32r(i32* %p, i32 %v) {
616*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_32r:
617*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
618*9880d681SAndroid Build Coastguard Worker; X64: xorl
619*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
620*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_32r:
621*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
622*9880d681SAndroid Build Coastguard Worker; X32: xorl
623*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
624*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
625*9880d681SAndroid Build Coastguard Worker  %2 = xor i32 %1, %v
626*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p release, align 4
627*9880d681SAndroid Build Coastguard Worker  ret void
628*9880d681SAndroid Build Coastguard Worker}
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Workerdefine void @xor_64i(i64* %p) {
631*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_64i:
632*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
633*9880d681SAndroid Build Coastguard Worker; X64: xorq
634*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
635*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'xorq'.
636*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_64i:
637*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
638*9880d681SAndroid Build Coastguard Worker  %2 = xor i64 %1, 2
639*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
640*9880d681SAndroid Build Coastguard Worker  ret void
641*9880d681SAndroid Build Coastguard Worker}
642*9880d681SAndroid Build Coastguard Worker
643*9880d681SAndroid Build Coastguard Workerdefine void @xor_64r(i64* %p, i64 %v) {
644*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_64r:
645*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
646*9880d681SAndroid Build Coastguard Worker; X64: xorq
647*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
648*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'xorq'.
649*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_64r:
650*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
651*9880d681SAndroid Build Coastguard Worker  %2 = xor i64 %1, %v
652*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
653*9880d681SAndroid Build Coastguard Worker  ret void
654*9880d681SAndroid Build Coastguard Worker}
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Workerdefine void @xor_32i_seq_cst(i32* %p) {
657*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_32i_seq_cst:
658*9880d681SAndroid Build Coastguard Worker; X64: xchgl
659*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_32i_seq_cst:
660*9880d681SAndroid Build Coastguard Worker; X32: xchgl
661*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
662*9880d681SAndroid Build Coastguard Worker  %2 = xor i32 %1, 2
663*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
664*9880d681SAndroid Build Coastguard Worker  ret void
665*9880d681SAndroid Build Coastguard Worker}
666*9880d681SAndroid Build Coastguard Worker
667*9880d681SAndroid Build Coastguard Workerdefine void @xor_32r_seq_cst(i32* %p, i32 %v) {
668*9880d681SAndroid Build Coastguard Worker; X64-LABEL: xor_32r_seq_cst:
669*9880d681SAndroid Build Coastguard Worker; X64: xchgl
670*9880d681SAndroid Build Coastguard Worker; X32-LABEL: xor_32r_seq_cst:
671*9880d681SAndroid Build Coastguard Worker; X32: xchgl
672*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
673*9880d681SAndroid Build Coastguard Worker  %2 = xor i32 %1, %v
674*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
675*9880d681SAndroid Build Coastguard Worker  ret void
676*9880d681SAndroid Build Coastguard Worker}
677*9880d681SAndroid Build Coastguard Worker
678*9880d681SAndroid Build Coastguard Worker; ----- INC -----
679*9880d681SAndroid Build Coastguard Worker
680*9880d681SAndroid Build Coastguard Workerdefine void @inc_8(i8* %p) {
681*9880d681SAndroid Build Coastguard Worker; X64-LABEL: inc_8:
682*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
683*9880d681SAndroid Build Coastguard Worker; X64: incb
684*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
685*9880d681SAndroid Build Coastguard Worker; X32-LABEL: inc_8:
686*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
687*9880d681SAndroid Build Coastguard Worker; X32: incb
688*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
689*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: inc_8:
690*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: incb
691*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: movb
692*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p seq_cst, align 1
693*9880d681SAndroid Build Coastguard Worker  %2 = add i8 %1, 1
694*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
695*9880d681SAndroid Build Coastguard Worker  ret void
696*9880d681SAndroid Build Coastguard Worker}
697*9880d681SAndroid Build Coastguard Worker
698*9880d681SAndroid Build Coastguard Workerdefine void @inc_16(i16* %p) {
699*9880d681SAndroid Build Coastguard Worker;   Currently the transformation is not done on 16 bit accesses, as the backend
700*9880d681SAndroid Build Coastguard Worker;   treat 16 bit arithmetic as expensive on X86/X86_64.
701*9880d681SAndroid Build Coastguard Worker; X64-LABEL: inc_16:
702*9880d681SAndroid Build Coastguard Worker; X64-NOT: incw
703*9880d681SAndroid Build Coastguard Worker; X32-LABEL: inc_16:
704*9880d681SAndroid Build Coastguard Worker; X32-NOT: incw
705*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: inc_16:
706*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: incw
707*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
708*9880d681SAndroid Build Coastguard Worker  %2 = add i16 %1, 1
709*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
710*9880d681SAndroid Build Coastguard Worker  ret void
711*9880d681SAndroid Build Coastguard Worker}
712*9880d681SAndroid Build Coastguard Worker
713*9880d681SAndroid Build Coastguard Workerdefine void @inc_32(i32* %p) {
714*9880d681SAndroid Build Coastguard Worker; X64-LABEL: inc_32:
715*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
716*9880d681SAndroid Build Coastguard Worker; X64: incl
717*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
718*9880d681SAndroid Build Coastguard Worker; X32-LABEL: inc_32:
719*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
720*9880d681SAndroid Build Coastguard Worker; X32: incl
721*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
722*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: inc_32:
723*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: incl
724*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: movl
725*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
726*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, 1
727*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p monotonic, align 4
728*9880d681SAndroid Build Coastguard Worker  ret void
729*9880d681SAndroid Build Coastguard Worker}
730*9880d681SAndroid Build Coastguard Worker
731*9880d681SAndroid Build Coastguard Workerdefine void @inc_64(i64* %p) {
732*9880d681SAndroid Build Coastguard Worker; X64-LABEL: inc_64:
733*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
734*9880d681SAndroid Build Coastguard Worker; X64: incq
735*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
736*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'incq'.
737*9880d681SAndroid Build Coastguard Worker; X32-LABEL: inc_64:
738*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: inc_64:
739*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: incq
740*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: movq
741*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
742*9880d681SAndroid Build Coastguard Worker  %2 = add i64 %1, 1
743*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
744*9880d681SAndroid Build Coastguard Worker  ret void
745*9880d681SAndroid Build Coastguard Worker}
746*9880d681SAndroid Build Coastguard Worker
747*9880d681SAndroid Build Coastguard Workerdefine void @inc_32_seq_cst(i32* %p) {
748*9880d681SAndroid Build Coastguard Worker; X64-LABEL: inc_32_seq_cst:
749*9880d681SAndroid Build Coastguard Worker; X64: xchgl
750*9880d681SAndroid Build Coastguard Worker; X32-LABEL: inc_32_seq_cst:
751*9880d681SAndroid Build Coastguard Worker; X32: xchgl
752*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
753*9880d681SAndroid Build Coastguard Worker  %2 = add i32 %1, 1
754*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
755*9880d681SAndroid Build Coastguard Worker  ret void
756*9880d681SAndroid Build Coastguard Worker}
757*9880d681SAndroid Build Coastguard Worker
758*9880d681SAndroid Build Coastguard Worker; ----- DEC -----
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Workerdefine void @dec_8(i8* %p) {
761*9880d681SAndroid Build Coastguard Worker; X64-LABEL: dec_8:
762*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
763*9880d681SAndroid Build Coastguard Worker; X64: decb
764*9880d681SAndroid Build Coastguard Worker; X64-NOT: movb
765*9880d681SAndroid Build Coastguard Worker; X32-LABEL: dec_8:
766*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
767*9880d681SAndroid Build Coastguard Worker; X32: decb
768*9880d681SAndroid Build Coastguard Worker; X32-NOT: movb
769*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: dec_8:
770*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: decb
771*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: movb
772*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i8, i8* %p seq_cst, align 1
773*9880d681SAndroid Build Coastguard Worker  %2 = sub i8 %1, 1
774*9880d681SAndroid Build Coastguard Worker  store atomic i8 %2, i8* %p release, align 1
775*9880d681SAndroid Build Coastguard Worker  ret void
776*9880d681SAndroid Build Coastguard Worker}
777*9880d681SAndroid Build Coastguard Worker
778*9880d681SAndroid Build Coastguard Workerdefine void @dec_16(i16* %p) {
779*9880d681SAndroid Build Coastguard Worker;   Currently the transformation is not done on 16 bit accesses, as the backend
780*9880d681SAndroid Build Coastguard Worker;   treat 16 bit arithmetic as expensive on X86/X86_64.
781*9880d681SAndroid Build Coastguard Worker; X64-LABEL: dec_16:
782*9880d681SAndroid Build Coastguard Worker; X64-NOT: decw
783*9880d681SAndroid Build Coastguard Worker; X32-LABEL: dec_16:
784*9880d681SAndroid Build Coastguard Worker; X32-NOT: decw
785*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: dec_16:
786*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: decw
787*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i16, i16* %p acquire, align 2
788*9880d681SAndroid Build Coastguard Worker  %2 = sub i16 %1, 1
789*9880d681SAndroid Build Coastguard Worker  store atomic i16 %2, i16* %p release, align 2
790*9880d681SAndroid Build Coastguard Worker  ret void
791*9880d681SAndroid Build Coastguard Worker}
792*9880d681SAndroid Build Coastguard Worker
793*9880d681SAndroid Build Coastguard Workerdefine void @dec_32(i32* %p) {
794*9880d681SAndroid Build Coastguard Worker; X64-LABEL: dec_32:
795*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
796*9880d681SAndroid Build Coastguard Worker; X64: decl
797*9880d681SAndroid Build Coastguard Worker; X64-NOT: movl
798*9880d681SAndroid Build Coastguard Worker; X32-LABEL: dec_32:
799*9880d681SAndroid Build Coastguard Worker; X32-NOT: lock
800*9880d681SAndroid Build Coastguard Worker; X32: decl
801*9880d681SAndroid Build Coastguard Worker; X32-NOT: movl
802*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: dec_32:
803*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: decl
804*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: movl
805*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p acquire, align 4
806*9880d681SAndroid Build Coastguard Worker  %2 = sub i32 %1, 1
807*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p monotonic, align 4
808*9880d681SAndroid Build Coastguard Worker  ret void
809*9880d681SAndroid Build Coastguard Worker}
810*9880d681SAndroid Build Coastguard Worker
811*9880d681SAndroid Build Coastguard Workerdefine void @dec_64(i64* %p) {
812*9880d681SAndroid Build Coastguard Worker; X64-LABEL: dec_64:
813*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
814*9880d681SAndroid Build Coastguard Worker; X64: decq
815*9880d681SAndroid Build Coastguard Worker; X64-NOT: movq
816*9880d681SAndroid Build Coastguard Worker;   We do not check X86-32 as it cannot do 'decq'.
817*9880d681SAndroid Build Coastguard Worker; X32-LABEL: dec_64:
818*9880d681SAndroid Build Coastguard Worker; SLOW_INC-LABEL: dec_64:
819*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: decq
820*9880d681SAndroid Build Coastguard Worker; SLOW_INC-NOT: movq
821*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %p acquire, align 8
822*9880d681SAndroid Build Coastguard Worker  %2 = sub i64 %1, 1
823*9880d681SAndroid Build Coastguard Worker  store atomic i64 %2, i64* %p release, align 8
824*9880d681SAndroid Build Coastguard Worker  ret void
825*9880d681SAndroid Build Coastguard Worker}
826*9880d681SAndroid Build Coastguard Worker
827*9880d681SAndroid Build Coastguard Workerdefine void @dec_32_seq_cst(i32* %p) {
828*9880d681SAndroid Build Coastguard Worker; X64-LABEL: dec_32_seq_cst:
829*9880d681SAndroid Build Coastguard Worker; X64: xchgl
830*9880d681SAndroid Build Coastguard Worker; X32-LABEL: dec_32_seq_cst:
831*9880d681SAndroid Build Coastguard Worker; X32: xchgl
832*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %p monotonic, align 4
833*9880d681SAndroid Build Coastguard Worker  %2 = sub i32 %1, 1
834*9880d681SAndroid Build Coastguard Worker  store atomic i32 %2, i32* %p seq_cst, align 4
835*9880d681SAndroid Build Coastguard Worker  ret void
836*9880d681SAndroid Build Coastguard Worker}
837*9880d681SAndroid Build Coastguard Worker
838*9880d681SAndroid Build Coastguard Worker; ----- FADD -----
839*9880d681SAndroid Build Coastguard Worker
840*9880d681SAndroid Build Coastguard Workerdefine void @fadd_32r(float* %loc, float %val) {
841*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_32r:
842*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
843*9880d681SAndroid Build Coastguard Worker; X64-NOT: mov
844*9880d681SAndroid Build Coastguard Worker; X64: addss (%[[M:[a-z]+]]), %[[XMM:xmm[0-9]+]]
845*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movss %[[XMM]], (%[[M]])
846*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_32r:
847*9880d681SAndroid Build Coastguard Worker; Don't check x86-32.
848*9880d681SAndroid Build Coastguard Worker; LLVM's SSE handling is conservative on x86-32 even without using atomics.
849*9880d681SAndroid Build Coastguard Worker  %floc = bitcast float* %loc to i32*
850*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i32, i32* %floc seq_cst, align 4
851*9880d681SAndroid Build Coastguard Worker  %2 = bitcast i32 %1 to float
852*9880d681SAndroid Build Coastguard Worker  %add = fadd float %2, %val
853*9880d681SAndroid Build Coastguard Worker  %3 = bitcast float %add to i32
854*9880d681SAndroid Build Coastguard Worker  store atomic i32 %3, i32* %floc release, align 4
855*9880d681SAndroid Build Coastguard Worker  ret void
856*9880d681SAndroid Build Coastguard Worker}
857*9880d681SAndroid Build Coastguard Worker
858*9880d681SAndroid Build Coastguard Workerdefine void @fadd_64r(double* %loc, double %val) {
859*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_64r:
860*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
861*9880d681SAndroid Build Coastguard Worker; X64-NOT: mov
862*9880d681SAndroid Build Coastguard Worker; X64: addsd (%[[M:[a-z]+]]), %[[XMM:xmm[0-9]+]]
863*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movsd %[[XMM]], (%[[M]])
864*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_64r:
865*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
866*9880d681SAndroid Build Coastguard Worker  %floc = bitcast double* %loc to i64*
867*9880d681SAndroid Build Coastguard Worker  %1 = load atomic i64, i64* %floc seq_cst, align 8
868*9880d681SAndroid Build Coastguard Worker  %2 = bitcast i64 %1 to double
869*9880d681SAndroid Build Coastguard Worker  %add = fadd double %2, %val
870*9880d681SAndroid Build Coastguard Worker  %3 = bitcast double %add to i64
871*9880d681SAndroid Build Coastguard Worker  store atomic i64 %3, i64* %floc release, align 8
872*9880d681SAndroid Build Coastguard Worker  ret void
873*9880d681SAndroid Build Coastguard Worker}
874*9880d681SAndroid Build Coastguard Worker
875*9880d681SAndroid Build Coastguard Worker@glob32 = global float 0.000000e+00, align 4
876*9880d681SAndroid Build Coastguard Worker@glob64 = global double 0.000000e+00, align 8
877*9880d681SAndroid Build Coastguard Worker
878*9880d681SAndroid Build Coastguard Worker; Floating-point add to a global using an immediate.
879*9880d681SAndroid Build Coastguard Workerdefine void @fadd_32g() {
880*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_32g:
881*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
882*9880d681SAndroid Build Coastguard Worker; X64:      movss .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]]
883*9880d681SAndroid Build Coastguard Worker; X64-NEXT: addss glob32(%rip), %[[XMM]]
884*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movss %[[XMM]], glob32(%rip)
885*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_32g:
886*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
887*9880d681SAndroid Build Coastguard Worker  %i = load atomic i32, i32* bitcast (float* @glob32 to i32*) monotonic, align 4
888*9880d681SAndroid Build Coastguard Worker  %f = bitcast i32 %i to float
889*9880d681SAndroid Build Coastguard Worker  %add = fadd float %f, 1.000000e+00
890*9880d681SAndroid Build Coastguard Worker  %s = bitcast float %add to i32
891*9880d681SAndroid Build Coastguard Worker  store atomic i32 %s, i32* bitcast (float* @glob32 to i32*) monotonic, align 4
892*9880d681SAndroid Build Coastguard Worker  ret void
893*9880d681SAndroid Build Coastguard Worker}
894*9880d681SAndroid Build Coastguard Worker
895*9880d681SAndroid Build Coastguard Workerdefine void @fadd_64g() {
896*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_64g:
897*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
898*9880d681SAndroid Build Coastguard Worker; X64:      movsd .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]]
899*9880d681SAndroid Build Coastguard Worker; X64-NEXT: addsd glob64(%rip), %[[XMM]]
900*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movsd %[[XMM]], glob64(%rip)
901*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_64g:
902*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
903*9880d681SAndroid Build Coastguard Worker  %i = load atomic i64, i64* bitcast (double* @glob64 to i64*) monotonic, align 8
904*9880d681SAndroid Build Coastguard Worker  %f = bitcast i64 %i to double
905*9880d681SAndroid Build Coastguard Worker  %add = fadd double %f, 1.000000e+00
906*9880d681SAndroid Build Coastguard Worker  %s = bitcast double %add to i64
907*9880d681SAndroid Build Coastguard Worker  store atomic i64 %s, i64* bitcast (double* @glob64 to i64*) monotonic, align 8
908*9880d681SAndroid Build Coastguard Worker  ret void
909*9880d681SAndroid Build Coastguard Worker}
910*9880d681SAndroid Build Coastguard Worker
911*9880d681SAndroid Build Coastguard Worker; Floating-point add to a hard-coded immediate location using an immediate.
912*9880d681SAndroid Build Coastguard Workerdefine void @fadd_32imm() {
913*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_32imm:
914*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
915*9880d681SAndroid Build Coastguard Worker; X64:      movl $3735928559, %e[[M:[a-z]+]]
916*9880d681SAndroid Build Coastguard Worker; X64:      movss .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]]
917*9880d681SAndroid Build Coastguard Worker; X64-NEXT: addss (%r[[M]]), %[[XMM]]
918*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movss %[[XMM]], (%r[[M]])
919*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_32imm:
920*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
921*9880d681SAndroid Build Coastguard Worker  %i = load atomic i32, i32* inttoptr (i32 3735928559 to i32*) monotonic, align 4
922*9880d681SAndroid Build Coastguard Worker  %f = bitcast i32 %i to float
923*9880d681SAndroid Build Coastguard Worker  %add = fadd float %f, 1.000000e+00
924*9880d681SAndroid Build Coastguard Worker  %s = bitcast float %add to i32
925*9880d681SAndroid Build Coastguard Worker  store atomic i32 %s, i32* inttoptr (i32 3735928559 to i32*) monotonic, align 4
926*9880d681SAndroid Build Coastguard Worker  ret void
927*9880d681SAndroid Build Coastguard Worker}
928*9880d681SAndroid Build Coastguard Worker
929*9880d681SAndroid Build Coastguard Workerdefine void @fadd_64imm() {
930*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_64imm:
931*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
932*9880d681SAndroid Build Coastguard Worker; X64:      movl $3735928559, %e[[M:[a-z]+]]
933*9880d681SAndroid Build Coastguard Worker; X64:      movsd .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]]
934*9880d681SAndroid Build Coastguard Worker; X64-NEXT: addsd (%r[[M]]), %[[XMM]]
935*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movsd %[[XMM]], (%r[[M]])
936*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_64imm:
937*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
938*9880d681SAndroid Build Coastguard Worker  %i = load atomic i64, i64* inttoptr (i64 3735928559 to i64*) monotonic, align 8
939*9880d681SAndroid Build Coastguard Worker  %f = bitcast i64 %i to double
940*9880d681SAndroid Build Coastguard Worker  %add = fadd double %f, 1.000000e+00
941*9880d681SAndroid Build Coastguard Worker  %s = bitcast double %add to i64
942*9880d681SAndroid Build Coastguard Worker  store atomic i64 %s, i64* inttoptr (i64 3735928559 to i64*) monotonic, align 8
943*9880d681SAndroid Build Coastguard Worker  ret void
944*9880d681SAndroid Build Coastguard Worker}
945*9880d681SAndroid Build Coastguard Worker
946*9880d681SAndroid Build Coastguard Worker; Floating-point add to a stack location.
947*9880d681SAndroid Build Coastguard Workerdefine void @fadd_32stack() {
948*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_32stack:
949*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
950*9880d681SAndroid Build Coastguard Worker; X64:      movss .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]]
951*9880d681SAndroid Build Coastguard Worker; X64-NEXT: addss [[STACKOFF:-?[0-9]+]](%rsp), %[[XMM]]
952*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movss %[[XMM]], [[STACKOFF]](%rsp)
953*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_32stack:
954*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
955*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i32, align 4
956*9880d681SAndroid Build Coastguard Worker  %bc3 = bitcast i32* %ptr to float*
957*9880d681SAndroid Build Coastguard Worker  %load = load atomic i32, i32* %ptr acquire, align 4
958*9880d681SAndroid Build Coastguard Worker  %bc0 = bitcast i32 %load to float
959*9880d681SAndroid Build Coastguard Worker  %fadd = fadd float 1.000000e+00, %bc0
960*9880d681SAndroid Build Coastguard Worker  %bc1 = bitcast float %fadd to i32
961*9880d681SAndroid Build Coastguard Worker  store atomic i32 %bc1, i32* %ptr release, align 4
962*9880d681SAndroid Build Coastguard Worker  ret void
963*9880d681SAndroid Build Coastguard Worker}
964*9880d681SAndroid Build Coastguard Worker
965*9880d681SAndroid Build Coastguard Workerdefine void @fadd_64stack() {
966*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_64stack:
967*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
968*9880d681SAndroid Build Coastguard Worker; X64:      movsd .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]]
969*9880d681SAndroid Build Coastguard Worker; X64-NEXT: addsd [[STACKOFF:-?[0-9]+]](%rsp), %[[XMM]]
970*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movsd %[[XMM]], [[STACKOFF]](%rsp)
971*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_64stack:
972*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
973*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i64, align 8
974*9880d681SAndroid Build Coastguard Worker  %bc3 = bitcast i64* %ptr to double*
975*9880d681SAndroid Build Coastguard Worker  %load = load atomic i64, i64* %ptr acquire, align 8
976*9880d681SAndroid Build Coastguard Worker  %bc0 = bitcast i64 %load to double
977*9880d681SAndroid Build Coastguard Worker  %fadd = fadd double 1.000000e+00, %bc0
978*9880d681SAndroid Build Coastguard Worker  %bc1 = bitcast double %fadd to i64
979*9880d681SAndroid Build Coastguard Worker  store atomic i64 %bc1, i64* %ptr release, align 8
980*9880d681SAndroid Build Coastguard Worker  ret void
981*9880d681SAndroid Build Coastguard Worker}
982*9880d681SAndroid Build Coastguard Worker
983*9880d681SAndroid Build Coastguard Workerdefine void @fadd_array(i64* %arg, double %arg1, i64 %arg2) {
984*9880d681SAndroid Build Coastguard Worker; X64-LABEL: fadd_array:
985*9880d681SAndroid Build Coastguard Worker; X64-NOT: lock
986*9880d681SAndroid Build Coastguard Worker; X64: addsd ([[ADDR:%r..,%r..,8]]), %[[XMM:xmm[0-9]+]]
987*9880d681SAndroid Build Coastguard Worker; X64-NEXT: movsd %[[XMM]], ([[ADDR]])
988*9880d681SAndroid Build Coastguard Worker; X32-LABEL: fadd_array:
989*9880d681SAndroid Build Coastguard Worker; Don't check x86-32 (see comment above).
990*9880d681SAndroid Build Coastguard Workerbb:
991*9880d681SAndroid Build Coastguard Worker  %tmp4 = getelementptr inbounds i64, i64* %arg, i64 %arg2
992*9880d681SAndroid Build Coastguard Worker  %tmp6 = load atomic i64, i64* %tmp4 monotonic, align 8
993*9880d681SAndroid Build Coastguard Worker  %tmp7 = bitcast i64 %tmp6 to double
994*9880d681SAndroid Build Coastguard Worker  %tmp8 = fadd double %tmp7, %arg1
995*9880d681SAndroid Build Coastguard Worker  %tmp9 = bitcast double %tmp8 to i64
996*9880d681SAndroid Build Coastguard Worker  store atomic i64 %tmp9, i64* %tmp4 monotonic, align 8
997*9880d681SAndroid Build Coastguard Worker  ret void
998*9880d681SAndroid Build Coastguard Worker}
999