1; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LE
2; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-LE
3; RUN: llc < %s -mtriple=armebv7 -target-abi apcs | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BE
4; RUN: llc < %s -mtriple=thumbebv7-none-linux-gnueabihf | FileCheck %s --check-prefix=CHECK-THUMB --check-prefix=CHECK-THUMB-BE
5
6define i64 @test1(i64* %ptr, i64 %val) {
7; CHECK-LABEL: test1:
8; CHECK: dmb {{ish$}}
9; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
10; CHECK-LE: adds [[REG3:(r[0-9]?[02468])]], [[REG1]]
11; CHECK-LE: adc [[REG4:(r[0-9]?[13579])]], [[REG2]]
12; CHECK-BE: adds [[REG4:(r[0-9]?[13579])]], [[REG2]]
13; CHECK-BE: adc [[REG3:(r[0-9]?[02468])]], [[REG1]]
14; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
15; CHECK: cmp
16; CHECK: bne
17; CHECK: dmb {{ish$}}
18
19; CHECK-THUMB-LABEL: test1:
20; CHECK-THUMB: dmb {{ish$}}
21; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
22; CHECK-THUMB-LE: adds.w [[REG3:[a-z0-9]+]], [[REG1]]
23; CHECK-THUMB-LE: adc.w [[REG4:[a-z0-9]+]], [[REG2]]
24; CHECK-THUMB-BE: adds.w [[REG4:[a-z0-9]+]], [[REG2]]
25; CHECK-THUMB-BE: adc.w [[REG3:[a-z0-9]+]], [[REG1]]
26; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
27; CHECK-THUMB: cmp
28; CHECK-THUMB: bne
29; CHECK-THUMB: dmb {{ish$}}
30
31  %r = atomicrmw add i64* %ptr, i64 %val seq_cst
32  ret i64 %r
33}
34
35define i64 @test2(i64* %ptr, i64 %val) {
36; CHECK-LABEL: test2:
37; CHECK: dmb {{ish$}}
38; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
39; CHECK-LE: subs [[REG3:(r[0-9]?[02468])]], [[REG1]]
40; CHECK-LE: sbc [[REG4:(r[0-9]?[13579])]], [[REG2]]
41; CHECK-BE: subs [[REG4:(r[0-9]?[13579])]], [[REG2]]
42; CHECK-BE: sbc [[REG3:(r[0-9]?[02468])]], [[REG1]]
43; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
44; CHECK: cmp
45; CHECK: bne
46; CHECK: dmb {{ish$}}
47
48; CHECK-THUMB-LABEL: test2:
49; CHECK-THUMB: dmb {{ish$}}
50; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
51; CHECK-THUMB-LE: subs.w [[REG3:[a-z0-9]+]], [[REG1]]
52; CHECK-THUMB-LE: sbc.w [[REG4:[a-z0-9]+]], [[REG2]]
53; CHECK-THUMB-BE: subs.w [[REG4:[a-z0-9]+]], [[REG2]]
54; CHECK-THUMB-BE: sbc.w [[REG3:[a-z0-9]+]], [[REG1]]
55; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
56; CHECK-THUMB: cmp
57; CHECK-THUMB: bne
58; CHECK-THUMB: dmb {{ish$}}
59
60  %r = atomicrmw sub i64* %ptr, i64 %val seq_cst
61  ret i64 %r
62}
63
64define i64 @test3(i64* %ptr, i64 %val) {
65; CHECK-LABEL: test3:
66; CHECK: dmb {{ish$}}
67; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
68; CHECK-LE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]]
69; CHECK-LE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]]
70; CHECK-BE-DAG: and [[REG4:(r[0-9]?[13579])]], [[REG2]]
71; CHECK-BE-DAG: and [[REG3:(r[0-9]?[02468])]], [[REG1]]
72; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
73; CHECK: cmp
74; CHECK: bne
75; CHECK: dmb {{ish$}}
76
77; CHECK-THUMB-LABEL: test3:
78; CHECK-THUMB: dmb {{ish$}}
79; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
80; CHECK-THUMB-LE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]]
81; CHECK-THUMB-LE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]]
82; CHECK-THUMB-BE-DAG: and.w [[REG4:[a-z0-9]+]], [[REG2]]
83; CHECK-THUMB-BE-DAG: and.w [[REG3:[a-z0-9]+]], [[REG1]]
84; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
85; CHECK-THUMB: cmp
86; CHECK-THUMB: bne
87; CHECK-THUMB: dmb {{ish$}}
88
89  %r = atomicrmw and i64* %ptr, i64 %val seq_cst
90  ret i64 %r
91}
92
93define i64 @test4(i64* %ptr, i64 %val) {
94; CHECK-LABEL: test4:
95; CHECK: dmb {{ish$}}
96; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
97; CHECK-LE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]]
98; CHECK-LE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]]
99; CHECK-BE-DAG: orr [[REG4:(r[0-9]?[13579])]], [[REG2]]
100; CHECK-BE-DAG: orr [[REG3:(r[0-9]?[02468])]], [[REG1]]
101; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
102; CHECK: cmp
103; CHECK: bne
104; CHECK: dmb {{ish$}}
105
106; CHECK-THUMB-LABEL: test4:
107; CHECK-THUMB: dmb {{ish$}}
108; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
109; CHECK-THUMB-LE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]]
110; CHECK-THUMB-LE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]]
111; CHECK-THUMB-BE-DAG: orr.w [[REG4:[a-z0-9]+]], [[REG2]]
112; CHECK-THUMB-BE-DAG: orr.w [[REG3:[a-z0-9]+]], [[REG1]]
113; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
114; CHECK-THUMB: cmp
115; CHECK-THUMB: bne
116; CHECK-THUMB: dmb {{ish$}}
117
118  %r = atomicrmw or i64* %ptr, i64 %val seq_cst
119  ret i64 %r
120}
121
122define i64 @test5(i64* %ptr, i64 %val) {
123; CHECK-LABEL: test5:
124; CHECK: dmb {{ish$}}
125; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
126; CHECK-LE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]]
127; CHECK-LE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]]
128; CHECK-BE-DAG: eor [[REG4:(r[0-9]?[13579])]], [[REG2]]
129; CHECK-BE-DAG: eor [[REG3:(r[0-9]?[02468])]], [[REG1]]
130; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
131; CHECK: cmp
132; CHECK: bne
133; CHECK: dmb {{ish$}}
134
135; CHECK-THUMB-LABEL: test5:
136; CHECK-THUMB: dmb {{ish$}}
137; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
138; CHECK-THUMB-LE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]]
139; CHECK-THUMB-LE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]]
140; CHECK-THUMB-BE-DAG: eor.w [[REG4:[a-z0-9]+]], [[REG2]]
141; CHECK-THUMB-BE-DAG: eor.w [[REG3:[a-z0-9]+]], [[REG1]]
142; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
143; CHECK-THUMB: cmp
144; CHECK-THUMB: bne
145; CHECK-THUMB: dmb {{ish$}}
146
147  %r = atomicrmw xor i64* %ptr, i64 %val seq_cst
148  ret i64 %r
149}
150
151define i64 @test6(i64* %ptr, i64 %val) {
152; CHECK-LABEL: test6:
153; CHECK: dmb {{ish$}}
154; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
155; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
156; CHECK: cmp
157; CHECK: bne
158; CHECK: dmb {{ish$}}
159
160; CHECK-THUMB-LABEL: test6:
161; CHECK-THUMB: dmb {{ish$}}
162; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
163; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
164; CHECK-THUMB: cmp
165; CHECK-THUMB: bne
166; CHECK-THUMB: dmb {{ish$}}
167
168  %r = atomicrmw xchg i64* %ptr, i64 %val seq_cst
169  ret i64 %r
170}
171
172define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) {
173; CHECK-LABEL: test7:
174; CHECK-DAG: mov [[VAL1LO:r[0-9]+]], r1
175; CHECK-DAG: dmb {{ish$}}
176; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
177; CHECK-LE-DAG: eor     [[MISMATCH_LO:r[0-9]+]], [[REG1]], [[VAL1LO]]
178; CHECK-LE-DAG: eor     [[MISMATCH_HI:r[0-9]+]], [[REG2]], r2
179; CHECK-BE-DAG: eor     [[MISMATCH_LO:r[0-9]+]], [[REG2]], r2
180; CHECK-BE-DAG: eor     [[MISMATCH_HI:r[0-9]+]], [[REG1]], r1
181; CHECK: orrs    {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
182; CHECK: bne
183; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
184; CHECK: cmp
185; CHECK: bne
186; CHECK: dmb {{ish$}}
187
188; CHECK-THUMB-LABEL: test7:
189; CHECK-THUMB: dmb {{ish$}}
190; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
191; CHECK-THUMB-LE-DAG: eor.w     [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2
192; CHECK-THUMB-LE-DAG: eor.w     [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3
193; CHECK-THUMB-BE-DAG: eor.w     [[MISMATCH_HI:[a-z0-9]+]], [[REG1]], r2
194; CHECK-THUMB-BE-DAG: eor.w     [[MISMATCH_LO:[a-z0-9]+]], [[REG2]], r3
195; CHECK-THUMB-LE: orrs    [[MISMATCH_HI]], [[MISMATCH_LO]]
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  %pair = cmpxchg i64* %ptr, i64 %val1, i64 %val2 seq_cst seq_cst
203  %r = extractvalue { i64, i1 } %pair, 0
204  ret i64 %r
205}
206
207; Compiles down to a single ldrexd
208define i64 @test8(i64* %ptr) {
209; CHECK-LABEL: test8:
210; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
211; CHECK: dmb {{ish$}}
212
213; CHECK-THUMB-LABEL: test8:
214; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
215; CHECK-THUMB: dmb {{ish$}}
216
217  %r = load atomic i64* %ptr seq_cst, align 8
218  ret i64 %r
219}
220
221; Compiles down to atomicrmw xchg; there really isn't any more efficient
222; way to write it.
223define void @test9(i64* %ptr, i64 %val) {
224; CHECK-LABEL: test9:
225; CHECK: dmb {{ish$}}
226; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
227; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
228; CHECK: cmp
229; CHECK: bne
230; CHECK: dmb {{ish$}}
231
232; CHECK-THUMB-LABEL: test9:
233; CHECK-THUMB: dmb {{ish$}}
234; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
235; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
236; CHECK-THUMB: cmp
237; CHECK-THUMB: bne
238; CHECK-THUMB: dmb {{ish$}}
239
240  store atomic i64 %val, i64* %ptr seq_cst, align 8
241  ret void
242}
243
244define i64 @test10(i64* %ptr, i64 %val) {
245; CHECK-LABEL: test10:
246; CHECK: dmb {{ish$}}
247; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
248; CHECK: mov     [[CARRY_LO:[a-z0-9]+]], #0
249; CHECK: mov     [[CARRY_HI:[a-z0-9]+]], #0
250; CHECK: mov     [[OUT_HI:[a-z0-9]+]], r2
251; CHECK-LE: cmp     [[REG1]], r1
252; CHECK-BE: cmp     [[REG2]], r2
253; CHECK: movwls  [[CARRY_LO]], #1
254; CHECK-LE: cmp     [[REG2]], r2
255; CHECK-BE: cmp     [[REG1]], r1
256; CHECK: movwle  [[CARRY_HI]], #1
257; CHECK: moveq   [[CARRY_HI]], [[CARRY_LO]]
258; CHECK: cmp     [[CARRY_HI]], #0
259; CHECK: movne   [[OUT_HI]], [[REG2]]
260; CHECK: mov     [[OUT_LO:[a-z0-9]+]], r1
261; CHECK: movne   [[OUT_LO]], [[REG1]]
262; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
263; CHECK: cmp
264; CHECK: bne
265; CHECK: dmb {{ish$}}
266
267; CHECK-THUMB-LABEL: test10:
268; CHECK-THUMB: dmb {{ish$}}
269; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
270; CHECK-THUMB: mov.w     [[CARRY_LO:[a-z0-9]+|lr]], #0
271; CHECK-THUMB: movs     [[CARRY_HI:[a-z0-9]+|lr]], #0
272; CHECK-THUMB-LE: cmp     [[REG1]], r2
273; CHECK-THUMB-BE: cmp     [[REG2]], r3
274; CHECK-THUMB: movls.w  [[CARRY_LO]], #1
275; CHECK-THUMB-LE: cmp     [[REG2]], r3
276; CHECK-THUMB-BE: cmp     [[REG1]], r2
277; CHECK-THUMB: movle  [[CARRY_HI]], #1
278; CHECK-THUMB: moveq   [[CARRY_HI]], [[CARRY_LO]]
279; CHECK-THUMB: mov     [[OUT_HI:[a-z0-9]+]], r3
280; CHECK-THUMB: cmp     [[CARRY_HI]], #0
281; CHECK-THUMB: mov     [[OUT_LO:[a-z0-9]+]], r2
282; CHECK-THUMB: movne   [[OUT_HI]], [[REG2]]
283; CHECK-THUMB: movne   [[OUT_LO]], [[REG1]]
284; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
285; CHECK-THUMB: cmp
286; CHECK-THUMB: bne
287; CHECK-THUMB: dmb {{ish$}}
288
289  %r = atomicrmw min i64* %ptr, i64 %val seq_cst
290  ret i64 %r
291}
292
293define i64 @test11(i64* %ptr, i64 %val) {
294; CHECK-LABEL: test11:
295; CHECK: dmb {{ish$}}
296; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
297; CHECK: mov     [[CARRY_LO:[a-z0-9]+]], #0
298; CHECK: mov     [[CARRY_HI:[a-z0-9]+]], #0
299; CHECK: mov     [[OUT_HI:[a-z0-9]+]], r2
300; CHECK-LE: cmp     [[REG1]], r1
301; CHECK-BE: cmp     [[REG2]], r2
302; CHECK: movwls  [[CARRY_LO]], #1
303; CHECK-LE: cmp     [[REG2]], r2
304; CHECK-BE: cmp     [[REG1]], r1
305; CHECK: movwls  [[CARRY_HI]], #1
306; CHECK: moveq   [[CARRY_HI]], [[CARRY_LO]]
307; CHECK: cmp     [[CARRY_HI]], #0
308; CHECK: movne   [[OUT_HI]], [[REG2]]
309; CHECK: mov     [[OUT_LO:[a-z0-9]+]], r1
310; CHECK: movne   [[OUT_LO]], [[REG1]]
311; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
312; CHECK: cmp
313; CHECK: bne
314; CHECK: dmb {{ish$}}
315
316; CHECK-THUMB-LABEL: test11:
317; CHECK-THUMB: dmb {{ish$}}
318; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
319; CHECK-THUMB: mov.w     [[CARRY_LO:[a-z0-9]+]], #0
320; CHECK-THUMB: movs     [[CARRY_HI:[a-z0-9]+]], #0
321; CHECK-THUMB-LE: cmp     [[REG1]], r2
322; CHECK-THUMB-BE: cmp     [[REG2]], r3
323; CHECK-THUMB: movls.w  [[CARRY_LO]], #1
324; CHECK-THUMB-LE: cmp     [[REG2]], r3
325; CHECK-THUMB-BE: cmp     [[REG1]], r2
326; CHECK-THUMB: movls  [[CARRY_HI]], #1
327; CHECK-THUMB: moveq   [[CARRY_HI]], [[CARRY_LO]]
328; CHECK-THUMB: mov     [[OUT_HI:[a-z0-9]+]], r3
329; CHECK-THUMB: cmp     [[CARRY_HI]], #0
330; CHECK-THUMB: mov     [[OUT_LO:[a-z0-9]+]], r2
331; CHECK-THUMB: movne   [[OUT_HI]], [[REG2]]
332; CHECK-THUMB: movne   [[OUT_LO]], [[REG1]]
333; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
334; CHECK-THUMB: cmp
335; CHECK-THUMB: bne
336; CHECK-THUMB: dmb {{ish$}}
337
338  %r = atomicrmw umin i64* %ptr, i64 %val seq_cst
339  ret i64 %r
340}
341
342define i64 @test12(i64* %ptr, i64 %val) {
343; CHECK-LABEL: test12:
344; CHECK: dmb {{ish$}}
345; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
346; CHECK: mov     [[CARRY_LO:[a-z0-9]+]], #0
347; CHECK: mov     [[CARRY_HI:[a-z0-9]+]], #0
348; CHECK: mov     [[OUT_HI:[a-z0-9]+]], r2
349; CHECK-LE: cmp     [[REG1]], r1
350; CHECK-BE: cmp     [[REG2]], r2
351; CHECK: movwhi  [[CARRY_LO]], #1
352; CHECK-LE: cmp     [[REG2]], r2
353; CHECK-BE: cmp     [[REG1]], r1
354; CHECK: movwgt  [[CARRY_HI]], #1
355; CHECK: moveq   [[CARRY_HI]], [[CARRY_LO]]
356; CHECK: cmp     [[CARRY_HI]], #0
357; CHECK: movne   [[OUT_HI]], [[REG2]]
358; CHECK: mov     [[OUT_LO:[a-z0-9]+]], r1
359; CHECK: movne   [[OUT_LO]], [[REG1]]
360; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
361; CHECK: cmp
362; CHECK: bne
363; CHECK: dmb {{ish$}}
364
365; CHECK-THUMB-LABEL: test12:
366; CHECK-THUMB: dmb {{ish$}}
367; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
368; CHECK-THUMB: mov.w     [[CARRY_LO:[a-z0-9]+]], #0
369; CHECK-THUMB: movs     [[CARRY_HI:[a-z0-9]+]], #0
370; CHECK-THUMB-LE: cmp     [[REG1]], r2
371; CHECK-THUMB-BE: cmp     [[REG2]], r3
372; CHECK-THUMB: movhi.w  [[CARRY_LO]], #1
373; CHECK-THUMB-LE: cmp     [[REG2]], r3
374; CHECK-THUMB-BE: cmp     [[REG1]], r2
375; CHECK-THUMB: movgt  [[CARRY_HI]], #1
376; CHECK-THUMB: moveq   [[CARRY_HI]], [[CARRY_LO]]
377; CHECK-THUMB: mov     [[OUT_HI:[a-z0-9]+]], r3
378; CHECK-THUMB: cmp     [[CARRY_HI]], #0
379; CHECK-THUMB: mov     [[OUT_LO:[a-z0-9]+]], r2
380; CHECK-THUMB: movne   [[OUT_HI]], [[REG2]]
381; CHECK-THUMB: movne   [[OUT_LO]], [[REG1]]
382; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
383; CHECK-THUMB: cmp
384; CHECK-THUMB: bne
385; CHECK-THUMB: dmb {{ish$}}
386
387  %r = atomicrmw max i64* %ptr, i64 %val seq_cst
388  ret i64 %r
389}
390
391define i64 @test13(i64* %ptr, i64 %val) {
392; CHECK-LABEL: test13:
393; CHECK: dmb {{ish$}}
394; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
395; CHECK: mov     [[CARRY_LO:[a-z0-9]+]], #0
396; CHECK: mov     [[CARRY_HI:[a-z0-9]+]], #0
397; CHECK: mov     [[OUT_HI:[a-z0-9]+]], r2
398; CHECK-LE: cmp     [[REG1]], r1
399; CHECK-BE: cmp     [[REG2]], r2
400; CHECK: movwhi  [[CARRY_LO]], #1
401; CHECK-LE: cmp     [[REG2]], r2
402; CHECK-BE: cmp     [[REG1]], r1
403; CHECK: movwhi  [[CARRY_HI]], #1
404; CHECK: moveq   [[CARRY_HI]], [[CARRY_LO]]
405; CHECK: cmp     [[CARRY_HI]], #0
406; CHECK: movne   [[OUT_HI]], [[REG2]]
407; CHECK: mov     [[OUT_LO:[a-z0-9]+]], r1
408; CHECK: movne   [[OUT_LO]], [[REG1]]
409; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
410; CHECK: cmp
411; CHECK: bne
412; CHECK: dmb {{ish$}}
413
414; CHECK-THUMB-LABEL: test13:
415; CHECK-THUMB: dmb {{ish$}}
416; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
417; CHECK-THUMB: mov.w     [[CARRY_LO:[a-z0-9]+]], #0
418; CHECK-THUMB: movs     [[CARRY_HI:[a-z0-9]+]], #0
419; CHECK-THUMB-LE: cmp     [[REG1]], r2
420; CHECK-THUMB-BE: cmp     [[REG2]], r3
421; CHECK-THUMB: movhi.w  [[CARRY_LO]], #1
422; CHECK-THUMB-LE: cmp     [[REG2]], r3
423; CHECK-THUMB-BE: cmp     [[REG1]], r2
424; CHECK-THUMB: movhi  [[CARRY_HI]], #1
425; CHECK-THUMB: moveq   [[CARRY_HI]], [[CARRY_LO]]
426; CHECK-THUMB: mov     [[OUT_HI:[a-z0-9]+]], r3
427; CHECK-THUMB: cmp     [[CARRY_HI]], #0
428; CHECK-THUMB: mov     [[OUT_LO:[a-z0-9]+]], r2
429; CHECK-THUMB: movne   [[OUT_HI]], [[REG2]]
430; CHECK-THUMB: movne   [[OUT_LO]], [[REG1]]
431; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
432; CHECK-THUMB: cmp
433; CHECK-THUMB: bne
434; CHECK-THUMB: dmb {{ish$}}
435  %r = atomicrmw umax i64* %ptr, i64 %val seq_cst
436  ret i64 %r
437}
438
439