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