1 ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
3 define void @vst1lanei8(i8* %A, <8 x i8>* %B) nounwind {
5 ;Check the (default) alignment.
6 ;CHECK: vst1.8 {d16[3]}, [r0]
7 %tmp1 = load <8 x i8>* %B
8 %tmp2 = extractelement <8 x i8> %tmp1, i32 3
9 store i8 %tmp2, i8* %A, align 8
13 ;Check for a post-increment updating store.
14 define void @vst1lanei8_update(i8** %ptr, <8 x i8>* %B) nounwind {
15 ;CHECK: vst1lanei8_update:
16 ;CHECK: vst1.8 {d16[3]}, [r2]!
18 %tmp1 = load <8 x i8>* %B
19 %tmp2 = extractelement <8 x i8> %tmp1, i32 3
20 store i8 %tmp2, i8* %A, align 8
21 %tmp3 = getelementptr i8* %A, i32 1
22 store i8* %tmp3, i8** %ptr
26 define void @vst1lanei16(i16* %A, <4 x i16>* %B) nounwind {
28 ;Check the alignment value. Max for this instruction is 16 bits:
29 ;CHECK: vst1.16 {d16[2]}, [r0, :16]
30 %tmp1 = load <4 x i16>* %B
31 %tmp2 = extractelement <4 x i16> %tmp1, i32 2
32 store i16 %tmp2, i16* %A, align 8
36 define void @vst1lanei32(i32* %A, <2 x i32>* %B) nounwind {
38 ;Check the alignment value. Max for this instruction is 32 bits:
39 ;CHECK: vst1.32 {d16[1]}, [r0, :32]
40 %tmp1 = load <2 x i32>* %B
41 %tmp2 = extractelement <2 x i32> %tmp1, i32 1
42 store i32 %tmp2, i32* %A, align 8
46 define void @vst1lanef(float* %A, <2 x float>* %B) nounwind {
48 ;CHECK: vst1.32 {d16[1]}, [r0]
49 %tmp1 = load <2 x float>* %B
50 %tmp2 = extractelement <2 x float> %tmp1, i32 1
51 store float %tmp2, float* %A
55 define void @vst1laneQi8(i8* %A, <16 x i8>* %B) nounwind {
57 ; // Can use scalar load. No need to use vectors.
58 ; // CHE-CK: vst1.8 {d17[1]}, [r0]
59 %tmp1 = load <16 x i8>* %B
60 %tmp2 = extractelement <16 x i8> %tmp1, i32 9
61 store i8 %tmp2, i8* %A, align 8
65 define void @vst1laneQi16(i16* %A, <8 x i16>* %B) nounwind {
67 ;CHECK: vst1.16 {d17[1]}, [r0, :16]
68 %tmp1 = load <8 x i16>* %B
69 %tmp2 = extractelement <8 x i16> %tmp1, i32 5
70 store i16 %tmp2, i16* %A, align 8
74 define void @vst1laneQi32(i32* %A, <4 x i32>* %B) nounwind {
76 ; // Can use scalar load. No need to use vectors.
77 ; // CHE-CK: vst1.32 {d17[1]}, [r0, :32]
78 %tmp1 = load <4 x i32>* %B
79 %tmp2 = extractelement <4 x i32> %tmp1, i32 3
80 store i32 %tmp2, i32* %A, align 8
84 ;Check for a post-increment updating store.
85 define void @vst1laneQi32_update(i32** %ptr, <4 x i32>* %B) nounwind {
86 ;CHECK: vst1laneQi32_update:
87 ; // Can use scalar load. No need to use vectors.
88 ; // CHE-CK: vst1.32 {d17[1]}, [r1, :32]!
90 %tmp1 = load <4 x i32>* %B
91 %tmp2 = extractelement <4 x i32> %tmp1, i32 3
92 store i32 %tmp2, i32* %A, align 8
93 %tmp3 = getelementptr i32* %A, i32 1
94 store i32* %tmp3, i32** %ptr
98 define void @vst1laneQf(float* %A, <4 x float>* %B) nounwind {
100 ; // Can use scalar load. No need to use vectors.
101 ; // CHE-CK: vst1.32 {d17[1]}, [r0]
102 %tmp1 = load <4 x float>* %B
103 %tmp2 = extractelement <4 x float> %tmp1, i32 3
104 store float %tmp2, float* %A
108 define void @vst2lanei8(i8* %A, <8 x i8>* %B) nounwind {
110 ;Check the alignment value. Max for this instruction is 16 bits:
111 ;CHECK: vst2.8 {d16[1], d17[1]}, [r0, :16]
112 %tmp1 = load <8 x i8>* %B
113 call void @llvm.arm.neon.vst2lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 4)
117 define void @vst2lanei16(i16* %A, <4 x i16>* %B) nounwind {
119 ;Check the alignment value. Max for this instruction is 32 bits:
120 ;CHECK: vst2.16 {d16[1], d17[1]}, [r0, :32]
121 %tmp0 = bitcast i16* %A to i8*
122 %tmp1 = load <4 x i16>* %B
123 call void @llvm.arm.neon.vst2lane.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 8)
127 ;Check for a post-increment updating store with register increment.
128 define void @vst2lanei16_update(i16** %ptr, <4 x i16>* %B, i32 %inc) nounwind {
129 ;CHECK: vst2lanei16_update:
130 ;CHECK: vst2.16 {d16[1], d17[1]}, [r1], r2
132 %tmp0 = bitcast i16* %A to i8*
133 %tmp1 = load <4 x i16>* %B
134 call void @llvm.arm.neon.vst2lane.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 2)
135 %tmp2 = getelementptr i16* %A, i32 %inc
136 store i16* %tmp2, i16** %ptr
140 define void @vst2lanei32(i32* %A, <2 x i32>* %B) nounwind {
143 %tmp0 = bitcast i32* %A to i8*
144 %tmp1 = load <2 x i32>* %B
145 call void @llvm.arm.neon.vst2lane.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 1)
149 define void @vst2lanef(float* %A, <2 x float>* %B) nounwind {
152 %tmp0 = bitcast float* %A to i8*
153 %tmp1 = load <2 x float>* %B
154 call void @llvm.arm.neon.vst2lane.v2f32(i8* %tmp0, <2 x float> %tmp1, <2 x float> %tmp1, i32 1, i32 1)
158 define void @vst2laneQi16(i16* %A, <8 x i16>* %B) nounwind {
159 ;CHECK: vst2laneQi16:
160 ;Check the (default) alignment.
161 ;CHECK: vst2.16 {d17[1], d19[1]}, [r0]
162 %tmp0 = bitcast i16* %A to i8*
163 %tmp1 = load <8 x i16>* %B
164 call void @llvm.arm.neon.vst2lane.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 5, i32 1)
168 define void @vst2laneQi32(i32* %A, <4 x i32>* %B) nounwind {
169 ;CHECK: vst2laneQi32:
170 ;Check the alignment value. Max for this instruction is 64 bits:
171 ;CHECK: vst2.32 {d17[0], d19[0]}, [r0, :64]
172 %tmp0 = bitcast i32* %A to i8*
173 %tmp1 = load <4 x i32>* %B
174 call void @llvm.arm.neon.vst2lane.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 2, i32 16)
178 define void @vst2laneQf(float* %A, <4 x float>* %B) nounwind {
181 %tmp0 = bitcast float* %A to i8*
182 %tmp1 = load <4 x float>* %B
183 call void @llvm.arm.neon.vst2lane.v4f32(i8* %tmp0, <4 x float> %tmp1, <4 x float> %tmp1, i32 3, i32 1)
187 declare void @llvm.arm.neon.vst2lane.v8i8(i8*, <8 x i8>, <8 x i8>, i32, i32) nounwind
188 declare void @llvm.arm.neon.vst2lane.v4i16(i8*, <4 x i16>, <4 x i16>, i32, i32) nounwind
189 declare void @llvm.arm.neon.vst2lane.v2i32(i8*, <2 x i32>, <2 x i32>, i32, i32) nounwind
190 declare void @llvm.arm.neon.vst2lane.v2f32(i8*, <2 x float>, <2 x float>, i32, i32) nounwind
192 declare void @llvm.arm.neon.vst2lane.v8i16(i8*, <8 x i16>, <8 x i16>, i32, i32) nounwind
193 declare void @llvm.arm.neon.vst2lane.v4i32(i8*, <4 x i32>, <4 x i32>, i32, i32) nounwind
194 declare void @llvm.arm.neon.vst2lane.v4f32(i8*, <4 x float>, <4 x float>, i32, i32) nounwind
196 define void @vst3lanei8(i8* %A, <8 x i8>* %B) nounwind {
199 %tmp1 = load <8 x i8>* %B
200 call void @llvm.arm.neon.vst3lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 1)
204 define void @vst3lanei16(i16* %A, <4 x i16>* %B) nounwind {
206 ;Check the (default) alignment value. VST3 does not support alignment.
207 ;CHECK: vst3.16 {d16[1], d17[1], d18[1]}, [r0]
208 %tmp0 = bitcast i16* %A to i8*
209 %tmp1 = load <4 x i16>* %B
210 call void @llvm.arm.neon.vst3lane.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 8)
214 define void @vst3lanei32(i32* %A, <2 x i32>* %B) nounwind {
217 %tmp0 = bitcast i32* %A to i8*
218 %tmp1 = load <2 x i32>* %B
219 call void @llvm.arm.neon.vst3lane.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 1)
223 define void @vst3lanef(float* %A, <2 x float>* %B) nounwind {
226 %tmp0 = bitcast float* %A to i8*
227 %tmp1 = load <2 x float>* %B
228 call void @llvm.arm.neon.vst3lane.v2f32(i8* %tmp0, <2 x float> %tmp1, <2 x float> %tmp1, <2 x float> %tmp1, i32 1, i32 1)
232 define void @vst3laneQi16(i16* %A, <8 x i16>* %B) nounwind {
233 ;CHECK: vst3laneQi16:
234 ;Check the (default) alignment value. VST3 does not support alignment.
235 ;CHECK: vst3.16 {d17[2], d19[2], d21[2]}, [r0]
236 %tmp0 = bitcast i16* %A to i8*
237 %tmp1 = load <8 x i16>* %B
238 call void @llvm.arm.neon.vst3lane.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 6, i32 8)
242 define void @vst3laneQi32(i32* %A, <4 x i32>* %B) nounwind {
243 ;CHECK: vst3laneQi32:
245 %tmp0 = bitcast i32* %A to i8*
246 %tmp1 = load <4 x i32>* %B
247 call void @llvm.arm.neon.vst3lane.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 0, i32 1)
251 ;Check for a post-increment updating store.
252 define void @vst3laneQi32_update(i32** %ptr, <4 x i32>* %B) nounwind {
253 ;CHECK: vst3laneQi32_update:
254 ;CHECK: vst3.32 {d16[0], d18[0], d20[0]}, [r1]!
256 %tmp0 = bitcast i32* %A to i8*
257 %tmp1 = load <4 x i32>* %B
258 call void @llvm.arm.neon.vst3lane.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 0, i32 1)
259 %tmp2 = getelementptr i32* %A, i32 3
260 store i32* %tmp2, i32** %ptr
264 define void @vst3laneQf(float* %A, <4 x float>* %B) nounwind {
267 %tmp0 = bitcast float* %A to i8*
268 %tmp1 = load <4 x float>* %B
269 call void @llvm.arm.neon.vst3lane.v4f32(i8* %tmp0, <4 x float> %tmp1, <4 x float> %tmp1, <4 x float> %tmp1, i32 1, i32 1)
273 declare void @llvm.arm.neon.vst3lane.v8i8(i8*, <8 x i8>, <8 x i8>, <8 x i8>, i32, i32) nounwind
274 declare void @llvm.arm.neon.vst3lane.v4i16(i8*, <4 x i16>, <4 x i16>, <4 x i16>, i32, i32) nounwind
275 declare void @llvm.arm.neon.vst3lane.v2i32(i8*, <2 x i32>, <2 x i32>, <2 x i32>, i32, i32) nounwind
276 declare void @llvm.arm.neon.vst3lane.v2f32(i8*, <2 x float>, <2 x float>, <2 x float>, i32, i32) nounwind
278 declare void @llvm.arm.neon.vst3lane.v8i16(i8*, <8 x i16>, <8 x i16>, <8 x i16>, i32, i32) nounwind
279 declare void @llvm.arm.neon.vst3lane.v4i32(i8*, <4 x i32>, <4 x i32>, <4 x i32>, i32, i32) nounwind
280 declare void @llvm.arm.neon.vst3lane.v4f32(i8*, <4 x float>, <4 x float>, <4 x float>, i32, i32) nounwind
283 define void @vst4lanei8(i8* %A, <8 x i8>* %B) nounwind {
285 ;Check the alignment value. Max for this instruction is 32 bits:
286 ;CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32]
287 %tmp1 = load <8 x i8>* %B
288 call void @llvm.arm.neon.vst4lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8)
292 ;Check for a post-increment updating store.
293 define void @vst4lanei8_update(i8** %ptr, <8 x i8>* %B) nounwind {
294 ;CHECK: vst4lanei8_update:
295 ;CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r1, :32]!
297 %tmp1 = load <8 x i8>* %B
298 call void @llvm.arm.neon.vst4lane.v8i8(i8* %A, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, <8 x i8> %tmp1, i32 1, i32 8)
299 %tmp2 = getelementptr i8* %A, i32 4
300 store i8* %tmp2, i8** %ptr
304 define void @vst4lanei16(i16* %A, <4 x i16>* %B) nounwind {
307 %tmp0 = bitcast i16* %A to i8*
308 %tmp1 = load <4 x i16>* %B
309 call void @llvm.arm.neon.vst4lane.v4i16(i8* %tmp0, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, <4 x i16> %tmp1, i32 1, i32 1)
313 define void @vst4lanei32(i32* %A, <2 x i32>* %B) nounwind {
315 ;Check the alignment value. Max for this instruction is 128 bits:
316 ;CHECK: vst4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128]
317 %tmp0 = bitcast i32* %A to i8*
318 %tmp1 = load <2 x i32>* %B
319 call void @llvm.arm.neon.vst4lane.v2i32(i8* %tmp0, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, <2 x i32> %tmp1, i32 1, i32 16)
323 define void @vst4lanef(float* %A, <2 x float>* %B) nounwind {
326 %tmp0 = bitcast float* %A to i8*
327 %tmp1 = load <2 x float>* %B
328 call void @llvm.arm.neon.vst4lane.v2f32(i8* %tmp0, <2 x float> %tmp1, <2 x float> %tmp1, <2 x float> %tmp1, <2 x float> %tmp1, i32 1, i32 1)
332 define void @vst4laneQi16(i16* %A, <8 x i16>* %B) nounwind {
333 ;CHECK: vst4laneQi16:
334 ;Check the alignment value. Max for this instruction is 64 bits:
335 ;CHECK: vst4.16 {d17[3], d19[3], d21[3], d23[3]}, [r0, :64]
336 %tmp0 = bitcast i16* %A to i8*
337 %tmp1 = load <8 x i16>* %B
338 call void @llvm.arm.neon.vst4lane.v8i16(i8* %tmp0, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, <8 x i16> %tmp1, i32 7, i32 16)
342 define void @vst4laneQi32(i32* %A, <4 x i32>* %B) nounwind {
343 ;CHECK: vst4laneQi32:
344 ;Check the (default) alignment.
345 ;CHECK: vst4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0]
346 %tmp0 = bitcast i32* %A to i8*
347 %tmp1 = load <4 x i32>* %B
348 call void @llvm.arm.neon.vst4lane.v4i32(i8* %tmp0, <4 x i32> %tmp1, <4 x i32> %tmp1, <4 x i32> %tmp1, <4 x i32> %tmp1, i32 2, i32 1)
352 define void @vst4laneQf(float* %A, <4 x float>* %B) nounwind {
355 %tmp0 = bitcast float* %A to i8*
356 %tmp1 = load <4 x float>* %B
357 call void @llvm.arm.neon.vst4lane.v4f32(i8* %tmp0, <4 x float> %tmp1, <4 x float> %tmp1, <4 x float> %tmp1, <4 x float> %tmp1, i32 1, i32 1)
361 declare void @llvm.arm.neon.vst4lane.v8i8(i8*, <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8>, i32, i32) nounwind
362 declare void @llvm.arm.neon.vst4lane.v4i16(i8*, <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16>, i32, i32) nounwind
363 declare void @llvm.arm.neon.vst4lane.v2i32(i8*, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>, i32, i32) nounwind
364 declare void @llvm.arm.neon.vst4lane.v2f32(i8*, <2 x float>, <2 x float>, <2 x float>, <2 x float>, i32, i32) nounwind
366 declare void @llvm.arm.neon.vst4lane.v8i16(i8*, <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16>, i32, i32) nounwind
367 declare void @llvm.arm.neon.vst4lane.v4i32(i8*, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, i32, i32) nounwind
368 declare void @llvm.arm.neon.vst4lane.v4f32(i8*, <4 x float>, <4 x float>, <4 x float>, <4 x float>, i32, i32) nounwind