1; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s
2
3define i64 @test1(i64* %ptr, i64 %val) {
4; CHECK: test1
5; CHECK: dmb ish
6; CHECK: ldrexd r2, r3
7; CHECK: adds r0, r2
8; CHECK: adc r1, r3
9; CHECK: strexd {{[a-z0-9]+}}, r0, r1
10; CHECK: cmp
11; CHECK: bne
12; CHECK: dmb ish
13  %r = atomicrmw add i64* %ptr, i64 %val seq_cst
14  ret i64 %r
15}
16
17define i64 @test2(i64* %ptr, i64 %val) {
18; CHECK: test2
19; CHECK: dmb ish
20; CHECK: ldrexd r2, r3
21; CHECK: subs r0, r2
22; CHECK: sbc r1, r3
23; CHECK: strexd {{[a-z0-9]+}}, r0, r1
24; CHECK: cmp
25; CHECK: bne
26; CHECK: dmb ish
27  %r = atomicrmw sub i64* %ptr, i64 %val seq_cst
28  ret i64 %r
29}
30
31define i64 @test3(i64* %ptr, i64 %val) {
32; CHECK: test3
33; CHECK: dmb ish
34; CHECK: ldrexd r2, r3
35; CHECK: and r0, r2
36; CHECK: and r1, r3
37; CHECK: strexd {{[a-z0-9]+}}, r0, r1
38; CHECK: cmp
39; CHECK: bne
40; CHECK: dmb ish
41  %r = atomicrmw and i64* %ptr, i64 %val seq_cst
42  ret i64 %r
43}
44
45define i64 @test4(i64* %ptr, i64 %val) {
46; CHECK: test4
47; CHECK: dmb ish
48; CHECK: ldrexd r2, r3
49; CHECK: orr r0, r2
50; CHECK: orr r1, r3
51; CHECK: strexd {{[a-z0-9]+}}, r0, r1
52; CHECK: cmp
53; CHECK: bne
54; CHECK: dmb ish
55  %r = atomicrmw or i64* %ptr, i64 %val seq_cst
56  ret i64 %r
57}
58
59define i64 @test5(i64* %ptr, i64 %val) {
60; CHECK: test5
61; CHECK: dmb ish
62; CHECK: ldrexd r2, r3
63; CHECK: eor r0, r2
64; CHECK: eor r1, r3
65; CHECK: strexd {{[a-z0-9]+}}, r0, r1
66; CHECK: cmp
67; CHECK: bne
68; CHECK: dmb ish
69  %r = atomicrmw xor i64* %ptr, i64 %val seq_cst
70  ret i64 %r
71}
72
73define i64 @test6(i64* %ptr, i64 %val) {
74; CHECK: test6
75; CHECK: dmb ish
76; CHECK: ldrexd r2, r3
77; CHECK: strexd {{[a-z0-9]+}}, r0, r1
78; CHECK: cmp
79; CHECK: bne
80; CHECK: dmb ish
81  %r = atomicrmw xchg i64* %ptr, i64 %val seq_cst
82  ret i64 %r
83}
84
85define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) {
86; CHECK: test7
87; CHECK: dmb ish
88; CHECK: ldrexd r2, r3
89; CHECK: cmp r2
90; CHECK: cmpeq r3
91; CHECK: bne
92; CHECK: strexd {{[a-z0-9]+}}, r0, r1
93; CHECK: cmp
94; CHECK: bne
95; CHECK: dmb ish
96  %r = cmpxchg i64* %ptr, i64 %val1, i64 %val2 seq_cst
97  ret i64 %r
98}
99
100; Compiles down to cmpxchg
101; FIXME: Should compile to a single ldrexd
102define i64 @test8(i64* %ptr) {
103; CHECK: test8
104; CHECK: ldrexd r2, r3
105; CHECK: cmp r2
106; CHECK: cmpeq r3
107; CHECK: bne
108; CHECK: strexd {{[a-z0-9]+}}, r0, r1
109; CHECK: cmp
110; CHECK: bne
111; CHECK: dmb ish
112  %r = load atomic i64* %ptr seq_cst, align 8
113  ret i64 %r
114}
115
116; Compiles down to atomicrmw xchg; there really isn't any more efficient
117; way to write it.
118define void @test9(i64* %ptr, i64 %val) {
119; CHECK: test9
120; CHECK: dmb ish
121; CHECK: ldrexd r2, r3
122; CHECK: strexd {{[a-z0-9]+}}, r0, r1
123; CHECK: cmp
124; CHECK: bne
125; CHECK: dmb ish
126  store atomic i64 %val, i64* %ptr seq_cst, align 8
127  ret void
128}
129