1; RUN: llc -mtriple=aarch64-- -O0 -fast-isel -fast-isel-abort=4 -verify-machineinstrs < %s | FileCheck %s
2; RUN: llc -mtriple=aarch64-- -O0 -fast-isel=0 -global-isel=false -verify-machineinstrs < %s | FileCheck %s
3
4; Note that checking SelectionDAG output isn't strictly necessary, but they
5; currently match, so we might as well check both!  Feel free to remove SDAG.
6
7; CHECK-LABEL: atomic_store_monotonic_8:
8; CHECK-NEXT: // %bb.0:
9; CHECK-NEXT:  strb  w1, [x0]
10; CHECK-NEXT:  ret
11define void @atomic_store_monotonic_8(i8* %p, i8 %val) #0 {
12  store atomic i8 %val, i8* %p monotonic, align 1
13  ret void
14}
15
16; CHECK-LABEL: atomic_store_monotonic_8_off:
17; CHECK-NEXT: // %bb.0:
18; CHECK-NEXT:  strb w1, [x0, #1]
19; CHECK-NEXT:  ret
20define void @atomic_store_monotonic_8_off(i8* %p, i8 %val) #0 {
21  %tmp0 = getelementptr i8, i8* %p, i32 1
22  store atomic i8 %val, i8* %tmp0 monotonic, align 1
23  ret void
24}
25
26; CHECK-LABEL: atomic_store_monotonic_16:
27; CHECK-NEXT: // %bb.0:
28; CHECK-NEXT:  strh  w1, [x0]
29; CHECK-NEXT:  ret
30define void @atomic_store_monotonic_16(i16* %p, i16 %val) #0 {
31  store atomic i16 %val, i16* %p monotonic, align 2
32  ret void
33}
34
35; CHECK-LABEL: atomic_store_monotonic_16_off:
36; CHECK-NEXT: // %bb.0:
37; CHECK-NEXT:  strh w1, [x0, #2]
38; CHECK-NEXT:  ret
39define void @atomic_store_monotonic_16_off(i16* %p, i16 %val) #0 {
40  %tmp0 = getelementptr i16, i16* %p, i32 1
41  store atomic i16 %val, i16* %tmp0 monotonic, align 2
42  ret void
43}
44
45; CHECK-LABEL: atomic_store_monotonic_32:
46; CHECK-NEXT: // %bb.0:
47; CHECK-NEXT:  str  w1, [x0]
48; CHECK-NEXT:  ret
49define void @atomic_store_monotonic_32(i32* %p, i32 %val) #0 {
50  store atomic i32 %val, i32* %p monotonic, align 4
51  ret void
52}
53
54; CHECK-LABEL: atomic_store_monotonic_32_off:
55; CHECK-NEXT: // %bb.0:
56; CHECK-NEXT:  str w1, [x0, #4]
57; CHECK-NEXT:  ret
58define void @atomic_store_monotonic_32_off(i32* %p, i32 %val) #0 {
59  %tmp0 = getelementptr i32, i32* %p, i32 1
60  store atomic i32 %val, i32* %tmp0 monotonic, align 4
61  ret void
62}
63
64; CHECK-LABEL: atomic_store_monotonic_64:
65; CHECK-NEXT: // %bb.0:
66; CHECK-NEXT:  str  x1, [x0]
67; CHECK-NEXT:  ret
68define void @atomic_store_monotonic_64(i64* %p, i64 %val) #0 {
69  store atomic i64 %val, i64* %p monotonic, align 8
70  ret void
71}
72
73; CHECK-LABEL: atomic_store_monotonic_64_off:
74; CHECK-NEXT: // %bb.0:
75; CHECK-NEXT:  str x1, [x0, #8]
76; CHECK-NEXT:  ret
77define void @atomic_store_monotonic_64_off(i64* %p, i64 %val) #0 {
78  %tmp0 = getelementptr i64, i64* %p, i32 1
79  store atomic i64 %val, i64* %tmp0 monotonic, align 8
80  ret void
81}
82
83; CHECK-LABEL: atomic_store_release_8:
84; CHECK-NEXT: // %bb.0:
85; CHECK-NEXT:  stlrb w1, [x0]
86; CHECK-NEXT:  ret
87define void @atomic_store_release_8(i8* %p, i8 %val) #0 {
88  store atomic i8 %val, i8* %p release, align 1
89  ret void
90}
91
92; CHECK-LABEL: atomic_store_release_8_off:
93; CHECK-NEXT: // %bb.0:
94; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #1
95; CHECK-NEXT:  stlrb w1, {{\[}}[[REG0]]]
96; CHECK-NEXT:  ret
97define void @atomic_store_release_8_off(i8* %p, i8 %val) #0 {
98  %tmp0 = getelementptr i8, i8* %p, i32 1
99  store atomic i8 %val, i8* %tmp0 release, align 1
100  ret void
101}
102
103; CHECK-LABEL: atomic_store_release_16:
104; CHECK-NEXT: // %bb.0:
105; CHECK-NEXT:  stlrh w1, [x0]
106; CHECK-NEXT:  ret
107define void @atomic_store_release_16(i16* %p, i16 %val) #0 {
108  store atomic i16 %val, i16* %p release, align 2
109  ret void
110}
111
112; CHECK-LABEL: atomic_store_release_16_off:
113; CHECK-NEXT: // %bb.0:
114; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #2
115; CHECK-NEXT:  stlrh w1, {{\[}}[[REG0]]]
116; CHECK-NEXT:  ret
117define void @atomic_store_release_16_off(i16* %p, i16 %val) #0 {
118  %tmp0 = getelementptr i16, i16* %p, i32 1
119  store atomic i16 %val, i16* %tmp0 release, align 2
120  ret void
121}
122
123; CHECK-LABEL: atomic_store_release_32:
124; CHECK-NEXT: // %bb.0:
125; CHECK-NEXT:  stlr w1, [x0]
126; CHECK-NEXT:  ret
127define void @atomic_store_release_32(i32* %p, i32 %val) #0 {
128  store atomic i32 %val, i32* %p release, align 4
129  ret void
130}
131
132; CHECK-LABEL: atomic_store_release_32_off:
133; CHECK-NEXT: // %bb.0:
134; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #4
135; CHECK-NEXT:  stlr w1, {{\[}}[[REG0]]]
136; CHECK-NEXT:  ret
137define void @atomic_store_release_32_off(i32* %p, i32 %val) #0 {
138  %tmp0 = getelementptr i32, i32* %p, i32 1
139  store atomic i32 %val, i32* %tmp0 release, align 4
140  ret void
141}
142
143; CHECK-LABEL: atomic_store_release_64:
144; CHECK-NEXT: // %bb.0:
145; CHECK-NEXT:  stlr x1, [x0]
146; CHECK-NEXT:  ret
147define void @atomic_store_release_64(i64* %p, i64 %val) #0 {
148  store atomic i64 %val, i64* %p release, align 8
149  ret void
150}
151
152; CHECK-LABEL: atomic_store_release_64_off:
153; CHECK-NEXT: // %bb.0:
154; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #8
155; CHECK-NEXT:  stlr x1, {{\[}}[[REG0]]]
156; CHECK-NEXT:  ret
157define void @atomic_store_release_64_off(i64* %p, i64 %val) #0 {
158  %tmp0 = getelementptr i64, i64* %p, i32 1
159  store atomic i64 %val, i64* %tmp0 release, align 8
160  ret void
161}
162
163
164; CHECK-LABEL: atomic_store_seq_cst_8:
165; CHECK-NEXT: // %bb.0:
166; CHECK-NEXT:  stlrb w1, [x0]
167; CHECK-NEXT:  ret
168define void @atomic_store_seq_cst_8(i8* %p, i8 %val) #0 {
169  store atomic i8 %val, i8* %p seq_cst, align 1
170  ret void
171}
172
173; CHECK-LABEL: atomic_store_seq_cst_8_off:
174; CHECK-NEXT: // %bb.0:
175; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #1
176; CHECK-NEXT:  stlrb w1, {{\[}}[[REG0]]]
177; CHECK-NEXT:  ret
178define void @atomic_store_seq_cst_8_off(i8* %p, i8 %val) #0 {
179  %tmp0 = getelementptr i8, i8* %p, i32 1
180  store atomic i8 %val, i8* %tmp0 seq_cst, align 1
181  ret void
182}
183
184; CHECK-LABEL: atomic_store_seq_cst_16:
185; CHECK-NEXT: // %bb.0:
186; CHECK-NEXT:  stlrh w1, [x0]
187; CHECK-NEXT:  ret
188define void @atomic_store_seq_cst_16(i16* %p, i16 %val) #0 {
189  store atomic i16 %val, i16* %p seq_cst, align 2
190  ret void
191}
192
193; CHECK-LABEL: atomic_store_seq_cst_16_off:
194; CHECK-NEXT: // %bb.0:
195; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #2
196; CHECK-NEXT:  stlrh w1, {{\[}}[[REG0]]]
197; CHECK-NEXT:  ret
198define void @atomic_store_seq_cst_16_off(i16* %p, i16 %val) #0 {
199  %tmp0 = getelementptr i16, i16* %p, i32 1
200  store atomic i16 %val, i16* %tmp0 seq_cst, align 2
201  ret void
202}
203
204; CHECK-LABEL: atomic_store_seq_cst_32:
205; CHECK-NEXT: // %bb.0:
206; CHECK-NEXT:  stlr w1, [x0]
207; CHECK-NEXT:  ret
208define void @atomic_store_seq_cst_32(i32* %p, i32 %val) #0 {
209  store atomic i32 %val, i32* %p seq_cst, align 4
210  ret void
211}
212
213; CHECK-LABEL: atomic_store_seq_cst_32_off:
214; CHECK-NEXT: // %bb.0:
215; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #4
216; CHECK-NEXT:  stlr w1, {{\[}}[[REG0]]]
217; CHECK-NEXT:  ret
218define void @atomic_store_seq_cst_32_off(i32* %p, i32 %val) #0 {
219  %tmp0 = getelementptr i32, i32* %p, i32 1
220  store atomic i32 %val, i32* %tmp0 seq_cst, align 4
221  ret void
222}
223
224; CHECK-LABEL: atomic_store_seq_cst_64:
225; CHECK-NEXT: // %bb.0:
226; CHECK-NEXT:  stlr x1, [x0]
227; CHECK-NEXT:  ret
228define void @atomic_store_seq_cst_64(i64* %p, i64 %val) #0 {
229  store atomic i64 %val, i64* %p seq_cst, align 8
230  ret void
231}
232
233; CHECK-LABEL: atomic_store_seq_cst_64_off:
234; CHECK-NEXT: // %bb.0:
235; CHECK-NEXT:  add [[REG0:x[0-9]+]], x0, #8
236; CHECK-NEXT:  stlr x1, {{\[}}[[REG0]]]
237; CHECK-NEXT:  ret
238define void @atomic_store_seq_cst_64_off(i64* %p, i64 %val) #0 {
239  %tmp0 = getelementptr i64, i64* %p, i32 1
240  store atomic i64 %val, i64* %tmp0 seq_cst, align 8
241  ret void
242}
243
244attributes #0 = { nounwind }
245