]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/ARM/vdup.ll
Vendor import of llvm release_34 branch r197841 (effectively, 3.4 RC3):
[FreeBSD/FreeBSD.git] / test / CodeGen / ARM / vdup.ll
1 ; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
2
3 define <8 x i8> @v_dup8(i8 %A) nounwind {
4 ;CHECK-LABEL: v_dup8:
5 ;CHECK: vdup.8
6         %tmp1 = insertelement <8 x i8> zeroinitializer, i8 %A, i32 0
7         %tmp2 = insertelement <8 x i8> %tmp1, i8 %A, i32 1
8         %tmp3 = insertelement <8 x i8> %tmp2, i8 %A, i32 2
9         %tmp4 = insertelement <8 x i8> %tmp3, i8 %A, i32 3
10         %tmp5 = insertelement <8 x i8> %tmp4, i8 %A, i32 4
11         %tmp6 = insertelement <8 x i8> %tmp5, i8 %A, i32 5
12         %tmp7 = insertelement <8 x i8> %tmp6, i8 %A, i32 6
13         %tmp8 = insertelement <8 x i8> %tmp7, i8 %A, i32 7
14         ret <8 x i8> %tmp8
15 }
16
17 define <4 x i16> @v_dup16(i16 %A) nounwind {
18 ;CHECK-LABEL: v_dup16:
19 ;CHECK: vdup.16
20         %tmp1 = insertelement <4 x i16> zeroinitializer, i16 %A, i32 0
21         %tmp2 = insertelement <4 x i16> %tmp1, i16 %A, i32 1
22         %tmp3 = insertelement <4 x i16> %tmp2, i16 %A, i32 2
23         %tmp4 = insertelement <4 x i16> %tmp3, i16 %A, i32 3
24         ret <4 x i16> %tmp4
25 }
26
27 define <2 x i32> @v_dup32(i32 %A) nounwind {
28 ;CHECK-LABEL: v_dup32:
29 ;CHECK: vdup.32
30         %tmp1 = insertelement <2 x i32> zeroinitializer, i32 %A, i32 0
31         %tmp2 = insertelement <2 x i32> %tmp1, i32 %A, i32 1
32         ret <2 x i32> %tmp2
33 }
34
35 define <2 x float> @v_dupfloat(float %A) nounwind {
36 ;CHECK-LABEL: v_dupfloat:
37 ;CHECK: vdup.32
38         %tmp1 = insertelement <2 x float> zeroinitializer, float %A, i32 0
39         %tmp2 = insertelement <2 x float> %tmp1, float %A, i32 1
40         ret <2 x float> %tmp2
41 }
42
43 define <16 x i8> @v_dupQ8(i8 %A) nounwind {
44 ;CHECK-LABEL: v_dupQ8:
45 ;CHECK: vdup.8
46         %tmp1 = insertelement <16 x i8> zeroinitializer, i8 %A, i32 0
47         %tmp2 = insertelement <16 x i8> %tmp1, i8 %A, i32 1
48         %tmp3 = insertelement <16 x i8> %tmp2, i8 %A, i32 2
49         %tmp4 = insertelement <16 x i8> %tmp3, i8 %A, i32 3
50         %tmp5 = insertelement <16 x i8> %tmp4, i8 %A, i32 4
51         %tmp6 = insertelement <16 x i8> %tmp5, i8 %A, i32 5
52         %tmp7 = insertelement <16 x i8> %tmp6, i8 %A, i32 6
53         %tmp8 = insertelement <16 x i8> %tmp7, i8 %A, i32 7
54         %tmp9 = insertelement <16 x i8> %tmp8, i8 %A, i32 8
55         %tmp10 = insertelement <16 x i8> %tmp9, i8 %A, i32 9
56         %tmp11 = insertelement <16 x i8> %tmp10, i8 %A, i32 10
57         %tmp12 = insertelement <16 x i8> %tmp11, i8 %A, i32 11
58         %tmp13 = insertelement <16 x i8> %tmp12, i8 %A, i32 12
59         %tmp14 = insertelement <16 x i8> %tmp13, i8 %A, i32 13
60         %tmp15 = insertelement <16 x i8> %tmp14, i8 %A, i32 14
61         %tmp16 = insertelement <16 x i8> %tmp15, i8 %A, i32 15
62         ret <16 x i8> %tmp16
63 }
64
65 define <8 x i16> @v_dupQ16(i16 %A) nounwind {
66 ;CHECK-LABEL: v_dupQ16:
67 ;CHECK: vdup.16
68         %tmp1 = insertelement <8 x i16> zeroinitializer, i16 %A, i32 0
69         %tmp2 = insertelement <8 x i16> %tmp1, i16 %A, i32 1
70         %tmp3 = insertelement <8 x i16> %tmp2, i16 %A, i32 2
71         %tmp4 = insertelement <8 x i16> %tmp3, i16 %A, i32 3
72         %tmp5 = insertelement <8 x i16> %tmp4, i16 %A, i32 4
73         %tmp6 = insertelement <8 x i16> %tmp5, i16 %A, i32 5
74         %tmp7 = insertelement <8 x i16> %tmp6, i16 %A, i32 6
75         %tmp8 = insertelement <8 x i16> %tmp7, i16 %A, i32 7
76         ret <8 x i16> %tmp8
77 }
78
79 define <4 x i32> @v_dupQ32(i32 %A) nounwind {
80 ;CHECK-LABEL: v_dupQ32:
81 ;CHECK: vdup.32
82         %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %A, i32 0
83         %tmp2 = insertelement <4 x i32> %tmp1, i32 %A, i32 1
84         %tmp3 = insertelement <4 x i32> %tmp2, i32 %A, i32 2
85         %tmp4 = insertelement <4 x i32> %tmp3, i32 %A, i32 3
86         ret <4 x i32> %tmp4
87 }
88
89 define <4 x float> @v_dupQfloat(float %A) nounwind {
90 ;CHECK-LABEL: v_dupQfloat:
91 ;CHECK: vdup.32
92         %tmp1 = insertelement <4 x float> zeroinitializer, float %A, i32 0
93         %tmp2 = insertelement <4 x float> %tmp1, float %A, i32 1
94         %tmp3 = insertelement <4 x float> %tmp2, float %A, i32 2
95         %tmp4 = insertelement <4 x float> %tmp3, float %A, i32 3
96         ret <4 x float> %tmp4
97 }
98
99 ; Check to make sure it works with shuffles, too.
100
101 define <8 x i8> @v_shuffledup8(i8 %A) nounwind {
102 ;CHECK-LABEL: v_shuffledup8:
103 ;CHECK: vdup.8
104         %tmp1 = insertelement <8 x i8> undef, i8 %A, i32 0
105         %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> zeroinitializer
106         ret <8 x i8> %tmp2
107 }
108
109 define <4 x i16> @v_shuffledup16(i16 %A) nounwind {
110 ;CHECK-LABEL: v_shuffledup16:
111 ;CHECK: vdup.16
112         %tmp1 = insertelement <4 x i16> undef, i16 %A, i32 0
113         %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> zeroinitializer
114         ret <4 x i16> %tmp2
115 }
116
117 define <2 x i32> @v_shuffledup32(i32 %A) nounwind {
118 ;CHECK-LABEL: v_shuffledup32:
119 ;CHECK: vdup.32
120         %tmp1 = insertelement <2 x i32> undef, i32 %A, i32 0
121         %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> zeroinitializer
122         ret <2 x i32> %tmp2
123 }
124
125 define <2 x float> @v_shuffledupfloat(float %A) nounwind {
126 ;CHECK-LABEL: v_shuffledupfloat:
127 ;CHECK: vdup.32
128         %tmp1 = insertelement <2 x float> undef, float %A, i32 0
129         %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> zeroinitializer
130         ret <2 x float> %tmp2
131 }
132
133 define <16 x i8> @v_shuffledupQ8(i8 %A) nounwind {
134 ;CHECK-LABEL: v_shuffledupQ8:
135 ;CHECK: vdup.8
136         %tmp1 = insertelement <16 x i8> undef, i8 %A, i32 0
137         %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> undef, <16 x i32> zeroinitializer
138         ret <16 x i8> %tmp2
139 }
140
141 define <8 x i16> @v_shuffledupQ16(i16 %A) nounwind {
142 ;CHECK-LABEL: v_shuffledupQ16:
143 ;CHECK: vdup.16
144         %tmp1 = insertelement <8 x i16> undef, i16 %A, i32 0
145         %tmp2 = shufflevector <8 x i16> %tmp1, <8 x i16> undef, <8 x i32> zeroinitializer
146         ret <8 x i16> %tmp2
147 }
148
149 define <4 x i32> @v_shuffledupQ32(i32 %A) nounwind {
150 ;CHECK-LABEL: v_shuffledupQ32:
151 ;CHECK: vdup.32
152         %tmp1 = insertelement <4 x i32> undef, i32 %A, i32 0
153         %tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <4 x i32> zeroinitializer
154         ret <4 x i32> %tmp2
155 }
156
157 define <4 x float> @v_shuffledupQfloat(float %A) nounwind {
158 ;CHECK-LABEL: v_shuffledupQfloat:
159 ;CHECK: vdup.32
160         %tmp1 = insertelement <4 x float> undef, float %A, i32 0
161         %tmp2 = shufflevector <4 x float> %tmp1, <4 x float> undef, <4 x i32> zeroinitializer
162         ret <4 x float> %tmp2
163 }
164
165 define <8 x i8> @vduplane8(<8 x i8>* %A) nounwind {
166 ;CHECK-LABEL: vduplane8:
167 ;CHECK: vdup.8
168         %tmp1 = load <8 x i8>* %A
169         %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >
170         ret <8 x i8> %tmp2
171 }
172
173 define <4 x i16> @vduplane16(<4 x i16>* %A) nounwind {
174 ;CHECK-LABEL: vduplane16:
175 ;CHECK: vdup.16
176         %tmp1 = load <4 x i16>* %A
177         %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >
178         ret <4 x i16> %tmp2
179 }
180
181 define <2 x i32> @vduplane32(<2 x i32>* %A) nounwind {
182 ;CHECK-LABEL: vduplane32:
183 ;CHECK: vdup.32
184         %tmp1 = load <2 x i32>* %A
185         %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <2 x i32> < i32 1, i32 1 >
186         ret <2 x i32> %tmp2
187 }
188
189 define <2 x float> @vduplanefloat(<2 x float>* %A) nounwind {
190 ;CHECK-LABEL: vduplanefloat:
191 ;CHECK: vdup.32
192         %tmp1 = load <2 x float>* %A
193         %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <2 x i32> < i32 1, i32 1 >
194         ret <2 x float> %tmp2
195 }
196
197 define <16 x i8> @vduplaneQ8(<8 x i8>* %A) nounwind {
198 ;CHECK-LABEL: vduplaneQ8:
199 ;CHECK: vdup.8
200         %tmp1 = load <8 x i8>* %A
201         %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <16 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >
202         ret <16 x i8> %tmp2
203 }
204
205 define <8 x i16> @vduplaneQ16(<4 x i16>* %A) nounwind {
206 ;CHECK-LABEL: vduplaneQ16:
207 ;CHECK: vdup.16
208         %tmp1 = load <4 x i16>* %A
209         %tmp2 = shufflevector <4 x i16> %tmp1, <4 x i16> undef, <8 x i32> < i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1 >
210         ret <8 x i16> %tmp2
211 }
212
213 define <4 x i32> @vduplaneQ32(<2 x i32>* %A) nounwind {
214 ;CHECK-LABEL: vduplaneQ32:
215 ;CHECK: vdup.32
216         %tmp1 = load <2 x i32>* %A
217         %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >
218         ret <4 x i32> %tmp2
219 }
220
221 define <4 x float> @vduplaneQfloat(<2 x float>* %A) nounwind {
222 ;CHECK-LABEL: vduplaneQfloat:
223 ;CHECK: vdup.32
224         %tmp1 = load <2 x float>* %A
225         %tmp2 = shufflevector <2 x float> %tmp1, <2 x float> undef, <4 x i32> < i32 1, i32 1, i32 1, i32 1 >
226         ret <4 x float> %tmp2
227 }
228
229 define <2 x i64> @foo(<2 x i64> %arg0_int64x1_t) nounwind readnone {
230 entry:
231   %0 = shufflevector <2 x i64> %arg0_int64x1_t, <2 x i64> undef, <2 x i32> <i32 1, i32 1>
232   ret <2 x i64> %0
233 }
234
235 define <2 x i64> @bar(<2 x i64> %arg0_int64x1_t) nounwind readnone {
236 entry:
237   %0 = shufflevector <2 x i64> %arg0_int64x1_t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
238   ret <2 x i64> %0
239 }
240
241 define <2 x double> @baz(<2 x double> %arg0_int64x1_t) nounwind readnone {
242 entry:
243   %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 1, i32 1>
244   ret <2 x double> %0
245 }
246
247 define <2 x double> @qux(<2 x double> %arg0_int64x1_t) nounwind readnone {
248 entry:
249   %0 = shufflevector <2 x double> %arg0_int64x1_t, <2 x double> undef, <2 x i32> <i32 0, i32 0>
250   ret <2 x double> %0
251 }
252
253 ; Radar 7373643
254 ;CHECK-LABEL: redundantVdup:
255 ;CHECK: vmov.i8
256 ;CHECK-NOT: vdup.8
257 ;CHECK: vstr
258 define void @redundantVdup(<8 x i8>* %ptr) nounwind {
259   %1 = insertelement <8 x i8> undef, i8 -128, i32 0
260   %2 = shufflevector <8 x i8> %1, <8 x i8> undef, <8 x i32> zeroinitializer
261   store <8 x i8> %2, <8 x i8>* %ptr, align 8
262   ret void
263 }
264
265 define <4 x i32> @tdupi(i32 %x, i32 %y) {
266 ;CHECK-LABEL: tdupi:
267 ;CHECK: vdup.32
268   %1 = insertelement <4 x i32> undef, i32 %x, i32 0
269   %2 = insertelement <4 x i32> %1, i32 %x, i32 1
270   %3 = insertelement <4 x i32> %2, i32 %x, i32 2
271   %4 = insertelement <4 x i32> %3, i32 %y, i32 3
272   ret <4 x i32> %4
273 }
274
275 define <4 x float> @tdupf(float %x, float %y) {
276 ;CHECK-LABEL: tdupf:
277 ;CHECK: vdup.32
278   %1 = insertelement <4 x float> undef, float %x, i32 0
279   %2 = insertelement <4 x float> %1, float %x, i32 1
280   %3 = insertelement <4 x float> %2, float %x, i32 2
281   %4 = insertelement <4 x float> %3, float %y, i32 3
282   ret <4 x float> %4
283 }
284
285 ; This test checks that when splatting an element from a vector into another,
286 ; the value isn't moved out to GPRs first.
287 define <4 x i32> @tduplane(<4 x i32> %invec) {
288 ;CHECK-LABEL: tduplane:
289 ;CHECK-NOT: vmov {{.*}}, d16[1]
290 ;CHECK: vdup.32 {{.*}}, d16[1]
291   %in = extractelement <4 x i32> %invec, i32 1
292   %1 = insertelement <4 x i32> undef, i32 %in, i32 0
293   %2 = insertelement <4 x i32> %1, i32 %in, i32 1
294   %3 = insertelement <4 x i32> %2, i32 %in, i32 2
295   %4 = insertelement <4 x i32> %3, i32 255, i32 3
296   ret <4 x i32> %4
297 }
298
299 define <2 x float> @check_f32(<4 x float> %v) nounwind {
300 ;CHECK-LABEL: check_f32:
301 ;CHECK: vdup.32 {{.*}}, d{{..}}[1]
302   %x = extractelement <4 x float> %v, i32 3
303   %1 = insertelement  <2 x float> undef, float %x, i32 0
304   %2 = insertelement  <2 x float> %1, float %x, i32 1
305   ret <2 x float> %2
306 }
307
308 define <2 x i32> @check_i32(<4 x i32> %v) nounwind {
309 ;CHECK-LABEL: check_i32:
310 ;CHECK: vdup.32 {{.*}}, d{{..}}[1]
311   %x = extractelement <4 x i32> %v, i32 3
312   %1 = insertelement  <2 x i32> undef, i32 %x, i32 0
313   %2 = insertelement  <2 x i32> %1, i32 %x, i32 1
314   ret <2 x i32> %2
315 }
316
317 define <4 x i16> @check_i16(<8 x i16> %v) nounwind {
318 ;CHECK-LABEL: check_i16:
319 ;CHECK: vdup.16 {{.*}}, d{{..}}[3]
320   %x = extractelement <8 x i16> %v, i32 3
321   %1 = insertelement  <4 x i16> undef, i16 %x, i32 0
322   %2 = insertelement  <4 x i16> %1, i16 %x, i32 1
323   ret <4 x i16> %2
324 }
325
326 define <8 x i8> @check_i8(<16 x i8> %v) nounwind {
327 ;CHECK-LABEL: check_i8:
328 ;CHECK: vdup.8 {{.*}}, d{{..}}[3]
329   %x = extractelement <16 x i8> %v, i32 3
330   %1 = insertelement  <8  x i8> undef, i8 %x, i32 0
331   %2 = insertelement  <8  x i8> %1, i8 %x, i32 1
332   ret <8 x i8> %2
333 }