[AArch64] Match base+offset in STNP addressing mode.
[oota-llvm.git] / test / CodeGen / AArch64 / nontemporal.ll
1 ; RUN: llc < %s -mtriple aarch64-apple-darwin -asm-verbose=false | FileCheck %s
2
3 define void @test_stnp_v4i64(<4 x i64>* %p, <4 x i64> %v) #0 {
4 ; CHECK-LABEL: test_stnp_v4i64:
5 ; CHECK-NEXT:  mov d[[HI1:[0-9]+]], v1[1]
6 ; CHECK-NEXT:  mov d[[HI0:[0-9]+]], v0[1]
7 ; CHECK-NEXT:  stnp d1, d[[HI1]], [x0, #16]
8 ; CHECK-NEXT:  stnp d0, d[[HI0]], [x0]
9 ; CHECK-NEXT:  ret
10   store <4 x i64> %v, <4 x i64>* %p, align 1, !nontemporal !0
11   ret void
12 }
13
14 define void @test_stnp_v4i32(<4 x i32>* %p, <4 x i32> %v) #0 {
15 ; CHECK-LABEL: test_stnp_v4i32:
16 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
17 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
18 ; CHECK-NEXT:  ret
19   store <4 x i32> %v, <4 x i32>* %p, align 1, !nontemporal !0
20   ret void
21 }
22
23 define void @test_stnp_v8i16(<8 x i16>* %p, <8 x i16> %v) #0 {
24 ; CHECK-LABEL: test_stnp_v8i16:
25 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
26 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
27 ; CHECK-NEXT:  ret
28   store <8 x i16> %v, <8 x i16>* %p, align 1, !nontemporal !0
29   ret void
30 }
31
32 define void @test_stnp_v16i8(<16 x i8>* %p, <16 x i8> %v) #0 {
33 ; CHECK-LABEL: test_stnp_v16i8:
34 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
35 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
36 ; CHECK-NEXT:  ret
37   store <16 x i8> %v, <16 x i8>* %p, align 1, !nontemporal !0
38   ret void
39 }
40
41 define void @test_stnp_v2i32(<2 x i32>* %p, <2 x i32> %v) #0 {
42 ; CHECK-LABEL: test_stnp_v2i32:
43 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
44 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
45 ; CHECK-NEXT:  ret
46   store <2 x i32> %v, <2 x i32>* %p, align 1, !nontemporal !0
47   ret void
48 }
49
50 define void @test_stnp_v4i16(<4 x i16>* %p, <4 x i16> %v) #0 {
51 ; CHECK-LABEL: test_stnp_v4i16:
52 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
53 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
54 ; CHECK-NEXT:  ret
55   store <4 x i16> %v, <4 x i16>* %p, align 1, !nontemporal !0
56   ret void
57 }
58
59 define void @test_stnp_v8i8(<8 x i8>* %p, <8 x i8> %v) #0 {
60 ; CHECK-LABEL: test_stnp_v8i8:
61 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
62 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
63 ; CHECK-NEXT:  ret
64   store <8 x i8> %v, <8 x i8>* %p, align 1, !nontemporal !0
65   ret void
66 }
67
68 define void @test_stnp_v2f64(<2 x double>* %p, <2 x double> %v) #0 {
69 ; CHECK-LABEL: test_stnp_v2f64:
70 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
71 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
72 ; CHECK-NEXT:  ret
73   store <2 x double> %v, <2 x double>* %p, align 1, !nontemporal !0
74   ret void
75 }
76
77 define void @test_stnp_v4f32(<4 x float>* %p, <4 x float> %v) #0 {
78 ; CHECK-LABEL: test_stnp_v4f32:
79 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
80 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0]
81 ; CHECK-NEXT:  ret
82   store <4 x float> %v, <4 x float>* %p, align 1, !nontemporal !0
83   ret void
84 }
85
86 define void @test_stnp_v2f32(<2 x float>* %p, <2 x float> %v) #0 {
87 ; CHECK-LABEL: test_stnp_v2f32:
88 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
89 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
90 ; CHECK-NEXT:  ret
91   store <2 x float> %v, <2 x float>* %p, align 1, !nontemporal !0
92   ret void
93 }
94
95 define void @test_stnp_v1f64(<1 x double>* %p, <1 x double> %v) #0 {
96 ; CHECK-LABEL: test_stnp_v1f64:
97 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
98 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
99 ; CHECK-NEXT:  ret
100   store <1 x double> %v, <1 x double>* %p, align 1, !nontemporal !0
101   ret void
102 }
103
104 define void @test_stnp_v1i64(<1 x i64>* %p, <1 x i64> %v) #0 {
105 ; CHECK-LABEL: test_stnp_v1i64:
106 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
107 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0]
108 ; CHECK-NEXT:  ret
109   store <1 x i64> %v, <1 x i64>* %p, align 1, !nontemporal !0
110   ret void
111 }
112
113 define void @test_stnp_i64(i64* %p, i64 %v) #0 {
114 ; CHECK-LABEL: test_stnp_i64:
115 ; CHECK-NEXT:  ubfx x[[HI:[0-9]+]], x1, #0, #32
116 ; CHECK-NEXT:  stnp w1, w[[HI]], [x0]
117 ; CHECK-NEXT:  ret
118   store i64 %v, i64* %p, align 1, !nontemporal !0
119   ret void
120 }
121
122
123 define void @test_stnp_v2f64_offset(<2 x double>* %p, <2 x double> %v) #0 {
124 ; CHECK-LABEL: test_stnp_v2f64_offset:
125 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
126 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #16]
127 ; CHECK-NEXT:  ret
128   %tmp0 = getelementptr <2 x double>, <2 x double>* %p, i32 1
129   store <2 x double> %v, <2 x double>* %tmp0, align 1, !nontemporal !0
130   ret void
131 }
132
133 define void @test_stnp_v2f64_offset_neg(<2 x double>* %p, <2 x double> %v) #0 {
134 ; CHECK-LABEL: test_stnp_v2f64_offset_neg:
135 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
136 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #-16]
137 ; CHECK-NEXT:  ret
138   %tmp0 = getelementptr <2 x double>, <2 x double>* %p, i32 -1
139   store <2 x double> %v, <2 x double>* %tmp0, align 1, !nontemporal !0
140   ret void
141 }
142
143 define void @test_stnp_v2f32_offset(<2 x float>* %p, <2 x float> %v) #0 {
144 ; CHECK-LABEL: test_stnp_v2f32_offset:
145 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
146 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #8]
147 ; CHECK-NEXT:  ret
148   %tmp0 = getelementptr <2 x float>, <2 x float>* %p, i32 1
149   store <2 x float> %v, <2 x float>* %tmp0, align 1, !nontemporal !0
150   ret void
151 }
152
153 define void @test_stnp_v2f32_offset_neg(<2 x float>* %p, <2 x float> %v) #0 {
154 ; CHECK-LABEL: test_stnp_v2f32_offset_neg:
155 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
156 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #-8]
157 ; CHECK-NEXT:  ret
158   %tmp0 = getelementptr <2 x float>, <2 x float>* %p, i32 -1
159   store <2 x float> %v, <2 x float>* %tmp0, align 1, !nontemporal !0
160   ret void
161 }
162
163 define void @test_stnp_i64_offset(i64* %p, i64 %v) #0 {
164 ; CHECK-LABEL: test_stnp_i64_offset:
165 ; CHECK-NEXT:  ubfx x[[HI:[0-9]+]], x1, #0, #32
166 ; CHECK-NEXT:  stnp w1, w[[HI]], [x0, #8]
167 ; CHECK-NEXT:  ret
168   %tmp0 = getelementptr i64, i64* %p, i32 1
169   store i64 %v, i64* %tmp0, align 1, !nontemporal !0
170   ret void
171 }
172
173 define void @test_stnp_i64_offset_neg(i64* %p, i64 %v) #0 {
174 ; CHECK-LABEL: test_stnp_i64_offset_neg:
175 ; CHECK-NEXT:  ubfx x[[HI:[0-9]+]], x1, #0, #32
176 ; CHECK-NEXT:  stnp w1, w[[HI]], [x0, #-8]
177 ; CHECK-NEXT:  ret
178   %tmp0 = getelementptr i64, i64* %p, i32 -1
179   store i64 %v, i64* %tmp0, align 1, !nontemporal !0
180   ret void
181 }
182
183 define void @test_stnp_v4f32_invalid_offset_4(i8* %p, <4 x float> %v) #0 {
184 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_4:
185 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #4
186 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
187 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
188 ; CHECK-NEXT:  ret
189   %tmp0 = getelementptr i8, i8* %p, i32 4
190   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
191   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
192   ret void
193 }
194
195 define void @test_stnp_v4f32_invalid_offset_neg_4(i8* %p, <4 x float> %v) #0 {
196 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_neg_4:
197 ; CHECK-NEXT:  sub x[[PTR:[0-9]+]], x0, #4
198 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
199 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
200 ; CHECK-NEXT:  ret
201   %tmp0 = getelementptr i8, i8* %p, i32 -4
202   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
203   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
204   ret void
205 }
206
207 define void @test_stnp_v4f32_invalid_offset_512(i8* %p, <4 x float> %v) #0 {
208 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_512:
209 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #512
210 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
211 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
212 ; CHECK-NEXT:  ret
213   %tmp0 = getelementptr i8, i8* %p, i32 512
214   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
215   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
216   ret void
217 }
218
219 define void @test_stnp_v4f32_offset_504(i8* %p, <4 x float> %v) #0 {
220 ; CHECK-LABEL: test_stnp_v4f32_offset_504:
221 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
222 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #504]
223 ; CHECK-NEXT:  ret
224   %tmp0 = getelementptr i8, i8* %p, i32 504
225   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
226   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
227   ret void
228 }
229
230 define void @test_stnp_v4f32_invalid_offset_508(i8* %p, <4 x float> %v) #0 {
231 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_508:
232 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #508
233 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
234 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
235 ; CHECK-NEXT:  ret
236   %tmp0 = getelementptr i8, i8* %p, i32 508
237   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
238   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
239   ret void
240 }
241
242 define void @test_stnp_v4f32_invalid_offset_neg_520(i8* %p, <4 x float> %v) #0 {
243 ; CHECK-LABEL: test_stnp_v4f32_invalid_offset_neg_520:
244 ; CHECK-NEXT:  sub x[[PTR:[0-9]+]], x0, #520
245 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
246 ; CHECK-NEXT:  stnp d0, d[[HI]], [x[[PTR]]]
247 ; CHECK-NEXT:  ret
248   %tmp0 = getelementptr i8, i8* %p, i32 -520
249   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
250   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
251   ret void
252 }
253
254 define void @test_stnp_v4f32_offset_neg_512(i8* %p, <4 x float> %v) #0 {
255 ; CHECK-LABEL: test_stnp_v4f32_offset_neg_512:
256 ; CHECK-NEXT:  mov d[[HI:[0-9]+]], v0[1]
257 ; CHECK-NEXT:  stnp d0, d[[HI]], [x0, #-512]
258 ; CHECK-NEXT:  ret
259   %tmp0 = getelementptr i8, i8* %p, i32 -512
260   %tmp1 = bitcast i8* %tmp0 to <4 x float>*
261   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
262   ret void
263 }
264
265
266 define void @test_stnp_v2f32_invalid_offset_256(i8* %p, <2 x float> %v) #0 {
267 ; CHECK-LABEL: test_stnp_v2f32_invalid_offset_256:
268 ; CHECK-NEXT:  add x[[PTR:[0-9]+]], x0, #256
269 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
270 ; CHECK-NEXT:  stnp s0, s[[HI]], [x[[PTR]]]
271 ; CHECK-NEXT:  ret
272   %tmp0 = getelementptr i8, i8* %p, i32 256
273   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
274   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
275   ret void
276 }
277
278 define void @test_stnp_v2f32_offset_252(i8* %p, <2 x float> %v) #0 {
279 ; CHECK-LABEL: test_stnp_v2f32_offset_252:
280 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
281 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #252]
282 ; CHECK-NEXT:  ret
283   %tmp0 = getelementptr i8, i8* %p, i32 252
284   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
285   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
286   ret void
287 }
288
289 define void @test_stnp_v2f32_invalid_offset_neg_260(i8* %p, <2 x float> %v) #0 {
290 ; CHECK-LABEL: test_stnp_v2f32_invalid_offset_neg_260:
291 ; CHECK-NEXT:  sub x[[PTR:[0-9]+]], x0, #260
292 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
293 ; CHECK-NEXT:  stnp s0, s[[HI]], [x[[PTR]]]
294 ; CHECK-NEXT:  ret
295   %tmp0 = getelementptr i8, i8* %p, i32 -260
296   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
297   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
298   ret void
299 }
300
301 define void @test_stnp_v2f32_offset_neg_256(i8* %p, <2 x float> %v) #0 {
302 ; CHECK-LABEL: test_stnp_v2f32_offset_neg_256:
303 ; CHECK-NEXT:  mov s[[HI:[0-9]+]], v0[1]
304 ; CHECK-NEXT:  stnp s0, s[[HI]], [x0, #-256]
305 ; CHECK-NEXT:  ret
306   %tmp0 = getelementptr i8, i8* %p, i32 -256
307   %tmp1 = bitcast i8* %tmp0 to <2 x float>*
308   store <2 x float> %v, <2 x float>* %tmp1, align 1, !nontemporal !0
309   ret void
310 }
311
312 declare void @dummy(<4 x float>*)
313
314 define void @test_stnp_v4f32_offset_alloca(<4 x float> %v) #0 {
315 ; CHECK-LABEL: test_stnp_v4f32_offset_alloca:
316 ; CHECK:       mov x29, sp
317 ; CHECK:       mov x[[PTR:[0-9]+]], sp
318 ; CHECK-NEXT:  stnp d0, d{{.*}}, [x[[PTR]]]
319 ; CHECK-NEXT:  mov x0, sp
320 ; CHECK-NEXT:  bl _dummy
321   %tmp0 = alloca <4 x float>
322   store <4 x float> %v, <4 x float>* %tmp0, align 1, !nontemporal !0
323   call void @dummy(<4 x float>* %tmp0)
324   ret void
325 }
326
327 define void @test_stnp_v4f32_offset_alloca_2(<4 x float> %v) #0 {
328 ; CHECK-LABEL: test_stnp_v4f32_offset_alloca_2:
329 ; CHECK:       mov x29, sp
330 ; CHECK:       mov x[[PTR:[0-9]+]], sp
331 ; CHECK-NEXT:  stnp d0, d{{.*}}, [x[[PTR]], #16]
332 ; CHECK-NEXT:  mov x0, sp
333 ; CHECK-NEXT:  bl _dummy
334   %tmp0 = alloca <4 x float>, i32 2
335   %tmp1 = getelementptr <4 x float>, <4 x float>* %tmp0, i32 1
336   store <4 x float> %v, <4 x float>* %tmp1, align 1, !nontemporal !0
337   call void @dummy(<4 x float>* %tmp0)
338   ret void
339 }
340
341 !0 = !{ i32 1 }
342
343 attributes #0 = { nounwind }