[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / build-vector-extract.ll
blob36b1b2cdcb43204e5f80fc74adc89a8569b1e300
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 define <2 x i64> @extract0_i32_zext_insert0_i64_undef(<4 x i32> %x) {
5 ; CHECK-LABEL: extract0_i32_zext_insert0_i64_undef:
6 ; CHECK:       // %bb.0:
7 ; CHECK-NEXT:    mov v0.s[1], wzr
8 ; CHECK-NEXT:    ret
9   %e = extractelement <4 x i32> %x, i32 0
10   %z = zext i32 %e to i64
11   %r = insertelement <2 x i64> undef, i64 %z, i32 0
12   ret <2 x i64> %r
15 define <2 x i64> @extract0_i32_zext_insert0_i64_zero(<4 x i32> %x) {
16 ; CHECK-LABEL: extract0_i32_zext_insert0_i64_zero:
17 ; CHECK:       // %bb.0:
18 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
19 ; CHECK-NEXT:    mov v1.s[0], v0.s[0]
20 ; CHECK-NEXT:    mov v0.16b, v1.16b
21 ; CHECK-NEXT:    ret
22   %e = extractelement <4 x i32> %x, i32 0
23   %z = zext i32 %e to i64
24   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
25   ret <2 x i64> %r
28 define <2 x i64> @extract1_i32_zext_insert0_i64_undef(<4 x i32> %x) {
29 ; CHECK-LABEL: extract1_i32_zext_insert0_i64_undef:
30 ; CHECK:       // %bb.0:
31 ; CHECK-NEXT:    mov w8, v0.s[1]
32 ; CHECK-NEXT:    fmov d0, x8
33 ; CHECK-NEXT:    ret
34   %e = extractelement <4 x i32> %x, i32 1
35   %z = zext i32 %e to i64
36   %r = insertelement <2 x i64> undef, i64 %z, i32 0
37   ret <2 x i64> %r
40 define <2 x i64> @extract1_i32_zext_insert0_i64_zero(<4 x i32> %x) {
41 ; CHECK-LABEL: extract1_i32_zext_insert0_i64_zero:
42 ; CHECK:       // %bb.0:
43 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
44 ; CHECK-NEXT:    mov v1.s[0], v0.s[1]
45 ; CHECK-NEXT:    mov v0.16b, v1.16b
46 ; CHECK-NEXT:    ret
47   %e = extractelement <4 x i32> %x, i32 1
48   %z = zext i32 %e to i64
49   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
50   ret <2 x i64> %r
53 define <2 x i64> @extract2_i32_zext_insert0_i64_undef(<4 x i32> %x) {
54 ; CHECK-LABEL: extract2_i32_zext_insert0_i64_undef:
55 ; CHECK:       // %bb.0:
56 ; CHECK-NEXT:    mov w8, v0.s[2]
57 ; CHECK-NEXT:    fmov d0, x8
58 ; CHECK-NEXT:    ret
59   %e = extractelement <4 x i32> %x, i32 2
60   %z = zext i32 %e to i64
61   %r = insertelement <2 x i64> undef, i64 %z, i32 0
62   ret <2 x i64> %r
65 define <2 x i64> @extract2_i32_zext_insert0_i64_zero(<4 x i32> %x) {
66 ; CHECK-LABEL: extract2_i32_zext_insert0_i64_zero:
67 ; CHECK:       // %bb.0:
68 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
69 ; CHECK-NEXT:    mov v1.s[0], v0.s[2]
70 ; CHECK-NEXT:    mov v0.16b, v1.16b
71 ; CHECK-NEXT:    ret
72   %e = extractelement <4 x i32> %x, i32 2
73   %z = zext i32 %e to i64
74   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
75   ret <2 x i64> %r
78 define <2 x i64> @extract3_i32_zext_insert0_i64_undef(<4 x i32> %x) {
79 ; CHECK-LABEL: extract3_i32_zext_insert0_i64_undef:
80 ; CHECK:       // %bb.0:
81 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
82 ; CHECK-NEXT:    ext v0.16b, v0.16b, v1.16b, #12
83 ; CHECK-NEXT:    ret
84   %e = extractelement <4 x i32> %x, i32 3
85   %z = zext i32 %e to i64
86   %r = insertelement <2 x i64> undef, i64 %z, i32 0
87   ret <2 x i64> %r
90 define <2 x i64> @extract3_i32_zext_insert0_i64_zero(<4 x i32> %x) {
91 ; CHECK-LABEL: extract3_i32_zext_insert0_i64_zero:
92 ; CHECK:       // %bb.0:
93 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
94 ; CHECK-NEXT:    mov v1.s[0], v0.s[3]
95 ; CHECK-NEXT:    mov v0.16b, v1.16b
96 ; CHECK-NEXT:    ret
97   %e = extractelement <4 x i32> %x, i32 3
98   %z = zext i32 %e to i64
99   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
100   ret <2 x i64> %r
103 define <2 x i64> @extract0_i32_zext_insert1_i64_undef(<4 x i32> %x) {
104 ; CHECK-LABEL: extract0_i32_zext_insert1_i64_undef:
105 ; CHECK:       // %bb.0:
106 ; CHECK-NEXT:    fmov w8, s0
107 ; CHECK-NEXT:    dup v0.2d, x8
108 ; CHECK-NEXT:    ret
109   %e = extractelement <4 x i32> %x, i32 0
110   %z = zext i32 %e to i64
111   %r = insertelement <2 x i64> undef, i64 %z, i32 1
112   ret <2 x i64> %r
115 define <2 x i64> @extract0_i32_zext_insert1_i64_zero(<4 x i32> %x) {
116 ; CHECK-LABEL: extract0_i32_zext_insert1_i64_zero:
117 ; CHECK:       // %bb.0:
118 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
119 ; CHECK-NEXT:    fmov w8, s0
120 ; CHECK-NEXT:    mov v1.d[1], x8
121 ; CHECK-NEXT:    mov v0.16b, v1.16b
122 ; CHECK-NEXT:    ret
123   %e = extractelement <4 x i32> %x, i32 0
124   %z = zext i32 %e to i64
125   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
126   ret <2 x i64> %r
129 define <2 x i64> @extract1_i32_zext_insert1_i64_undef(<4 x i32> %x) {
130 ; CHECK-LABEL: extract1_i32_zext_insert1_i64_undef:
131 ; CHECK:       // %bb.0:
132 ; CHECK-NEXT:    mov w8, v0.s[1]
133 ; CHECK-NEXT:    dup v0.2d, x8
134 ; CHECK-NEXT:    ret
135   %e = extractelement <4 x i32> %x, i32 1
136   %z = zext i32 %e to i64
137   %r = insertelement <2 x i64> undef, i64 %z, i32 1
138   ret <2 x i64> %r
141 define <2 x i64> @extract1_i32_zext_insert1_i64_zero(<4 x i32> %x) {
142 ; CHECK-LABEL: extract1_i32_zext_insert1_i64_zero:
143 ; CHECK:       // %bb.0:
144 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
145 ; CHECK-NEXT:    mov w8, v0.s[1]
146 ; CHECK-NEXT:    mov v1.d[1], x8
147 ; CHECK-NEXT:    mov v0.16b, v1.16b
148 ; CHECK-NEXT:    ret
149   %e = extractelement <4 x i32> %x, i32 1
150   %z = zext i32 %e to i64
151   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
152   ret <2 x i64> %r
155 define <2 x i64> @extract2_i32_zext_insert1_i64_undef(<4 x i32> %x) {
156 ; CHECK-LABEL: extract2_i32_zext_insert1_i64_undef:
157 ; CHECK:       // %bb.0:
158 ; CHECK-NEXT:    mov v0.s[3], wzr
159 ; CHECK-NEXT:    ret
160   %e = extractelement <4 x i32> %x, i32 2
161   %z = zext i32 %e to i64
162   %r = insertelement <2 x i64> undef, i64 %z, i32 1
163   ret <2 x i64> %r
166 define <2 x i64> @extract2_i32_zext_insert1_i64_zero(<4 x i32> %x) {
167 ; CHECK-LABEL: extract2_i32_zext_insert1_i64_zero:
168 ; CHECK:       // %bb.0:
169 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
170 ; CHECK-NEXT:    mov w8, v0.s[2]
171 ; CHECK-NEXT:    mov v1.d[1], x8
172 ; CHECK-NEXT:    mov v0.16b, v1.16b
173 ; CHECK-NEXT:    ret
174   %e = extractelement <4 x i32> %x, i32 2
175   %z = zext i32 %e to i64
176   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
177   ret <2 x i64> %r
180 define <2 x i64> @extract3_i32_zext_insert1_i64_undef(<4 x i32> %x) {
181 ; CHECK-LABEL: extract3_i32_zext_insert1_i64_undef:
182 ; CHECK:       // %bb.0:
183 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
184 ; CHECK-NEXT:    ext v0.16b, v0.16b, v1.16b, #4
185 ; CHECK-NEXT:    ret
186   %e = extractelement <4 x i32> %x, i32 3
187   %z = zext i32 %e to i64
188   %r = insertelement <2 x i64> undef, i64 %z, i32 1
189   ret <2 x i64> %r
192 define <2 x i64> @extract3_i32_zext_insert1_i64_zero(<4 x i32> %x) {
193 ; CHECK-LABEL: extract3_i32_zext_insert1_i64_zero:
194 ; CHECK:       // %bb.0:
195 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
196 ; CHECK-NEXT:    mov w8, v0.s[3]
197 ; CHECK-NEXT:    mov v1.d[1], x8
198 ; CHECK-NEXT:    mov v0.16b, v1.16b
199 ; CHECK-NEXT:    ret
200   %e = extractelement <4 x i32> %x, i32 3
201   %z = zext i32 %e to i64
202   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
203   ret <2 x i64> %r
206 define <2 x i64> @extract0_i16_zext_insert0_i64_undef(<8 x i16> %x) {
207 ; CHECK-LABEL: extract0_i16_zext_insert0_i64_undef:
208 ; CHECK:       // %bb.0:
209 ; CHECK-NEXT:    umov w8, v0.h[0]
210 ; CHECK-NEXT:    fmov d0, x8
211 ; CHECK-NEXT:    ret
212   %e = extractelement <8 x i16> %x, i32 0
213   %z = zext i16 %e to i64
214   %r = insertelement <2 x i64> undef, i64 %z, i32 0
215   ret <2 x i64> %r
218 define <2 x i64> @extract0_i16_zext_insert0_i64_zero(<8 x i16> %x) {
219 ; CHECK-LABEL: extract0_i16_zext_insert0_i64_zero:
220 ; CHECK:       // %bb.0:
221 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
222 ; CHECK-NEXT:    umov w8, v0.h[0]
223 ; CHECK-NEXT:    mov v1.s[0], w8
224 ; CHECK-NEXT:    mov v0.16b, v1.16b
225 ; CHECK-NEXT:    ret
226   %e = extractelement <8 x i16> %x, i32 0
227   %z = zext i16 %e to i64
228   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
229   ret <2 x i64> %r
232 define <2 x i64> @extract1_i16_zext_insert0_i64_undef(<8 x i16> %x) {
233 ; CHECK-LABEL: extract1_i16_zext_insert0_i64_undef:
234 ; CHECK:       // %bb.0:
235 ; CHECK-NEXT:    umov w8, v0.h[1]
236 ; CHECK-NEXT:    fmov d0, x8
237 ; CHECK-NEXT:    ret
238   %e = extractelement <8 x i16> %x, i32 1
239   %z = zext i16 %e to i64
240   %r = insertelement <2 x i64> undef, i64 %z, i32 0
241   ret <2 x i64> %r
244 define <2 x i64> @extract1_i16_zext_insert0_i64_zero(<8 x i16> %x) {
245 ; CHECK-LABEL: extract1_i16_zext_insert0_i64_zero:
246 ; CHECK:       // %bb.0:
247 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
248 ; CHECK-NEXT:    umov w8, v0.h[1]
249 ; CHECK-NEXT:    mov v1.s[0], w8
250 ; CHECK-NEXT:    mov v0.16b, v1.16b
251 ; CHECK-NEXT:    ret
252   %e = extractelement <8 x i16> %x, i32 1
253   %z = zext i16 %e to i64
254   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
255   ret <2 x i64> %r
258 define <2 x i64> @extract2_i16_zext_insert0_i64_undef(<8 x i16> %x) {
259 ; CHECK-LABEL: extract2_i16_zext_insert0_i64_undef:
260 ; CHECK:       // %bb.0:
261 ; CHECK-NEXT:    umov w8, v0.h[2]
262 ; CHECK-NEXT:    fmov d0, x8
263 ; CHECK-NEXT:    ret
264   %e = extractelement <8 x i16> %x, i32 2
265   %z = zext i16 %e to i64
266   %r = insertelement <2 x i64> undef, i64 %z, i32 0
267   ret <2 x i64> %r
270 define <2 x i64> @extract2_i16_zext_insert0_i64_zero(<8 x i16> %x) {
271 ; CHECK-LABEL: extract2_i16_zext_insert0_i64_zero:
272 ; CHECK:       // %bb.0:
273 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
274 ; CHECK-NEXT:    umov w8, v0.h[2]
275 ; CHECK-NEXT:    mov v1.s[0], w8
276 ; CHECK-NEXT:    mov v0.16b, v1.16b
277 ; CHECK-NEXT:    ret
278   %e = extractelement <8 x i16> %x, i32 2
279   %z = zext i16 %e to i64
280   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
281   ret <2 x i64> %r
284 define <2 x i64> @extract3_i16_zext_insert0_i64_undef(<8 x i16> %x) {
285 ; CHECK-LABEL: extract3_i16_zext_insert0_i64_undef:
286 ; CHECK:       // %bb.0:
287 ; CHECK-NEXT:    umov w8, v0.h[3]
288 ; CHECK-NEXT:    fmov d0, x8
289 ; CHECK-NEXT:    ret
290   %e = extractelement <8 x i16> %x, i32 3
291   %z = zext i16 %e to i64
292   %r = insertelement <2 x i64> undef, i64 %z, i32 0
293   ret <2 x i64> %r
296 define <2 x i64> @extract3_i16_zext_insert0_i64_zero(<8 x i16> %x) {
297 ; CHECK-LABEL: extract3_i16_zext_insert0_i64_zero:
298 ; CHECK:       // %bb.0:
299 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
300 ; CHECK-NEXT:    umov w8, v0.h[3]
301 ; CHECK-NEXT:    mov v1.s[0], w8
302 ; CHECK-NEXT:    mov v0.16b, v1.16b
303 ; CHECK-NEXT:    ret
304   %e = extractelement <8 x i16> %x, i32 3
305   %z = zext i16 %e to i64
306   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
307   ret <2 x i64> %r
310 define <2 x i64> @extract0_i16_zext_insert1_i64_undef(<8 x i16> %x) {
311 ; CHECK-LABEL: extract0_i16_zext_insert1_i64_undef:
312 ; CHECK:       // %bb.0:
313 ; CHECK-NEXT:    umov w8, v0.h[0]
314 ; CHECK-NEXT:    dup v0.2d, x8
315 ; CHECK-NEXT:    ret
316   %e = extractelement <8 x i16> %x, i32 0
317   %z = zext i16 %e to i64
318   %r = insertelement <2 x i64> undef, i64 %z, i32 1
319   ret <2 x i64> %r
322 define <2 x i64> @extract0_i16_zext_insert1_i64_zero(<8 x i16> %x) {
323 ; CHECK-LABEL: extract0_i16_zext_insert1_i64_zero:
324 ; CHECK:       // %bb.0:
325 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
326 ; CHECK-NEXT:    umov w8, v0.h[0]
327 ; CHECK-NEXT:    mov v1.d[1], x8
328 ; CHECK-NEXT:    mov v0.16b, v1.16b
329 ; CHECK-NEXT:    ret
330   %e = extractelement <8 x i16> %x, i32 0
331   %z = zext i16 %e to i64
332   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
333   ret <2 x i64> %r
336 define <2 x i64> @extract1_i16_zext_insert1_i64_undef(<8 x i16> %x) {
337 ; CHECK-LABEL: extract1_i16_zext_insert1_i64_undef:
338 ; CHECK:       // %bb.0:
339 ; CHECK-NEXT:    umov w8, v0.h[1]
340 ; CHECK-NEXT:    dup v0.2d, x8
341 ; CHECK-NEXT:    ret
342   %e = extractelement <8 x i16> %x, i32 1
343   %z = zext i16 %e to i64
344   %r = insertelement <2 x i64> undef, i64 %z, i32 1
345   ret <2 x i64> %r
348 define <2 x i64> @extract1_i16_zext_insert1_i64_zero(<8 x i16> %x) {
349 ; CHECK-LABEL: extract1_i16_zext_insert1_i64_zero:
350 ; CHECK:       // %bb.0:
351 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
352 ; CHECK-NEXT:    umov w8, v0.h[1]
353 ; CHECK-NEXT:    mov v1.d[1], x8
354 ; CHECK-NEXT:    mov v0.16b, v1.16b
355 ; CHECK-NEXT:    ret
356   %e = extractelement <8 x i16> %x, i32 1
357   %z = zext i16 %e to i64
358   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
359   ret <2 x i64> %r
362 define <2 x i64> @extract2_i16_zext_insert1_i64_undef(<8 x i16> %x) {
363 ; CHECK-LABEL: extract2_i16_zext_insert1_i64_undef:
364 ; CHECK:       // %bb.0:
365 ; CHECK-NEXT:    umov w8, v0.h[2]
366 ; CHECK-NEXT:    dup v0.2d, x8
367 ; CHECK-NEXT:    ret
368   %e = extractelement <8 x i16> %x, i32 2
369   %z = zext i16 %e to i64
370   %r = insertelement <2 x i64> undef, i64 %z, i32 1
371   ret <2 x i64> %r
374 define <2 x i64> @extract2_i16_zext_insert1_i64_zero(<8 x i16> %x) {
375 ; CHECK-LABEL: extract2_i16_zext_insert1_i64_zero:
376 ; CHECK:       // %bb.0:
377 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
378 ; CHECK-NEXT:    umov w8, v0.h[2]
379 ; CHECK-NEXT:    mov v1.d[1], x8
380 ; CHECK-NEXT:    mov v0.16b, v1.16b
381 ; CHECK-NEXT:    ret
382   %e = extractelement <8 x i16> %x, i32 2
383   %z = zext i16 %e to i64
384   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
385   ret <2 x i64> %r
388 define <2 x i64> @extract3_i16_zext_insert1_i64_undef(<8 x i16> %x) {
389 ; CHECK-LABEL: extract3_i16_zext_insert1_i64_undef:
390 ; CHECK:       // %bb.0:
391 ; CHECK-NEXT:    umov w8, v0.h[3]
392 ; CHECK-NEXT:    dup v0.2d, x8
393 ; CHECK-NEXT:    ret
394   %e = extractelement <8 x i16> %x, i32 3
395   %z = zext i16 %e to i64
396   %r = insertelement <2 x i64> undef, i64 %z, i32 1
397   ret <2 x i64> %r
400 define <2 x i64> @extract3_i16_zext_insert1_i64_zero(<8 x i16> %x) {
401 ; CHECK-LABEL: extract3_i16_zext_insert1_i64_zero:
402 ; CHECK:       // %bb.0:
403 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
404 ; CHECK-NEXT:    umov w8, v0.h[3]
405 ; CHECK-NEXT:    mov v1.d[1], x8
406 ; CHECK-NEXT:    mov v0.16b, v1.16b
407 ; CHECK-NEXT:    ret
408   %e = extractelement <8 x i16> %x, i32 3
409   %z = zext i16 %e to i64
410   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
411   ret <2 x i64> %r
414 ; i8
416 define <2 x i64> @extract0_i8_zext_insert0_i64_undef(<16 x i8> %x) {
417 ; CHECK-LABEL: extract0_i8_zext_insert0_i64_undef:
418 ; CHECK:       // %bb.0:
419 ; CHECK-NEXT:    umov w8, v0.b[0]
420 ; CHECK-NEXT:    fmov d0, x8
421 ; CHECK-NEXT:    ret
422   %e = extractelement <16 x i8> %x, i32 0
423   %z = zext i8 %e to i64
424   %r = insertelement <2 x i64> undef, i64 %z, i32 0
425   ret <2 x i64> %r
428 define <2 x i64> @extract0_i8_zext_insert0_i64_zero(<16 x i8> %x) {
429 ; CHECK-LABEL: extract0_i8_zext_insert0_i64_zero:
430 ; CHECK:       // %bb.0:
431 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
432 ; CHECK-NEXT:    umov w8, v0.b[0]
433 ; CHECK-NEXT:    mov v1.s[0], w8
434 ; CHECK-NEXT:    mov v0.16b, v1.16b
435 ; CHECK-NEXT:    ret
436   %e = extractelement <16 x i8> %x, i32 0
437   %z = zext i8 %e to i64
438   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
439   ret <2 x i64> %r
442 define <2 x i64> @extract1_i8_zext_insert0_i64_undef(<16 x i8> %x) {
443 ; CHECK-LABEL: extract1_i8_zext_insert0_i64_undef:
444 ; CHECK:       // %bb.0:
445 ; CHECK-NEXT:    umov w8, v0.b[1]
446 ; CHECK-NEXT:    fmov d0, x8
447 ; CHECK-NEXT:    ret
448   %e = extractelement <16 x i8> %x, i32 1
449   %z = zext i8 %e to i64
450   %r = insertelement <2 x i64> undef, i64 %z, i32 0
451   ret <2 x i64> %r
454 define <2 x i64> @extract1_i8_zext_insert0_i64_zero(<16 x i8> %x) {
455 ; CHECK-LABEL: extract1_i8_zext_insert0_i64_zero:
456 ; CHECK:       // %bb.0:
457 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
458 ; CHECK-NEXT:    umov w8, v0.b[1]
459 ; CHECK-NEXT:    mov v1.s[0], w8
460 ; CHECK-NEXT:    mov v0.16b, v1.16b
461 ; CHECK-NEXT:    ret
462   %e = extractelement <16 x i8> %x, i32 1
463   %z = zext i8 %e to i64
464   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
465   ret <2 x i64> %r
468 define <2 x i64> @extract2_i8_zext_insert0_i64_undef(<16 x i8> %x) {
469 ; CHECK-LABEL: extract2_i8_zext_insert0_i64_undef:
470 ; CHECK:       // %bb.0:
471 ; CHECK-NEXT:    umov w8, v0.b[2]
472 ; CHECK-NEXT:    fmov d0, x8
473 ; CHECK-NEXT:    ret
474   %e = extractelement <16 x i8> %x, i32 2
475   %z = zext i8 %e to i64
476   %r = insertelement <2 x i64> undef, i64 %z, i32 0
477   ret <2 x i64> %r
480 define <2 x i64> @extract2_i8_zext_insert0_i64_zero(<16 x i8> %x) {
481 ; CHECK-LABEL: extract2_i8_zext_insert0_i64_zero:
482 ; CHECK:       // %bb.0:
483 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
484 ; CHECK-NEXT:    umov w8, v0.b[2]
485 ; CHECK-NEXT:    mov v1.s[0], w8
486 ; CHECK-NEXT:    mov v0.16b, v1.16b
487 ; CHECK-NEXT:    ret
488   %e = extractelement <16 x i8> %x, i32 2
489   %z = zext i8 %e to i64
490   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
491   ret <2 x i64> %r
494 define <2 x i64> @extract3_i8_zext_insert0_i64_undef(<16 x i8> %x) {
495 ; CHECK-LABEL: extract3_i8_zext_insert0_i64_undef:
496 ; CHECK:       // %bb.0:
497 ; CHECK-NEXT:    umov w8, v0.b[3]
498 ; CHECK-NEXT:    fmov d0, x8
499 ; CHECK-NEXT:    ret
500   %e = extractelement <16 x i8> %x, i32 3
501   %z = zext i8 %e to i64
502   %r = insertelement <2 x i64> undef, i64 %z, i32 0
503   ret <2 x i64> %r
506 define <2 x i64> @extract3_i8_zext_insert0_i64_zero(<16 x i8> %x) {
507 ; CHECK-LABEL: extract3_i8_zext_insert0_i64_zero:
508 ; CHECK:       // %bb.0:
509 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
510 ; CHECK-NEXT:    umov w8, v0.b[3]
511 ; CHECK-NEXT:    mov v1.s[0], w8
512 ; CHECK-NEXT:    mov v0.16b, v1.16b
513 ; CHECK-NEXT:    ret
514   %e = extractelement <16 x i8> %x, i32 3
515   %z = zext i8 %e to i64
516   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 0
517   ret <2 x i64> %r
520 define <2 x i64> @extract0_i8_zext_insert1_i64_undef(<16 x i8> %x) {
521 ; CHECK-LABEL: extract0_i8_zext_insert1_i64_undef:
522 ; CHECK:       // %bb.0:
523 ; CHECK-NEXT:    umov w8, v0.b[0]
524 ; CHECK-NEXT:    dup v0.2d, x8
525 ; CHECK-NEXT:    ret
526   %e = extractelement <16 x i8> %x, i32 0
527   %z = zext i8 %e to i64
528   %r = insertelement <2 x i64> undef, i64 %z, i32 1
529   ret <2 x i64> %r
532 define <2 x i64> @extract0_i8_zext_insert1_i64_zero(<16 x i8> %x) {
533 ; CHECK-LABEL: extract0_i8_zext_insert1_i64_zero:
534 ; CHECK:       // %bb.0:
535 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
536 ; CHECK-NEXT:    umov w8, v0.b[0]
537 ; CHECK-NEXT:    mov v1.d[1], x8
538 ; CHECK-NEXT:    mov v0.16b, v1.16b
539 ; CHECK-NEXT:    ret
540   %e = extractelement <16 x i8> %x, i32 0
541   %z = zext i8 %e to i64
542   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
543   ret <2 x i64> %r
546 define <2 x i64> @extract1_i8_zext_insert1_i64_undef(<16 x i8> %x) {
547 ; CHECK-LABEL: extract1_i8_zext_insert1_i64_undef:
548 ; CHECK:       // %bb.0:
549 ; CHECK-NEXT:    umov w8, v0.b[1]
550 ; CHECK-NEXT:    dup v0.2d, x8
551 ; CHECK-NEXT:    ret
552   %e = extractelement <16 x i8> %x, i32 1
553   %z = zext i8 %e to i64
554   %r = insertelement <2 x i64> undef, i64 %z, i32 1
555   ret <2 x i64> %r
558 define <2 x i64> @extract1_i8_zext_insert1_i64_zero(<16 x i8> %x) {
559 ; CHECK-LABEL: extract1_i8_zext_insert1_i64_zero:
560 ; CHECK:       // %bb.0:
561 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
562 ; CHECK-NEXT:    umov w8, v0.b[1]
563 ; CHECK-NEXT:    mov v1.d[1], x8
564 ; CHECK-NEXT:    mov v0.16b, v1.16b
565 ; CHECK-NEXT:    ret
566   %e = extractelement <16 x i8> %x, i32 1
567   %z = zext i8 %e to i64
568   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
569   ret <2 x i64> %r
572 define <2 x i64> @extract2_i8_zext_insert1_i64_undef(<16 x i8> %x) {
573 ; CHECK-LABEL: extract2_i8_zext_insert1_i64_undef:
574 ; CHECK:       // %bb.0:
575 ; CHECK-NEXT:    umov w8, v0.b[2]
576 ; CHECK-NEXT:    dup v0.2d, x8
577 ; CHECK-NEXT:    ret
578   %e = extractelement <16 x i8> %x, i32 2
579   %z = zext i8 %e to i64
580   %r = insertelement <2 x i64> undef, i64 %z, i32 1
581   ret <2 x i64> %r
584 define <2 x i64> @extract2_i8_zext_insert1_i64_zero(<16 x i8> %x) {
585 ; CHECK-LABEL: extract2_i8_zext_insert1_i64_zero:
586 ; CHECK:       // %bb.0:
587 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
588 ; CHECK-NEXT:    umov w8, v0.b[2]
589 ; CHECK-NEXT:    mov v1.d[1], x8
590 ; CHECK-NEXT:    mov v0.16b, v1.16b
591 ; CHECK-NEXT:    ret
592   %e = extractelement <16 x i8> %x, i32 2
593   %z = zext i8 %e to i64
594   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
595   ret <2 x i64> %r
598 define <2 x i64> @extract3_i8_zext_insert1_i64_undef(<16 x i8> %x) {
599 ; CHECK-LABEL: extract3_i8_zext_insert1_i64_undef:
600 ; CHECK:       // %bb.0:
601 ; CHECK-NEXT:    umov w8, v0.b[3]
602 ; CHECK-NEXT:    dup v0.2d, x8
603 ; CHECK-NEXT:    ret
604   %e = extractelement <16 x i8> %x, i32 3
605   %z = zext i8 %e to i64
606   %r = insertelement <2 x i64> undef, i64 %z, i32 1
607   ret <2 x i64> %r
610 define <2 x i64> @extract3_i8_zext_insert1_i64_zero(<16 x i8> %x) {
611 ; CHECK-LABEL: extract3_i8_zext_insert1_i64_zero:
612 ; CHECK:       // %bb.0:
613 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
614 ; CHECK-NEXT:    umov w8, v0.b[3]
615 ; CHECK-NEXT:    mov v1.d[1], x8
616 ; CHECK-NEXT:    mov v0.16b, v1.16b
617 ; CHECK-NEXT:    ret
618   %e = extractelement <16 x i8> %x, i32 3
619   %z = zext i8 %e to i64
620   %r = insertelement <2 x i64> zeroinitializer, i64 %z, i32 1
621   ret <2 x i64> %r
625 ; This would crash because we did not expect to create
626 ; a shuffle for a vector where the source operand is
627 ; not the same size as the result.
628 ; TODO: Should we handle this pattern? Ie, is moving to/from
629 ; registers the optimal code?
631 define <4 x i32> @larger_bv_than_source(<4 x i16> %t0) {
632 ; CHECK-LABEL: larger_bv_than_source:
633 ; CHECK:       // %bb.0:
634 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
635 ; CHECK-NEXT:    umov w8, v0.h[2]
636 ; CHECK-NEXT:    fmov s0, w8
637 ; CHECK-NEXT:    ret
638   %t1 = extractelement <4 x i16> %t0, i32 2
639   %vgetq_lane = zext i16 %t1 to i32
640   %t2 = insertelement <4 x i32> undef, i32 %vgetq_lane, i64 0
641   ret <4 x i32> %t2