1 ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
3 define void @vst1lanei8(i8* %A, <8 x i8>* %B) nounwind {
4 ;CHECK-LABEL: vst1lanei8:
5 ;Check the (default) alignment.
6 ;CHECK: vst1.8 {{{d[0-9]+}}[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-LABEL: vst1lanei8_update:
16 ;CHECK: vst1.8 {d16[3]}, [{{r[0-9]+}}]!
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 {
27 ;CHECK-LABEL: vst1lanei16:
28 ;Check the alignment value. Max for this instruction is 16 bits:
29 ;CHECK: vst1.16 {{{d[0-9]+}}[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 {
37 ;CHECK-LABEL: vst1lanei32:
38 ;Check the alignment value. Max for this instruction is 32 bits:
39 ;CHECK: vst1.32 {{{d[0-9]+}}[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 {
47 ;CHECK-LABEL: vst1lanef:
48 ;CHECK: vst1.32 {{{d[0-9]+}}[1]}, [r0:32]
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 {
56 ;CHECK-LABEL: vst1laneQi8:
57 ; // Can use scalar load. No need to use vectors.
58 ; // CHE-CK: vst1.8 {{{d[0-9]+}}[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 {
66 ;CHECK-LABEL: vst1laneQi16:
67 ;CHECK: vst1.16 {{{d[0-9]+}}[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 {
75 ;CHECK-LABEL: vst1laneQi32:
76 ; // Can use scalar load. No need to use vectors.
77 ; // CHE-CK: vst1.32 {{{d[0-9]+}}[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-LABEL: vst1laneQi32_update:
87 ; // Can use scalar load. No need to use vectors.
88 ; // CHE-CK: vst1.32 {{{d[0-9]+}}[1]}, [{{r[0-9]+}}: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 {
99 ;CHECK-LABEL: vst1laneQf:
100 ; // Can use scalar load. No need to use vectors.
101 ; // CHE-CK: vst1.32 {{{d[0-9]+}}[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 {
109 ;CHECK-LABEL: vst2lanei8:
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 {
118 ;CHECK-LABEL: vst2lanei16:
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-LABEL: vst2lanei16_update:
130 ;CHECK: vst2.16 {d16[1], d17[1]}, [{{r[0-9]+}}], {{r[0-9]+}}
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 {
141 ;CHECK-LABEL: vst2lanei32:
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 {
150 ;CHECK-LABEL: vst2lanef:
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-LABEL: 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-LABEL: 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 {
179 ;CHECK-LABEL: vst2laneQf:
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 {
197 ;CHECK-LABEL: vst3lanei8:
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 {
205 ;CHECK-LABEL: vst3lanei16:
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 {
215 ;CHECK-LABEL: vst3lanei32:
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 {
224 ;CHECK-LABEL: vst3lanef:
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-LABEL: 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-LABEL: 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-LABEL: vst3laneQi32_update:
254 ;CHECK: vst3.32 {d16[0], d18[0], d20[0]}, [{{r[0-9]+}}]!
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 {
265 ;CHECK-LABEL: vst3laneQf:
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 {
284 ;CHECK-LABEL: vst4lanei8:
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-LABEL: vst4lanei8_update:
295 ;CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [{{r[0-9]+}}: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 {
305 ;CHECK-LABEL: vst4lanei16:
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 {
314 ;CHECK-LABEL: vst4lanei32:
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 {
324 ;CHECK-LABEL: vst4lanef:
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-LABEL: 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-LABEL: 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 {
353 ;CHECK-LABEL: vst4laneQf:
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 ; Make sure this doesn't crash; PR10258
362 define <8 x i16> @variable_insertelement(<8 x i16> %a, i16 %b, i32 %c) nounwind readnone {
363 ;CHECK-LABEL: variable_insertelement:
364 %r = insertelement <8 x i16> %a, i16 %b, i32 %c
368 declare void @llvm.arm.neon.vst4lane.v8i8(i8*, <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8>, i32, i32) nounwind
369 declare void @llvm.arm.neon.vst4lane.v4i16(i8*, <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16>, i32, i32) nounwind
370 declare void @llvm.arm.neon.vst4lane.v2i32(i8*, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>, i32, i32) nounwind
371 declare void @llvm.arm.neon.vst4lane.v2f32(i8*, <2 x float>, <2 x float>, <2 x float>, <2 x float>, i32, i32) nounwind
373 declare void @llvm.arm.neon.vst4lane.v8i16(i8*, <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16>, i32, i32) nounwind
374 declare void @llvm.arm.neon.vst4lane.v4i32(i8*, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, i32, i32) nounwind
375 declare void @llvm.arm.neon.vst4lane.v4f32(i8*, <4 x float>, <4 x float>, <4 x float>, <4 x float>, i32, i32) nounwind