• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s
2; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB
3
4define i64 @test1(i64* %ptr, i64 %val) {
5; CHECK: test1:
6; CHECK: dmb ish
7; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
8; CHECK: adds [[REG3:(r[0-9]?[02468])]], [[REG1]]
9; CHECK: adc [[REG4:(r[0-9]?[13579])]], [[REG2]]
10; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
11; CHECK: cmp
12; CHECK: bne
13; CHECK: dmb ish
14
15; CHECK-THUMB: test1:
16; CHECK-THUMB: dmb ish
17; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
18; CHECK-THUMB: adds.w [[REG3:[a-z0-9]+]], [[REG1]]
19; CHECK-THUMB: adc.w [[REG4:[a-z0-9]+]], [[REG2]]
20; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
21; CHECK-THUMB: cmp
22; CHECK-THUMB: bne
23; CHECK-THUMB: dmb ish
24
25  %r = atomicrmw add i64* %ptr, i64 %val seq_cst
26  ret i64 %r
27}
28
29define i64 @test2(i64* %ptr, i64 %val) {
30; CHECK: test2:
31; CHECK: dmb ish
32; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
33; CHECK: subs [[REG3:(r[0-9]?[02468])]], [[REG1]]
34; CHECK: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]]
35; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
36; CHECK: cmp
37; CHECK: bne
38; CHECK: dmb ish
39
40; CHECK-THUMB: test2:
41; CHECK-THUMB: dmb ish
42; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
43; CHECK-THUMB: subs.w [[REG3:[a-z0-9]+]], [[REG1]]
44; CHECK-THUMB: sbc.w [[REG4:[a-z0-9]+]], [[REG2]]
45; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
46; CHECK-THUMB: cmp
47; CHECK-THUMB: bne
48; CHECK-THUMB: dmb ish
49
50  %r = atomicrmw sub i64* %ptr, i64 %val seq_cst
51  ret i64 %r
52}
53
54define i64 @test3(i64* %ptr, i64 %val) {
55; CHECK: test3:
56; CHECK: dmb ish
57; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
58; CHECK: and [[REG3:(r[0-9]?[02468])]], [[REG1]]
59; CHECK: and [[REG4:(r[0-9]?[13579])]], [[REG2]]
60; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
61; CHECK: cmp
62; CHECK: bne
63; CHECK: dmb ish
64
65; CHECK-THUMB: test3:
66; CHECK-THUMB: dmb ish
67; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
68; CHECK-THUMB: and.w [[REG3:[a-z0-9]+]], [[REG1]]
69; CHECK-THUMB: and.w [[REG4:[a-z0-9]+]], [[REG2]]
70; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
71; CHECK-THUMB: cmp
72; CHECK-THUMB: bne
73; CHECK-THUMB: dmb ish
74
75  %r = atomicrmw and i64* %ptr, i64 %val seq_cst
76  ret i64 %r
77}
78
79define i64 @test4(i64* %ptr, i64 %val) {
80; CHECK: test4:
81; CHECK: dmb ish
82; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
83; CHECK: orr [[REG3:(r[0-9]?[02468])]], [[REG1]]
84; CHECK: orr [[REG4:(r[0-9]?[13579])]], [[REG2]]
85; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
86; CHECK: cmp
87; CHECK: bne
88; CHECK: dmb ish
89
90; CHECK-THUMB: test4:
91; CHECK-THUMB: dmb ish
92; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
93; CHECK-THUMB: orr.w [[REG3:[a-z0-9]+]], [[REG1]]
94; CHECK-THUMB: orr.w [[REG4:[a-z0-9]+]], [[REG2]]
95; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
96; CHECK-THUMB: cmp
97; CHECK-THUMB: bne
98; CHECK-THUMB: dmb ish
99
100  %r = atomicrmw or i64* %ptr, i64 %val seq_cst
101  ret i64 %r
102}
103
104define i64 @test5(i64* %ptr, i64 %val) {
105; CHECK: test5:
106; CHECK: dmb ish
107; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
108; CHECK: eor [[REG3:(r[0-9]?[02468])]], [[REG1]]
109; CHECK: eor [[REG4:(r[0-9]?[13579])]], [[REG2]]
110; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
111; CHECK: cmp
112; CHECK: bne
113; CHECK: dmb ish
114
115; CHECK-THUMB: test5:
116; CHECK-THUMB: dmb ish
117; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
118; CHECK-THUMB: eor.w [[REG3:[a-z0-9]+]], [[REG1]]
119; CHECK-THUMB: eor.w [[REG4:[a-z0-9]+]], [[REG2]]
120; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
121; CHECK-THUMB: cmp
122; CHECK-THUMB: bne
123; CHECK-THUMB: dmb ish
124
125  %r = atomicrmw xor i64* %ptr, i64 %val seq_cst
126  ret i64 %r
127}
128
129define i64 @test6(i64* %ptr, i64 %val) {
130; CHECK: test6:
131; CHECK: dmb ish
132; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
133; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
134; CHECK: cmp
135; CHECK: bne
136; CHECK: dmb ish
137
138; CHECK-THUMB: test6:
139; CHECK-THUMB: dmb ish
140; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
141; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
142; CHECK-THUMB: cmp
143; CHECK-THUMB: bne
144; CHECK-THUMB: dmb ish
145
146  %r = atomicrmw xchg i64* %ptr, i64 %val seq_cst
147  ret i64 %r
148}
149
150define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) {
151; CHECK: test7:
152; CHECK: dmb ish
153; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
154; CHECK: cmp [[REG1]]
155; CHECK: cmpeq [[REG2]]
156; CHECK: bne
157; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
158; CHECK: cmp
159; CHECK: bne
160; CHECK: dmb ish
161
162; CHECK-THUMB: test7:
163; CHECK-THUMB: dmb ish
164; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
165; CHECK-THUMB: cmp [[REG1]]
166; CHECK-THUMB: it eq
167; CHECK-THUMB: cmpeq [[REG2]]
168; CHECK-THUMB: bne
169; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
170; CHECK-THUMB: cmp
171; CHECK-THUMB: bne
172; CHECK-THUMB: dmb ish
173
174  %r = cmpxchg i64* %ptr, i64 %val1, i64 %val2 seq_cst
175  ret i64 %r
176}
177
178; Compiles down to cmpxchg
179; FIXME: Should compile to a single ldrexd
180define i64 @test8(i64* %ptr) {
181; CHECK: test8:
182; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
183; CHECK: cmp [[REG1]]
184; CHECK: cmpeq [[REG2]]
185; CHECK: bne
186; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
187; CHECK: cmp
188; CHECK: bne
189; CHECK: dmb ish
190
191; CHECK-THUMB: test8:
192; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
193; CHECK-THUMB: cmp [[REG1]]
194; CHECK-THUMB: it eq
195; CHECK-THUMB: cmpeq [[REG2]]
196; CHECK-THUMB: bne
197; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
198; CHECK-THUMB: cmp
199; CHECK-THUMB: bne
200; CHECK-THUMB: dmb ish
201
202  %r = load atomic i64* %ptr seq_cst, align 8
203  ret i64 %r
204}
205
206; Compiles down to atomicrmw xchg; there really isn't any more efficient
207; way to write it.
208define void @test9(i64* %ptr, i64 %val) {
209; CHECK: test9:
210; CHECK: dmb ish
211; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
212; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
213; CHECK: cmp
214; CHECK: bne
215; CHECK: dmb ish
216
217; CHECK-THUMB: test9:
218; CHECK-THUMB: dmb ish
219; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
220; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
221; CHECK-THUMB: cmp
222; CHECK-THUMB: bne
223; CHECK-THUMB: dmb ish
224
225  store atomic i64 %val, i64* %ptr seq_cst, align 8
226  ret void
227}
228
229define i64 @test10(i64* %ptr, i64 %val) {
230; CHECK: test10:
231; CHECK: dmb ish
232; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
233; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]]
234; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]]
235; CHECK: blt
236; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
237; CHECK: cmp
238; CHECK: bne
239; CHECK: dmb ish
240
241; CHECK-THUMB: test10:
242; CHECK-THUMB: dmb ish
243; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
244; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]]
245; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]]
246; CHECK-THUMB: blt
247; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
248; CHECK-THUMB: cmp
249; CHECK-THUMB: bne
250; CHECK-THUMB: dmb ish
251
252  %r = atomicrmw min i64* %ptr, i64 %val seq_cst
253  ret i64 %r
254}
255
256define i64 @test11(i64* %ptr, i64 %val) {
257; CHECK: test11:
258; CHECK: dmb ish
259; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
260; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]]
261; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]]
262; CHECK: blo
263; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
264; CHECK: cmp
265; CHECK: bne
266; CHECK: dmb ish
267
268
269; CHECK-THUMB: test11:
270; CHECK-THUMB: dmb ish
271; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
272; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]]
273; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]]
274; CHECK-THUMB: blo
275; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
276; CHECK-THUMB: cmp
277; CHECK-THUMB: bne
278; CHECK-THUMB: dmb ish
279
280  %r = atomicrmw umin i64* %ptr, i64 %val seq_cst
281  ret i64 %r
282}
283
284define i64 @test12(i64* %ptr, i64 %val) {
285; CHECK: test12:
286; CHECK: dmb ish
287; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
288; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]]
289; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]]
290; CHECK: bge
291; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
292; CHECK: cmp
293; CHECK: bne
294; CHECK: dmb ish
295
296; CHECK-THUMB: test12:
297; CHECK-THUMB: dmb ish
298; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
299; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]]
300; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]]
301; CHECK-THUMB: bge
302; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
303; CHECK-THUMB: cmp
304; CHECK-THUMB: bne
305; CHECK-THUMB: dmb ish
306
307  %r = atomicrmw max i64* %ptr, i64 %val seq_cst
308  ret i64 %r
309}
310
311define i64 @test13(i64* %ptr, i64 %val) {
312; CHECK: test13:
313; CHECK: dmb ish
314; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
315; CHECK: subs {{[a-z0-9]+}}, [[REG1]], [[REG3:(r[0-9]?[02468])]]
316; CHECK: sbcs {{[a-z0-9]+}}, [[REG2]], [[REG4:(r[0-9]?[13579])]]
317; CHECK: bhs
318; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
319; CHECK: cmp
320; CHECK: bne
321; CHECK: dmb ish
322
323; CHECK-THUMB: test13:
324; CHECK-THUMB: dmb ish
325; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
326; CHECK-THUMB: subs.w {{[a-z0-9]+}}, [[REG1]], [[REG3:[a-z0-9]+]]
327; CHECK-THUMB: sbcs.w {{[a-z0-9]+}}, [[REG2]], [[REG4:[a-z0-9]+]]
328; CHECK-THUMB: bhs
329; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
330; CHECK-THUMB: cmp
331; CHECK-THUMB: bne
332; CHECK-THUMB: dmb ish
333  %r = atomicrmw umax i64* %ptr, i64 %val seq_cst
334  ret i64 %r
335}
336
337