xref: /llvm-project/llvm/test/CodeGen/AArch64/sve-extract-element.ll (revision c2bd5c25b3634e55089d34afe922aa38eee743e2)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s | FileCheck %s
3
4target triple = "aarch64-unknown-linux-gnu"
5
6define i8 @test_lane0_16xi8(<vscale x 16 x i8> %a) #0 {
7; CHECK-LABEL: test_lane0_16xi8:
8; CHECK:       // %bb.0:
9; CHECK-NEXT:    fmov w0, s0
10; CHECK-NEXT:    ret
11  %b = extractelement <vscale x 16 x i8> %a, i32 0
12  ret i8 %b
13}
14
15define i8 @test_lane15_16xi8(<vscale x 16 x i8> %a) #0 {
16; CHECK-LABEL: test_lane15_16xi8:
17; CHECK:       // %bb.0:
18; CHECK-NEXT:    umov w0, v0.b[15]
19; CHECK-NEXT:    ret
20  %b = extractelement <vscale x 16 x i8> %a, i32 15
21  ret i8 %b
22}
23
24define i8 @test_lane16_16xi8(<vscale x 16 x i8> %a) #0 {
25; CHECK-LABEL: test_lane16_16xi8:
26; CHECK:       // %bb.0:
27; CHECK-NEXT:    mov z0.b, z0.b[16]
28; CHECK-NEXT:    fmov w0, s0
29; CHECK-NEXT:    ret
30  %b = extractelement <vscale x 16 x i8> %a, i32 16
31  ret i8 %b
32}
33
34define i16 @test_lane0_8xi16(<vscale x 8 x i16> %a) #0 {
35; CHECK-LABEL: test_lane0_8xi16:
36; CHECK:       // %bb.0:
37; CHECK-NEXT:    fmov w0, s0
38; CHECK-NEXT:    ret
39  %b = extractelement <vscale x 8 x i16> %a, i32 0
40  ret i16 %b
41}
42
43define i16 @test_lane7_8xi16(<vscale x 8 x i16> %a) #0 {
44; CHECK-LABEL: test_lane7_8xi16:
45; CHECK:       // %bb.0:
46; CHECK-NEXT:    umov w0, v0.h[7]
47; CHECK-NEXT:    ret
48  %b = extractelement <vscale x 8 x i16> %a, i32 7
49  ret i16 %b
50}
51
52define i16 @test_lane8_8xi16(<vscale x 8 x i16> %a) #0 {
53; CHECK-LABEL: test_lane8_8xi16:
54; CHECK:       // %bb.0:
55; CHECK-NEXT:    mov z0.h, z0.h[8]
56; CHECK-NEXT:    fmov w0, s0
57; CHECK-NEXT:    ret
58  %b = extractelement <vscale x 8 x i16> %a, i32 8
59  ret i16 %b
60}
61
62define i32 @test_lane0_4xi32(<vscale x 4 x i32> %a) #0 {
63; CHECK-LABEL: test_lane0_4xi32:
64; CHECK:       // %bb.0:
65; CHECK-NEXT:    fmov w0, s0
66; CHECK-NEXT:    ret
67  %b = extractelement <vscale x 4 x i32> %a, i32 0
68  ret i32 %b
69}
70
71define i32 @test_lane3_4xi32(<vscale x 4 x i32> %a) #0 {
72; CHECK-LABEL: test_lane3_4xi32:
73; CHECK:       // %bb.0:
74; CHECK-NEXT:    mov w0, v0.s[3]
75; CHECK-NEXT:    ret
76  %b = extractelement <vscale x 4 x i32> %a, i32 3
77  ret i32 %b
78}
79
80define i32 @test_lane4_4xi32(<vscale x 4 x i32> %a) #0 {
81; CHECK-LABEL: test_lane4_4xi32:
82; CHECK:       // %bb.0:
83; CHECK-NEXT:    mov z0.s, z0.s[4]
84; CHECK-NEXT:    fmov w0, s0
85; CHECK-NEXT:    ret
86  %b = extractelement <vscale x 4 x i32> %a, i32 4
87  ret i32 %b
88}
89
90define i64 @test_lane0_2xi64(<vscale x 2 x i64> %a) #0 {
91; CHECK-LABEL: test_lane0_2xi64:
92; CHECK:       // %bb.0:
93; CHECK-NEXT:    fmov x0, d0
94; CHECK-NEXT:    ret
95  %b = extractelement <vscale x 2 x i64> %a, i32 0
96  ret i64 %b
97}
98
99define i64 @test_lane1_2xi64(<vscale x 2 x i64> %a) #0 {
100; CHECK-LABEL: test_lane1_2xi64:
101; CHECK:       // %bb.0:
102; CHECK-NEXT:    mov x0, v0.d[1]
103; CHECK-NEXT:    ret
104  %b = extractelement <vscale x 2 x i64> %a, i32 1
105  ret i64 %b
106}
107
108define i64 @test_lane2_2xi64(<vscale x 2 x i64> %a) #0 {
109; CHECK-LABEL: test_lane2_2xi64:
110; CHECK:       // %bb.0:
111; CHECK-NEXT:    mov z0.d, z0.d[2]
112; CHECK-NEXT:    fmov x0, d0
113; CHECK-NEXT:    ret
114  %b = extractelement <vscale x 2 x i64> %a, i32 2
115  ret i64 %b
116}
117
118define half @test_lane0_8xf16(<vscale x 8 x half> %a) #0 {
119; CHECK-LABEL: test_lane0_8xf16:
120; CHECK:       // %bb.0:
121; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
122; CHECK-NEXT:    ret
123  %b = extractelement <vscale x 8 x half> %a, i32 0
124  ret half %b
125}
126
127define half @test_lane7_8xf16(<vscale x 8 x half> %a) #0 {
128; CHECK-LABEL: test_lane7_8xf16:
129; CHECK:       // %bb.0:
130; CHECK-NEXT:    mov z0.h, z0.h[7]
131; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
132; CHECK-NEXT:    ret
133  %b = extractelement <vscale x 8 x half> %a, i32 7
134  ret half %b
135}
136
137define half @test_lane8_8xf16(<vscale x 8 x half> %a) #0 {
138; CHECK-LABEL: test_lane8_8xf16:
139; CHECK:       // %bb.0:
140; CHECK-NEXT:    mov z0.h, z0.h[8]
141; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
142; CHECK-NEXT:    ret
143  %b = extractelement <vscale x 8 x half> %a, i32 8
144  ret half %b
145}
146
147define half @test_lane0_4xf16(<vscale x 4 x half> %a) #0 {
148; CHECK-LABEL: test_lane0_4xf16:
149; CHECK:       // %bb.0:
150; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
151; CHECK-NEXT:    ret
152  %b = extractelement <vscale x 4 x half> %a, i32 0
153  ret half %b
154}
155
156define half @test_lane3_4xf16(<vscale x 4 x half> %a) #0 {
157; CHECK-LABEL: test_lane3_4xf16:
158; CHECK:       // %bb.0:
159; CHECK-NEXT:    mov z0.s, z0.s[3]
160; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
161; CHECK-NEXT:    ret
162  %b = extractelement <vscale x 4 x half> %a, i32 3
163  ret half %b
164}
165
166define half @test_lane4_4xf16(<vscale x 4 x half> %a) #0 {
167; CHECK-LABEL: test_lane4_4xf16:
168; CHECK:       // %bb.0:
169; CHECK-NEXT:    mov z0.s, z0.s[4]
170; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
171; CHECK-NEXT:    ret
172  %b = extractelement <vscale x 4 x half> %a, i32 4
173  ret half %b
174}
175
176define half @test_lane0_2xf16(<vscale x 2 x half> %a) #0 {
177; CHECK-LABEL: test_lane0_2xf16:
178; CHECK:       // %bb.0:
179; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
180; CHECK-NEXT:    ret
181  %b = extractelement <vscale x 2 x half> %a, i32 0
182  ret half %b
183}
184
185define half @test_lane1_2xf16(<vscale x 2 x half> %a) #0 {
186; CHECK-LABEL: test_lane1_2xf16:
187; CHECK:       // %bb.0:
188; CHECK-NEXT:    mov z0.d, z0.d[1]
189; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
190; CHECK-NEXT:    ret
191  %b = extractelement <vscale x 2 x half> %a, i32 1
192  ret half %b
193}
194
195define half @test_lane2_2xf16(<vscale x 2 x half> %a) #0 {
196; CHECK-LABEL: test_lane2_2xf16:
197; CHECK:       // %bb.0:
198; CHECK-NEXT:    mov z0.d, z0.d[2]
199; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
200; CHECK-NEXT:    ret
201  %b = extractelement <vscale x 2 x half> %a, i32 2
202  ret half %b
203}
204
205define bfloat @test_lane0_8xbf16(<vscale x 8 x bfloat> %a) #0 {
206; CHECK-LABEL: test_lane0_8xbf16:
207; CHECK:       // %bb.0:
208; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
209; CHECK-NEXT:    ret
210  %b = extractelement <vscale x 8 x bfloat> %a, i32 0
211  ret bfloat %b
212}
213
214define bfloat @test_lane7_8xbf16(<vscale x 8 x bfloat> %a) #0 {
215; CHECK-LABEL: test_lane7_8xbf16:
216; CHECK:       // %bb.0:
217; CHECK-NEXT:    mov z0.h, z0.h[7]
218; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
219; CHECK-NEXT:    ret
220  %b = extractelement <vscale x 8 x bfloat> %a, i32 7
221  ret bfloat %b
222}
223
224define bfloat @test_lane8_8xbf16(<vscale x 8 x bfloat> %a) #0 {
225; CHECK-LABEL: test_lane8_8xbf16:
226; CHECK:       // %bb.0:
227; CHECK-NEXT:    mov z0.h, z0.h[8]
228; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
229; CHECK-NEXT:    ret
230  %b = extractelement <vscale x 8 x bfloat> %a, i32 8
231  ret bfloat %b
232}
233
234define bfloat @test_lane0_4xbf16(<vscale x 4 x bfloat> %a) #0 {
235; CHECK-LABEL: test_lane0_4xbf16:
236; CHECK:       // %bb.0:
237; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
238; CHECK-NEXT:    ret
239  %b = extractelement <vscale x 4 x bfloat> %a, i32 0
240  ret bfloat %b
241}
242
243define bfloat @test_lane3_4xbf16(<vscale x 4 x bfloat> %a) #0 {
244; CHECK-LABEL: test_lane3_4xbf16:
245; CHECK:       // %bb.0:
246; CHECK-NEXT:    mov z0.s, z0.s[3]
247; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
248; CHECK-NEXT:    ret
249  %b = extractelement <vscale x 4 x bfloat> %a, i32 3
250  ret bfloat %b
251}
252
253define bfloat @test_lane4_4xbf16(<vscale x 4 x bfloat> %a) #0 {
254; CHECK-LABEL: test_lane4_4xbf16:
255; CHECK:       // %bb.0:
256; CHECK-NEXT:    mov z0.s, z0.s[4]
257; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
258; CHECK-NEXT:    ret
259  %b = extractelement <vscale x 4 x bfloat> %a, i32 4
260  ret bfloat %b
261}
262
263define bfloat @test_lane0_2xbf16(<vscale x 2 x bfloat> %a) #0 {
264; CHECK-LABEL: test_lane0_2xbf16:
265; CHECK:       // %bb.0:
266; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
267; CHECK-NEXT:    ret
268  %b = extractelement <vscale x 2 x bfloat> %a, i32 0
269  ret bfloat %b
270}
271
272define bfloat @test_lane1_2xbf16(<vscale x 2 x bfloat> %a) #0 {
273; CHECK-LABEL: test_lane1_2xbf16:
274; CHECK:       // %bb.0:
275; CHECK-NEXT:    mov z0.d, z0.d[1]
276; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
277; CHECK-NEXT:    ret
278  %b = extractelement <vscale x 2 x bfloat> %a, i32 1
279  ret bfloat %b
280}
281
282define bfloat @test_lane2_2xbf16(<vscale x 2 x bfloat> %a) #0 {
283; CHECK-LABEL: test_lane2_2xbf16:
284; CHECK:       // %bb.0:
285; CHECK-NEXT:    mov z0.d, z0.d[2]
286; CHECK-NEXT:    // kill: def $h0 killed $h0 killed $z0
287; CHECK-NEXT:    ret
288  %b = extractelement <vscale x 2 x bfloat> %a, i32 2
289  ret bfloat %b
290}
291
292define float @test_lane0_4xf32(<vscale x 4 x float> %a) #0 {
293; CHECK-LABEL: test_lane0_4xf32:
294; CHECK:       // %bb.0:
295; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $z0
296; CHECK-NEXT:    ret
297  %b = extractelement <vscale x 4 x float> %a, i32 0
298  ret float %b
299}
300
301define float @test_lane3_4xf32(<vscale x 4 x float> %a) #0 {
302; CHECK-LABEL: test_lane3_4xf32:
303; CHECK:       // %bb.0:
304; CHECK-NEXT:    mov z0.s, z0.s[3]
305; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $z0
306; CHECK-NEXT:    ret
307  %b = extractelement <vscale x 4 x float> %a, i32 3
308  ret float %b
309}
310
311define float @test_lane4_4xf32(<vscale x 4 x float> %a) #0 {
312; CHECK-LABEL: test_lane4_4xf32:
313; CHECK:       // %bb.0:
314; CHECK-NEXT:    mov z0.s, z0.s[4]
315; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $z0
316; CHECK-NEXT:    ret
317  %b = extractelement <vscale x 4 x float> %a, i32 4
318  ret float %b
319}
320
321define float @test_lane0_2xf32(<vscale x 2 x float> %a) #0 {
322; CHECK-LABEL: test_lane0_2xf32:
323; CHECK:       // %bb.0:
324; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $z0
325; CHECK-NEXT:    ret
326  %b = extractelement <vscale x 2 x float> %a, i32 0
327  ret float %b
328}
329
330define float @test_lane1_2xf32(<vscale x 2 x float> %a) #0 {
331; CHECK-LABEL: test_lane1_2xf32:
332; CHECK:       // %bb.0:
333; CHECK-NEXT:    mov z0.d, z0.d[1]
334; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $z0
335; CHECK-NEXT:    ret
336  %b = extractelement <vscale x 2 x float> %a, i32 1
337  ret float %b
338}
339
340define float @test_lane2_2xf32(<vscale x 2 x float> %a) #0 {
341; CHECK-LABEL: test_lane2_2xf32:
342; CHECK:       // %bb.0:
343; CHECK-NEXT:    mov z0.d, z0.d[2]
344; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $z0
345; CHECK-NEXT:    ret
346  %b = extractelement <vscale x 2 x float> %a, i32 2
347  ret float %b
348}
349
350define double @test_lane0_2xf64(<vscale x 2 x double> %a) #0 {
351; CHECK-LABEL: test_lane0_2xf64:
352; CHECK:       // %bb.0:
353; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
354; CHECK-NEXT:    ret
355  %b = extractelement <vscale x 2 x double> %a, i32 0
356  ret double %b
357}
358
359define double @test_lane1_2xf64(<vscale x 2 x double> %a) #0 {
360; CHECK-LABEL: test_lane1_2xf64:
361; CHECK:       // %bb.0:
362; CHECK-NEXT:    mov z0.d, z0.d[1]
363; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
364; CHECK-NEXT:    ret
365  %b = extractelement <vscale x 2 x double> %a, i32 1
366  ret double %b
367}
368
369define double @test_lane2_2xf64(<vscale x 2 x double> %a) #0 {
370; CHECK-LABEL: test_lane2_2xf64:
371; CHECK:       // %bb.0:
372; CHECK-NEXT:    mov z0.d, z0.d[2]
373; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
374; CHECK-NEXT:    ret
375  %b = extractelement <vscale x 2 x double> %a, i32 2
376  ret double %b
377}
378
379define i8 @test_lanex_16xi8(<vscale x 16 x i8> %a, i32 %x) #0 {
380; CHECK-LABEL: test_lanex_16xi8:
381; CHECK:       // %bb.0:
382; CHECK-NEXT:    mov w8, w0
383; CHECK-NEXT:    whilels p0.b, xzr, x8
384; CHECK-NEXT:    lastb w0, p0, z0.b
385; CHECK-NEXT:    ret
386  %b = extractelement <vscale x 16 x i8> %a, i32 %x
387  ret i8 %b
388}
389
390define i16 @test_lanex_8xi16(<vscale x 8 x i16> %a, i32 %x) #0 {
391; CHECK-LABEL: test_lanex_8xi16:
392; CHECK:       // %bb.0:
393; CHECK-NEXT:    mov w8, w0
394; CHECK-NEXT:    whilels p0.h, xzr, x8
395; CHECK-NEXT:    lastb w0, p0, z0.h
396; CHECK-NEXT:    ret
397  %b = extractelement <vscale x 8 x i16> %a, i32 %x
398  ret i16 %b
399}
400
401define i32 @test_lanex_4xi32(<vscale x 4 x i32> %a, i32 %x) #0 {
402; CHECK-LABEL: test_lanex_4xi32:
403; CHECK:       // %bb.0:
404; CHECK-NEXT:    mov w8, w0
405; CHECK-NEXT:    whilels p0.s, xzr, x8
406; CHECK-NEXT:    lastb w0, p0, z0.s
407; CHECK-NEXT:    ret
408  %b = extractelement <vscale x 4 x i32> %a, i32 %x
409  ret i32 %b
410}
411
412define i64 @test_lanex_2xi64(<vscale x 2 x i64> %a, i32 %x) #0 {
413; CHECK-LABEL: test_lanex_2xi64:
414; CHECK:       // %bb.0:
415; CHECK-NEXT:    mov w8, w0
416; CHECK-NEXT:    whilels p0.d, xzr, x8
417; CHECK-NEXT:    lastb x0, p0, z0.d
418; CHECK-NEXT:    ret
419  %b = extractelement <vscale x 2 x i64> %a, i32 %x
420  ret i64 %b
421}
422
423define half @test_lanex_8xf16(<vscale x 8 x half> %a, i32 %x) #0 {
424; CHECK-LABEL: test_lanex_8xf16:
425; CHECK:       // %bb.0:
426; CHECK-NEXT:    mov w8, w0
427; CHECK-NEXT:    whilels p0.h, xzr, x8
428; CHECK-NEXT:    lastb h0, p0, z0.h
429; CHECK-NEXT:    ret
430  %b = extractelement <vscale x 8 x half> %a, i32 %x
431  ret half %b
432}
433
434define half @test_lanex_4xf16(<vscale x 4 x half> %a, i32 %x) #0 {
435; CHECK-LABEL: test_lanex_4xf16:
436; CHECK:       // %bb.0:
437; CHECK-NEXT:    mov w8, w0
438; CHECK-NEXT:    whilels p0.s, xzr, x8
439; CHECK-NEXT:    lastb h0, p0, z0.h
440; CHECK-NEXT:    ret
441  %b = extractelement <vscale x 4 x half> %a, i32 %x
442  ret half %b
443}
444
445define half @test_lanex_2xf16(<vscale x 2 x half> %a, i32 %x) #0 {
446; CHECK-LABEL: test_lanex_2xf16:
447; CHECK:       // %bb.0:
448; CHECK-NEXT:    mov w8, w0
449; CHECK-NEXT:    whilels p0.d, xzr, x8
450; CHECK-NEXT:    lastb h0, p0, z0.h
451; CHECK-NEXT:    ret
452  %b = extractelement <vscale x 2 x half> %a, i32 %x
453  ret half %b
454}
455
456define bfloat @test_lanex_8xbf16(<vscale x 8 x bfloat> %a, i32 %x) #0 {
457; CHECK-LABEL: test_lanex_8xbf16:
458; CHECK:       // %bb.0:
459; CHECK-NEXT:    mov w8, w0
460; CHECK-NEXT:    whilels p0.h, xzr, x8
461; CHECK-NEXT:    lastb h0, p0, z0.h
462; CHECK-NEXT:    ret
463  %b = extractelement <vscale x 8 x bfloat> %a, i32 %x
464  ret bfloat %b
465}
466
467define bfloat @test_lanex_4xbf16(<vscale x 4 x bfloat> %a, i32 %x) #0 {
468; CHECK-LABEL: test_lanex_4xbf16:
469; CHECK:       // %bb.0:
470; CHECK-NEXT:    mov w8, w0
471; CHECK-NEXT:    whilels p0.s, xzr, x8
472; CHECK-NEXT:    lastb h0, p0, z0.h
473; CHECK-NEXT:    ret
474  %b = extractelement <vscale x 4 x bfloat> %a, i32 %x
475  ret bfloat %b
476}
477
478define bfloat @test_lanex_2xbf16(<vscale x 2 x bfloat> %a, i32 %x) #0 {
479; CHECK-LABEL: test_lanex_2xbf16:
480; CHECK:       // %bb.0:
481; CHECK-NEXT:    mov w8, w0
482; CHECK-NEXT:    whilels p0.d, xzr, x8
483; CHECK-NEXT:    lastb h0, p0, z0.h
484; CHECK-NEXT:    ret
485  %b = extractelement <vscale x 2 x bfloat> %a, i32 %x
486  ret bfloat %b
487}
488
489define float @test_lanex_4xf32(<vscale x 4 x float> %a, i32 %x) #0 {
490; CHECK-LABEL: test_lanex_4xf32:
491; CHECK:       // %bb.0:
492; CHECK-NEXT:    mov w8, w0
493; CHECK-NEXT:    whilels p0.s, xzr, x8
494; CHECK-NEXT:    lastb s0, p0, z0.s
495; CHECK-NEXT:    ret
496  %b = extractelement <vscale x 4 x float> %a, i32 %x
497  ret float %b
498}
499
500define float @test_lanex_2xf32(<vscale x 2 x float> %a, i32 %x) #0 {
501; CHECK-LABEL: test_lanex_2xf32:
502; CHECK:       // %bb.0:
503; CHECK-NEXT:    mov w8, w0
504; CHECK-NEXT:    whilels p0.d, xzr, x8
505; CHECK-NEXT:    lastb s0, p0, z0.s
506; CHECK-NEXT:    ret
507  %b = extractelement <vscale x 2 x float> %a, i32 %x
508  ret float %b
509}
510
511define double @test_lanex_2xf64(<vscale x 2 x double> %a, i32 %x) #0 {
512; CHECK-LABEL: test_lanex_2xf64:
513; CHECK:       // %bb.0:
514; CHECK-NEXT:    mov w8, w0
515; CHECK-NEXT:    whilels p0.d, xzr, x8
516; CHECK-NEXT:    lastb d0, p0, z0.d
517; CHECK-NEXT:    ret
518  %b = extractelement <vscale x 2 x double> %a, i32 %x
519  ret double %b
520}
521
522; Deliberately choose an index that is undefined
523define i32 @test_undef_lane_4xi32(<vscale x 4 x i32> %a) #0 {
524; CHECK-LABEL: test_undef_lane_4xi32:
525; CHECK:       // %bb.0:
526; CHECK-NEXT:    fmov w0, s0
527; CHECK-NEXT:    ret
528  %b = extractelement <vscale x 4 x i32> %a, i32 undef
529  ret i32 %b
530}
531
532define i8 @extract_of_insert_undef_16xi8(i8 %a) #0 {
533; CHECK-LABEL: extract_of_insert_undef_16xi8:
534; CHECK:       // %bb.0:
535; CHECK-NEXT:    ret
536  %b = insertelement <vscale x 16 x i8> undef, i8 %a, i32 0
537  %c = extractelement <vscale x 16 x i8> %b, i32 0
538  ret i8 %c
539}
540
541define i8 @extract0_of_insert0_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {
542; CHECK-LABEL: extract0_of_insert0_16xi8:
543; CHECK:       // %bb.0:
544; CHECK-NEXT:    ret
545  %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 0
546  %d = extractelement <vscale x 16 x i8> %c, i32 0
547  ret i8 %d
548}
549
550define i8 @extract64_of_insert64_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {
551; CHECK-LABEL: extract64_of_insert64_16xi8:
552; CHECK:       // %bb.0:
553; CHECK-NEXT:    ret
554  %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 64
555  %d = extractelement <vscale x 16 x i8> %c, i32 64
556  ret i8 %d
557}
558
559define i8 @extract_of_insert_diff_lanes_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {
560; CHECK-LABEL: extract_of_insert_diff_lanes_16xi8:
561; CHECK:       // %bb.0:
562; CHECK-NEXT:    umov w0, v0.b[3]
563; CHECK-NEXT:    ret
564  %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 0
565  %d = extractelement <vscale x 16 x i8> %c, i32 3
566  ret i8 %d
567}
568
569define i8 @test_lane0_zero_16xi8(<vscale x 16 x i8> %a) #0 {
570; CHECK-LABEL: test_lane0_zero_16xi8:
571; CHECK:       // %bb.0:
572; CHECK-NEXT:    mov w0, wzr
573; CHECK-NEXT:    ret
574  %b = extractelement <vscale x 16 x i8> zeroinitializer, i32 0
575  ret i8 %b
576}
577
578; The DAG combiner should fold the extract of a splat to give element zero
579; of the splat, i.e. %x. If the index is beyond the end of the scalable
580; vector the result is undefined anyway.
581define i64 @test_lanex_splat_2xi64(i64 %x, i32 %y) #0 {
582; CHECK-LABEL: test_lanex_splat_2xi64:
583; CHECK:       // %bb.0:
584; CHECK-NEXT:    ret
585  %a = insertelement <vscale x 2 x i64> undef, i64 %x, i32 0
586  %b = shufflevector <vscale x 2 x i64> %a, <vscale x 2 x i64> undef, <vscale x 2 x i32> zeroinitializer
587  %c = extractelement <vscale x 2 x i64> %b, i32 %y
588  ret i64 %c
589}
590
591define i1 @test_lane0_16xi1(<vscale x 16 x i1> %a) #0 {
592; CHECK-LABEL: test_lane0_16xi1:
593; CHECK:       // %bb.0:
594; CHECK-NEXT:    mov z0.b, p0/z, #1 // =0x1
595; CHECK-NEXT:    fmov w8, s0
596; CHECK-NEXT:    and w0, w8, #0x1
597; CHECK-NEXT:    ret
598  %b = extractelement <vscale x 16 x i1> %a, i32 0
599  ret i1 %b
600}
601
602define i1 @test_lane9_8xi1(<vscale x 8 x i1> %a) #0 {
603; CHECK-LABEL: test_lane9_8xi1:
604; CHECK:       // %bb.0:
605; CHECK-NEXT:    mov z0.h, p0/z, #1 // =0x1
606; CHECK-NEXT:    mov z0.h, z0.h[9]
607; CHECK-NEXT:    fmov w8, s0
608; CHECK-NEXT:    and w0, w8, #0x1
609; CHECK-NEXT:    ret
610  %b = extractelement <vscale x 8 x i1> %a, i32 9
611  ret i1 %b
612}
613
614define i1 @test_last_8xi1(<vscale x 8 x i1> %a) #0 {
615; CHECK-LABEL: test_last_8xi1:
616; CHECK:       // %bb.0:
617; CHECK-NEXT:    mov x8, #-1 // =0xffffffffffffffff
618; CHECK-NEXT:    mov z0.h, p0/z, #1 // =0x1
619; CHECK-NEXT:    whilels p0.h, xzr, x8
620; CHECK-NEXT:    lastb w8, p0, z0.h
621; CHECK-NEXT:    and w0, w8, #0x1
622; CHECK-NEXT:    ret
623  %vscale = call i64 @llvm.vscale.i64()
624  %shl = shl nuw nsw i64 %vscale, 3
625  %idx = add nuw nsw i64 %shl, -1
626  %bit = extractelement <vscale x 8 x i1> %a, i64 %idx
627  ret i1 %bit
628}
629
630define i1 @test_lanex_4xi1(<vscale x 4 x i1> %a, i32 %x) #0 {
631; CHECK-LABEL: test_lanex_4xi1:
632; CHECK:       // %bb.0:
633; CHECK-NEXT:    mov z0.s, p0/z, #1 // =0x1
634; CHECK-NEXT:    mov w8, w0
635; CHECK-NEXT:    whilels p0.s, xzr, x8
636; CHECK-NEXT:    lastb w8, p0, z0.s
637; CHECK-NEXT:    and w0, w8, #0x1
638; CHECK-NEXT:    ret
639  %b = extractelement <vscale x 4 x i1> %a, i32 %x
640  ret i1 %b
641}
642
643define i1 @test_lane4_2xi1(<vscale x 2 x i1> %a) #0 {
644; CHECK-LABEL: test_lane4_2xi1:
645; CHECK:       // %bb.0:
646; CHECK-NEXT:    mov z0.d, p0/z, #1 // =0x1
647; CHECK-NEXT:    mov z0.s, z0.s[8]
648; CHECK-NEXT:    fmov w8, s0
649; CHECK-NEXT:    and w0, w8, #0x1
650; CHECK-NEXT:    ret
651  %b = extractelement <vscale x 2 x i1> %a, i32 4
652  ret i1 %b
653}
654
655declare i64 @llvm.vscale.i64()
656
657attributes #0 = { "target-features"="+sve,+bf16" }
658