xref: /llvm-project/llvm/test/CodeGen/AArch64/build-vector-extract.ll (revision 4fc417ec376cbd9646cbfd4f4c4659b4202f328e)
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:    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
26}
27
28define <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
38}
39
40define <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
51}
52
53define <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
63}
64
65define <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
76}
77
78define <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
88}
89
90define <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
101}
102
103define <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
113}
114
115define <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
127}
128
129define <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
139}
140
141define <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
153}
154
155define <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
164}
165
166define <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
178}
179
180define <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
190}
191
192define <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
204}
205
206define <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
216}
217
218define <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
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:    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
256}
257
258define <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
268}
269
270define <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
282}
283
284define <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
294}
295
296define <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
308}
309
310define <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
320}
321
322define <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
334}
335
336define <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
346}
347
348define <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
360}
361
362define <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
372}
373
374define <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
386}
387
388define <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
398}
399
400define <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
412}
413
414; i8
415
416define <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
426}
427
428define <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
440}
441
442define <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
452}
453
454define <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
466}
467
468define <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
478}
479
480define <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
492}
493
494define <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
504}
505
506define <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
518}
519
520define <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
530}
531
532define <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
544}
545
546define <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
556}
557
558define <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
570}
571
572define <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
582}
583
584define <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
596}
597
598define <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
608}
609
610define <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
622}
623
624
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?
630
631define <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
642}
643
644