1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s | FileCheck %s
4 target triple = "aarch64-unknown-linux-gnu"
6 define i8 @test_lane0_16xi8(<vscale x 16 x i8> %a) #0 {
7 ; CHECK-LABEL: test_lane0_16xi8:
9 ; CHECK-NEXT: fmov w0, s0
11 %b = extractelement <vscale x 16 x i8> %a, i32 0
15 define i8 @test_lane15_16xi8(<vscale x 16 x i8> %a) #0 {
16 ; CHECK-LABEL: test_lane15_16xi8:
18 ; CHECK-NEXT: umov w0, v0.b[15]
20 %b = extractelement <vscale x 16 x i8> %a, i32 15
24 define i8 @test_lane16_16xi8(<vscale x 16 x i8> %a) #0 {
25 ; CHECK-LABEL: test_lane16_16xi8:
27 ; CHECK-NEXT: mov z0.b, z0.b[16]
28 ; CHECK-NEXT: fmov w0, s0
30 %b = extractelement <vscale x 16 x i8> %a, i32 16
34 define i16 @test_lane0_8xi16(<vscale x 8 x i16> %a) #0 {
35 ; CHECK-LABEL: test_lane0_8xi16:
37 ; CHECK-NEXT: fmov w0, s0
39 %b = extractelement <vscale x 8 x i16> %a, i32 0
43 define i16 @test_lane7_8xi16(<vscale x 8 x i16> %a) #0 {
44 ; CHECK-LABEL: test_lane7_8xi16:
46 ; CHECK-NEXT: umov w0, v0.h[7]
48 %b = extractelement <vscale x 8 x i16> %a, i32 7
52 define i16 @test_lane8_8xi16(<vscale x 8 x i16> %a) #0 {
53 ; CHECK-LABEL: test_lane8_8xi16:
55 ; CHECK-NEXT: mov z0.h, z0.h[8]
56 ; CHECK-NEXT: fmov w0, s0
58 %b = extractelement <vscale x 8 x i16> %a, i32 8
62 define i32 @test_lane0_4xi32(<vscale x 4 x i32> %a) #0 {
63 ; CHECK-LABEL: test_lane0_4xi32:
65 ; CHECK-NEXT: fmov w0, s0
67 %b = extractelement <vscale x 4 x i32> %a, i32 0
71 define i32 @test_lane3_4xi32(<vscale x 4 x i32> %a) #0 {
72 ; CHECK-LABEL: test_lane3_4xi32:
74 ; CHECK-NEXT: mov w0, v0.s[3]
76 %b = extractelement <vscale x 4 x i32> %a, i32 3
80 define i32 @test_lane4_4xi32(<vscale x 4 x i32> %a) #0 {
81 ; CHECK-LABEL: test_lane4_4xi32:
83 ; CHECK-NEXT: mov z0.s, z0.s[4]
84 ; CHECK-NEXT: fmov w0, s0
86 %b = extractelement <vscale x 4 x i32> %a, i32 4
90 define i64 @test_lane0_2xi64(<vscale x 2 x i64> %a) #0 {
91 ; CHECK-LABEL: test_lane0_2xi64:
93 ; CHECK-NEXT: fmov x0, d0
95 %b = extractelement <vscale x 2 x i64> %a, i32 0
99 define i64 @test_lane1_2xi64(<vscale x 2 x i64> %a) #0 {
100 ; CHECK-LABEL: test_lane1_2xi64:
102 ; CHECK-NEXT: mov x0, v0.d[1]
104 %b = extractelement <vscale x 2 x i64> %a, i32 1
108 define i64 @test_lane2_2xi64(<vscale x 2 x i64> %a) #0 {
109 ; CHECK-LABEL: test_lane2_2xi64:
111 ; CHECK-NEXT: mov z0.d, z0.d[2]
112 ; CHECK-NEXT: fmov x0, d0
114 %b = extractelement <vscale x 2 x i64> %a, i32 2
118 define half @test_lane0_8xf16(<vscale x 8 x half> %a) #0 {
119 ; CHECK-LABEL: test_lane0_8xf16:
121 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
123 %b = extractelement <vscale x 8 x half> %a, i32 0
127 define half @test_lane7_8xf16(<vscale x 8 x half> %a) #0 {
128 ; CHECK-LABEL: test_lane7_8xf16:
130 ; CHECK-NEXT: mov z0.h, z0.h[7]
131 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
133 %b = extractelement <vscale x 8 x half> %a, i32 7
137 define half @test_lane8_8xf16(<vscale x 8 x half> %a) #0 {
138 ; CHECK-LABEL: test_lane8_8xf16:
140 ; CHECK-NEXT: mov z0.h, z0.h[8]
141 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
143 %b = extractelement <vscale x 8 x half> %a, i32 8
147 define half @test_lane0_4xf16(<vscale x 4 x half> %a) #0 {
148 ; CHECK-LABEL: test_lane0_4xf16:
150 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
152 %b = extractelement <vscale x 4 x half> %a, i32 0
156 define half @test_lane3_4xf16(<vscale x 4 x half> %a) #0 {
157 ; CHECK-LABEL: test_lane3_4xf16:
159 ; CHECK-NEXT: mov z0.s, z0.s[3]
160 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
162 %b = extractelement <vscale x 4 x half> %a, i32 3
166 define half @test_lane4_4xf16(<vscale x 4 x half> %a) #0 {
167 ; CHECK-LABEL: test_lane4_4xf16:
169 ; CHECK-NEXT: mov z0.s, z0.s[4]
170 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
172 %b = extractelement <vscale x 4 x half> %a, i32 4
176 define half @test_lane0_2xf16(<vscale x 2 x half> %a) #0 {
177 ; CHECK-LABEL: test_lane0_2xf16:
179 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
181 %b = extractelement <vscale x 2 x half> %a, i32 0
185 define half @test_lane1_2xf16(<vscale x 2 x half> %a) #0 {
186 ; CHECK-LABEL: test_lane1_2xf16:
188 ; CHECK-NEXT: mov z0.d, z0.d[1]
189 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
191 %b = extractelement <vscale x 2 x half> %a, i32 1
195 define half @test_lane2_2xf16(<vscale x 2 x half> %a) #0 {
196 ; CHECK-LABEL: test_lane2_2xf16:
198 ; CHECK-NEXT: mov z0.d, z0.d[2]
199 ; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0
201 %b = extractelement <vscale x 2 x half> %a, i32 2
205 define float @test_lane0_4xf32(<vscale x 4 x float> %a) #0 {
206 ; CHECK-LABEL: test_lane0_4xf32:
208 ; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0
210 %b = extractelement <vscale x 4 x float> %a, i32 0
214 define float @test_lane3_4xf32(<vscale x 4 x float> %a) #0 {
215 ; CHECK-LABEL: test_lane3_4xf32:
217 ; CHECK-NEXT: mov z0.s, z0.s[3]
218 ; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0
220 %b = extractelement <vscale x 4 x float> %a, i32 3
224 define float @test_lane4_4xf32(<vscale x 4 x float> %a) #0 {
225 ; CHECK-LABEL: test_lane4_4xf32:
227 ; CHECK-NEXT: mov z0.s, z0.s[4]
228 ; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0
230 %b = extractelement <vscale x 4 x float> %a, i32 4
234 define float @test_lane0_2xf32(<vscale x 2 x float> %a) #0 {
235 ; CHECK-LABEL: test_lane0_2xf32:
237 ; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0
239 %b = extractelement <vscale x 2 x float> %a, i32 0
243 define float @test_lane1_2xf32(<vscale x 2 x float> %a) #0 {
244 ; CHECK-LABEL: test_lane1_2xf32:
246 ; CHECK-NEXT: mov z0.d, z0.d[1]
247 ; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0
249 %b = extractelement <vscale x 2 x float> %a, i32 1
253 define float @test_lane2_2xf32(<vscale x 2 x float> %a) #0 {
254 ; CHECK-LABEL: test_lane2_2xf32:
256 ; CHECK-NEXT: mov z0.d, z0.d[2]
257 ; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0
259 %b = extractelement <vscale x 2 x float> %a, i32 2
263 define double @test_lane0_2xf64(<vscale x 2 x double> %a) #0 {
264 ; CHECK-LABEL: test_lane0_2xf64:
266 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0
268 %b = extractelement <vscale x 2 x double> %a, i32 0
272 define double @test_lane1_2xf64(<vscale x 2 x double> %a) #0 {
273 ; CHECK-LABEL: test_lane1_2xf64:
275 ; CHECK-NEXT: mov z0.d, z0.d[1]
276 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0
278 %b = extractelement <vscale x 2 x double> %a, i32 1
282 define double @test_lane2_2xf64(<vscale x 2 x double> %a) #0 {
283 ; CHECK-LABEL: test_lane2_2xf64:
285 ; CHECK-NEXT: mov z0.d, z0.d[2]
286 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0
288 %b = extractelement <vscale x 2 x double> %a, i32 2
292 define i8 @test_lanex_16xi8(<vscale x 16 x i8> %a, i32 %x) #0 {
293 ; CHECK-LABEL: test_lanex_16xi8:
295 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
296 ; CHECK-NEXT: sxtw x8, w0
297 ; CHECK-NEXT: whilels p0.b, xzr, x8
298 ; CHECK-NEXT: lastb w0, p0, z0.b
300 %b = extractelement <vscale x 16 x i8> %a, i32 %x
304 define i16 @test_lanex_8xi16(<vscale x 8 x i16> %a, i32 %x) #0 {
305 ; CHECK-LABEL: test_lanex_8xi16:
307 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
308 ; CHECK-NEXT: sxtw x8, w0
309 ; CHECK-NEXT: whilels p0.h, xzr, x8
310 ; CHECK-NEXT: lastb w0, p0, z0.h
312 %b = extractelement <vscale x 8 x i16> %a, i32 %x
316 define i32 @test_lanex_4xi32(<vscale x 4 x i32> %a, i32 %x) #0 {
317 ; CHECK-LABEL: test_lanex_4xi32:
319 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
320 ; CHECK-NEXT: sxtw x8, w0
321 ; CHECK-NEXT: whilels p0.s, xzr, x8
322 ; CHECK-NEXT: lastb w0, p0, z0.s
324 %b = extractelement <vscale x 4 x i32> %a, i32 %x
328 define i64 @test_lanex_2xi64(<vscale x 2 x i64> %a, i32 %x) #0 {
329 ; CHECK-LABEL: test_lanex_2xi64:
331 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
332 ; CHECK-NEXT: sxtw x8, w0
333 ; CHECK-NEXT: whilels p0.d, xzr, x8
334 ; CHECK-NEXT: lastb x0, p0, z0.d
336 %b = extractelement <vscale x 2 x i64> %a, i32 %x
340 define half @test_lanex_8xf16(<vscale x 8 x half> %a, i32 %x) #0 {
341 ; CHECK-LABEL: test_lanex_8xf16:
343 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
344 ; CHECK-NEXT: sxtw x8, w0
345 ; CHECK-NEXT: whilels p0.h, xzr, x8
346 ; CHECK-NEXT: lastb h0, p0, z0.h
348 %b = extractelement <vscale x 8 x half> %a, i32 %x
352 define half @test_lanex_4xf16(<vscale x 4 x half> %a, i32 %x) #0 {
353 ; CHECK-LABEL: test_lanex_4xf16:
355 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
356 ; CHECK-NEXT: sxtw x8, w0
357 ; CHECK-NEXT: whilels p0.s, xzr, x8
358 ; CHECK-NEXT: lastb h0, p0, z0.h
360 %b = extractelement <vscale x 4 x half> %a, i32 %x
364 define half @test_lanex_2xf16(<vscale x 2 x half> %a, i32 %x) #0 {
365 ; CHECK-LABEL: test_lanex_2xf16:
367 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
368 ; CHECK-NEXT: sxtw x8, w0
369 ; CHECK-NEXT: whilels p0.d, xzr, x8
370 ; CHECK-NEXT: lastb h0, p0, z0.h
372 %b = extractelement <vscale x 2 x half> %a, i32 %x
376 define float @test_lanex_4xf32(<vscale x 4 x float> %a, i32 %x) #0 {
377 ; CHECK-LABEL: test_lanex_4xf32:
379 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
380 ; CHECK-NEXT: sxtw x8, w0
381 ; CHECK-NEXT: whilels p0.s, xzr, x8
382 ; CHECK-NEXT: lastb s0, p0, z0.s
384 %b = extractelement <vscale x 4 x float> %a, i32 %x
388 define float @test_lanex_2xf32(<vscale x 2 x float> %a, i32 %x) #0 {
389 ; CHECK-LABEL: test_lanex_2xf32:
391 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
392 ; CHECK-NEXT: sxtw x8, w0
393 ; CHECK-NEXT: whilels p0.d, xzr, x8
394 ; CHECK-NEXT: lastb s0, p0, z0.s
396 %b = extractelement <vscale x 2 x float> %a, i32 %x
400 define double @test_lanex_2xf64(<vscale x 2 x double> %a, i32 %x) #0 {
401 ; CHECK-LABEL: test_lanex_2xf64:
403 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
404 ; CHECK-NEXT: sxtw x8, w0
405 ; CHECK-NEXT: whilels p0.d, xzr, x8
406 ; CHECK-NEXT: lastb d0, p0, z0.d
408 %b = extractelement <vscale x 2 x double> %a, i32 %x
412 ; Deliberately choose an index that is undefined
413 define i32 @test_undef_lane_4xi32(<vscale x 4 x i32> %a) #0 {
414 ; CHECK-LABEL: test_undef_lane_4xi32:
416 ; CHECK-NEXT: fmov w0, s0
418 %b = extractelement <vscale x 4 x i32> %a, i32 undef
422 define i8 @extract_of_insert_undef_16xi8(i8 %a) #0 {
423 ; CHECK-LABEL: extract_of_insert_undef_16xi8:
426 %b = insertelement <vscale x 16 x i8> undef, i8 %a, i32 0
427 %c = extractelement <vscale x 16 x i8> %b, i32 0
431 define i8 @extract0_of_insert0_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {
432 ; CHECK-LABEL: extract0_of_insert0_16xi8:
435 %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 0
436 %d = extractelement <vscale x 16 x i8> %c, i32 0
440 define i8 @extract64_of_insert64_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {
441 ; CHECK-LABEL: extract64_of_insert64_16xi8:
444 %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 64
445 %d = extractelement <vscale x 16 x i8> %c, i32 64
449 define i8 @extract_of_insert_diff_lanes_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {
450 ; CHECK-LABEL: extract_of_insert_diff_lanes_16xi8:
452 ; CHECK-NEXT: umov w0, v0.b[3]
454 %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 0
455 %d = extractelement <vscale x 16 x i8> %c, i32 3
459 define i8 @test_lane0_zero_16xi8(<vscale x 16 x i8> %a) #0 {
460 ; CHECK-LABEL: test_lane0_zero_16xi8:
462 ; CHECK-NEXT: mov w0, wzr
464 %b = extractelement <vscale x 16 x i8> zeroinitializer, i32 0
468 ; The DAG combiner should fold the extract of a splat to give element zero
469 ; of the splat, i.e. %x. If the index is beyond the end of the scalable
470 ; vector the result is undefined anyway.
471 define i64 @test_lanex_splat_2xi64(i64 %x, i32 %y) #0 {
472 ; CHECK-LABEL: test_lanex_splat_2xi64:
475 %a = insertelement <vscale x 2 x i64> undef, i64 %x, i32 0
476 %b = shufflevector <vscale x 2 x i64> %a, <vscale x 2 x i64> undef, <vscale x 2 x i32> zeroinitializer
477 %c = extractelement <vscale x 2 x i64> %b, i32 %y
481 define i1 @test_lane0_16xi1(<vscale x 16 x i1> %a) #0 {
482 ; CHECK-LABEL: test_lane0_16xi1:
484 ; CHECK-NEXT: mov z0.b, p0/z, #1 // =0x1
485 ; CHECK-NEXT: fmov w8, s0
486 ; CHECK-NEXT: and w0, w8, #0x1
488 %b = extractelement <vscale x 16 x i1> %a, i32 0
492 define i1 @test_lane9_8xi1(<vscale x 8 x i1> %a) #0 {
493 ; CHECK-LABEL: test_lane9_8xi1:
495 ; CHECK-NEXT: mov z0.h, p0/z, #1 // =0x1
496 ; CHECK-NEXT: mov z0.h, z0.h[9]
497 ; CHECK-NEXT: fmov w8, s0
498 ; CHECK-NEXT: and w0, w8, #0x1
500 %b = extractelement <vscale x 8 x i1> %a, i32 9
504 define i1 @test_lanex_4xi1(<vscale x 4 x i1> %a, i32 %x) #0 {
505 ; CHECK-LABEL: test_lanex_4xi1:
507 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
508 ; CHECK-NEXT: sxtw x8, w0
509 ; CHECK-NEXT: whilels p1.s, xzr, x8
510 ; CHECK-NEXT: mov z0.s, p0/z, #1 // =0x1
511 ; CHECK-NEXT: lastb w8, p1, z0.s
512 ; CHECK-NEXT: and w0, w8, #0x1
514 %b = extractelement <vscale x 4 x i1> %a, i32 %x
518 define i1 @test_lane4_2xi1(<vscale x 2 x i1> %a) #0 {
519 ; CHECK-LABEL: test_lane4_2xi1:
521 ; CHECK-NEXT: mov z0.d, p0/z, #1 // =0x1
522 ; CHECK-NEXT: mov z0.d, z0.d[4]
523 ; CHECK-NEXT: fmov x8, d0
524 ; CHECK-NEXT: and w0, w8, #0x1
526 %b = extractelement <vscale x 2 x i1> %a, i32 4
530 attributes #0 = { "target-features"="+sve" }