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