789 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s | FileCheck %s3 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, s010; CHECK-NEXT: ret11 %b = extractelement <vscale x 16 x i8> %a, i32 012 ret i8 %b13}14 15define i32 @test_lane0_16xi8_zext_i32(<vscale x 16 x i8> %a) #0 {16; CHECK-LABEL: test_lane0_16xi8_zext_i32:17; CHECK: // %bb.0:18; CHECK-NEXT: umov w0, v0.b[0]19; CHECK-NEXT: ret20 %b = extractelement <vscale x 16 x i8> %a, i32 021 %c = zext i8 %b to i3222 ret i32 %c23}24 25define i64 @test_lane0_16xi8_zext_i64(<vscale x 16 x i8> %a) #0 {26; CHECK-LABEL: test_lane0_16xi8_zext_i64:27; CHECK: // %bb.0:28; CHECK-NEXT: umov w0, v0.b[0]29; CHECK-NEXT: ret30 %b = extractelement <vscale x 16 x i8> %a, i32 031 %c = zext i8 %b to i6432 ret i64 %c33}34 35define i8 @test_lane15_16xi8(<vscale x 16 x i8> %a) #0 {36; CHECK-LABEL: test_lane15_16xi8:37; CHECK: // %bb.0:38; CHECK-NEXT: umov w0, v0.b[15]39; CHECK-NEXT: ret40 %b = extractelement <vscale x 16 x i8> %a, i32 1541 ret i8 %b42}43 44define i32 @test_lane15_16xi8_zext_i32(<vscale x 16 x i8> %a) #0 {45; CHECK-LABEL: test_lane15_16xi8_zext_i32:46; CHECK: // %bb.0:47; CHECK-NEXT: umov w0, v0.b[15]48; CHECK-NEXT: ret49 %b = extractelement <vscale x 16 x i8> %a, i32 1550 %c = zext i8 %b to i3251 ret i32 %c52}53 54define i64 @test_lane15_16xi8_zext_i64(<vscale x 16 x i8> %a) #0 {55; CHECK-LABEL: test_lane15_16xi8_zext_i64:56; CHECK: // %bb.0:57; CHECK-NEXT: umov w0, v0.b[15]58; CHECK-NEXT: ret59 %b = extractelement <vscale x 16 x i8> %a, i32 1560 %c = zext i8 %b to i6461 ret i64 %c62}63 64define i8 @test_lane16_16xi8(<vscale x 16 x i8> %a) #0 {65; CHECK-LABEL: test_lane16_16xi8:66; CHECK: // %bb.0:67; CHECK-NEXT: mov z0.b, z0.b[16]68; CHECK-NEXT: fmov w0, s069; CHECK-NEXT: ret70 %b = extractelement <vscale x 16 x i8> %a, i32 1671 ret i8 %b72}73 74; FIXME: FMOV+AND -> UMOV.75define i32 @test_lane16_16xi8_zext_i32(<vscale x 16 x i8> %a) #0 {76; CHECK-LABEL: test_lane16_16xi8_zext_i32:77; CHECK: // %bb.0:78; CHECK-NEXT: mov z0.b, z0.b[16]79; CHECK-NEXT: fmov w8, s080; CHECK-NEXT: and w0, w8, #0xff81; CHECK-NEXT: ret82 %b = extractelement <vscale x 16 x i8> %a, i32 1683 %c = zext i8 %b to i3284 ret i32 %c85}86 87; FIXME: FMOV+AND -> UMOV.88define i64 @test_lane16_16xi8_zext_i64(<vscale x 16 x i8> %a) #0 {89; CHECK-LABEL: test_lane16_16xi8_zext_i64:90; CHECK: // %bb.0:91; CHECK-NEXT: mov z0.b, z0.b[16]92; CHECK-NEXT: fmov w8, s093; CHECK-NEXT: and x0, x8, #0xff94; CHECK-NEXT: ret95 %b = extractelement <vscale x 16 x i8> %a, i32 1696 %c = zext i8 %b to i6497 ret i64 %c98}99 100define i16 @test_lane0_8xi16(<vscale x 8 x i16> %a) #0 {101; CHECK-LABEL: test_lane0_8xi16:102; CHECK: // %bb.0:103; CHECK-NEXT: fmov w0, s0104; CHECK-NEXT: ret105 %b = extractelement <vscale x 8 x i16> %a, i32 0106 ret i16 %b107}108 109define i32 @test_lane0_8xi16_zext_i32(<vscale x 8 x i16> %a) #0 {110; CHECK-LABEL: test_lane0_8xi16_zext_i32:111; CHECK: // %bb.0:112; CHECK-NEXT: umov w0, v0.h[0]113; CHECK-NEXT: ret114 %b = extractelement <vscale x 8 x i16> %a, i32 0115 %c = zext i16 %b to i32116 ret i32 %c117}118 119define i64 @test_lane0_8xi16_zext_i64(<vscale x 8 x i16> %a) #0 {120; CHECK-LABEL: test_lane0_8xi16_zext_i64:121; CHECK: // %bb.0:122; CHECK-NEXT: umov w0, v0.h[0]123; CHECK-NEXT: ret124 %b = extractelement <vscale x 8 x i16> %a, i32 0125 %c = zext i16 %b to i64126 ret i64 %c127}128 129define i16 @test_lane7_8xi16(<vscale x 8 x i16> %a) #0 {130; CHECK-LABEL: test_lane7_8xi16:131; CHECK: // %bb.0:132; CHECK-NEXT: umov w0, v0.h[7]133; CHECK-NEXT: ret134 %b = extractelement <vscale x 8 x i16> %a, i32 7135 ret i16 %b136}137 138define i32 @test_lane7_8xi16_zext_i32(<vscale x 8 x i16> %a) #0 {139; CHECK-LABEL: test_lane7_8xi16_zext_i32:140; CHECK: // %bb.0:141; CHECK-NEXT: umov w0, v0.h[7]142; CHECK-NEXT: ret143 %b = extractelement <vscale x 8 x i16> %a, i32 7144 %c = zext i16 %b to i32145 ret i32 %c146}147 148define i64 @test_lane7_8xi16_zext_i64(<vscale x 8 x i16> %a) #0 {149; CHECK-LABEL: test_lane7_8xi16_zext_i64:150; CHECK: // %bb.0:151; CHECK-NEXT: umov w0, v0.h[7]152; CHECK-NEXT: ret153 %b = extractelement <vscale x 8 x i16> %a, i32 7154 %c = zext i16 %b to i64155 ret i64 %c156}157 158define i16 @test_lane8_8xi16(<vscale x 8 x i16> %a) #0 {159; CHECK-LABEL: test_lane8_8xi16:160; CHECK: // %bb.0:161; CHECK-NEXT: mov z0.h, z0.h[8]162; CHECK-NEXT: fmov w0, s0163; CHECK-NEXT: ret164 %b = extractelement <vscale x 8 x i16> %a, i32 8165 ret i16 %b166}167 168; FIXME: FMOV+AND -> UMOV.169define i32 @test_lane8_8xi16_zext_i32(<vscale x 8 x i16> %a) #0 {170; CHECK-LABEL: test_lane8_8xi16_zext_i32:171; CHECK: // %bb.0:172; CHECK-NEXT: mov z0.h, z0.h[8]173; CHECK-NEXT: fmov w8, s0174; CHECK-NEXT: and w0, w8, #0xffff175; CHECK-NEXT: ret176 %b = extractelement <vscale x 8 x i16> %a, i32 8177 %c = zext i16 %b to i32178 ret i32 %c179}180 181; FIXME: FMOV+AND -> UMOV.182define i64 @test_lane8_8xi16_zext_i64(<vscale x 8 x i16> %a) #0 {183; CHECK-LABEL: test_lane8_8xi16_zext_i64:184; CHECK: // %bb.0:185; CHECK-NEXT: mov z0.h, z0.h[8]186; CHECK-NEXT: fmov w8, s0187; CHECK-NEXT: and x0, x8, #0xffff188; CHECK-NEXT: ret189 %b = extractelement <vscale x 8 x i16> %a, i32 8190 %c = zext i16 %b to i64191 ret i64 %c192}193 194define i32 @test_lane0_4xi32(<vscale x 4 x i32> %a) #0 {195; CHECK-LABEL: test_lane0_4xi32:196; CHECK: // %bb.0:197; CHECK-NEXT: fmov w0, s0198; CHECK-NEXT: ret199 %b = extractelement <vscale x 4 x i32> %a, i32 0200 ret i32 %b201}202 203define i32 @test_lane3_4xi32(<vscale x 4 x i32> %a) #0 {204; CHECK-LABEL: test_lane3_4xi32:205; CHECK: // %bb.0:206; CHECK-NEXT: mov w0, v0.s[3]207; CHECK-NEXT: ret208 %b = extractelement <vscale x 4 x i32> %a, i32 3209 ret i32 %b210}211 212define i32 @test_lane4_4xi32(<vscale x 4 x i32> %a) #0 {213; CHECK-LABEL: test_lane4_4xi32:214; CHECK: // %bb.0:215; CHECK-NEXT: mov z0.s, z0.s[4]216; CHECK-NEXT: fmov w0, s0217; CHECK-NEXT: ret218 %b = extractelement <vscale x 4 x i32> %a, i32 4219 ret i32 %b220}221 222define i64 @test_lane0_2xi64(<vscale x 2 x i64> %a) #0 {223; CHECK-LABEL: test_lane0_2xi64:224; CHECK: // %bb.0:225; CHECK-NEXT: fmov x0, d0226; CHECK-NEXT: ret227 %b = extractelement <vscale x 2 x i64> %a, i32 0228 ret i64 %b229}230 231define i64 @test_lane1_2xi64(<vscale x 2 x i64> %a) #0 {232; CHECK-LABEL: test_lane1_2xi64:233; CHECK: // %bb.0:234; CHECK-NEXT: mov x0, v0.d[1]235; CHECK-NEXT: ret236 %b = extractelement <vscale x 2 x i64> %a, i32 1237 ret i64 %b238}239 240define i64 @test_lane2_2xi64(<vscale x 2 x i64> %a) #0 {241; CHECK-LABEL: test_lane2_2xi64:242; CHECK: // %bb.0:243; CHECK-NEXT: mov z0.d, z0.d[2]244; CHECK-NEXT: fmov x0, d0245; CHECK-NEXT: ret246 %b = extractelement <vscale x 2 x i64> %a, i32 2247 ret i64 %b248}249 250define half @test_lane0_8xf16(<vscale x 8 x half> %a) #0 {251; CHECK-LABEL: test_lane0_8xf16:252; CHECK: // %bb.0:253; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0254; CHECK-NEXT: ret255 %b = extractelement <vscale x 8 x half> %a, i32 0256 ret half %b257}258 259define half @test_lane7_8xf16(<vscale x 8 x half> %a) #0 {260; CHECK-LABEL: test_lane7_8xf16:261; CHECK: // %bb.0:262; CHECK-NEXT: mov z0.h, z0.h[7]263; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0264; CHECK-NEXT: ret265 %b = extractelement <vscale x 8 x half> %a, i32 7266 ret half %b267}268 269define half @test_lane8_8xf16(<vscale x 8 x half> %a) #0 {270; CHECK-LABEL: test_lane8_8xf16:271; CHECK: // %bb.0:272; CHECK-NEXT: mov z0.h, z0.h[8]273; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0274; CHECK-NEXT: ret275 %b = extractelement <vscale x 8 x half> %a, i32 8276 ret half %b277}278 279define half @test_lane0_4xf16(<vscale x 4 x half> %a) #0 {280; CHECK-LABEL: test_lane0_4xf16:281; CHECK: // %bb.0:282; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0283; CHECK-NEXT: ret284 %b = extractelement <vscale x 4 x half> %a, i32 0285 ret half %b286}287 288define half @test_lane3_4xf16(<vscale x 4 x half> %a) #0 {289; CHECK-LABEL: test_lane3_4xf16:290; CHECK: // %bb.0:291; CHECK-NEXT: mov z0.s, z0.s[3]292; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0293; CHECK-NEXT: ret294 %b = extractelement <vscale x 4 x half> %a, i32 3295 ret half %b296}297 298define half @test_lane4_4xf16(<vscale x 4 x half> %a) #0 {299; CHECK-LABEL: test_lane4_4xf16:300; CHECK: // %bb.0:301; CHECK-NEXT: mov z0.s, z0.s[4]302; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0303; CHECK-NEXT: ret304 %b = extractelement <vscale x 4 x half> %a, i32 4305 ret half %b306}307 308define half @test_lane0_2xf16(<vscale x 2 x half> %a) #0 {309; CHECK-LABEL: test_lane0_2xf16:310; CHECK: // %bb.0:311; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0312; CHECK-NEXT: ret313 %b = extractelement <vscale x 2 x half> %a, i32 0314 ret half %b315}316 317define half @test_lane1_2xf16(<vscale x 2 x half> %a) #0 {318; CHECK-LABEL: test_lane1_2xf16:319; CHECK: // %bb.0:320; CHECK-NEXT: mov z0.d, z0.d[1]321; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0322; CHECK-NEXT: ret323 %b = extractelement <vscale x 2 x half> %a, i32 1324 ret half %b325}326 327define half @test_lane2_2xf16(<vscale x 2 x half> %a) #0 {328; CHECK-LABEL: test_lane2_2xf16:329; CHECK: // %bb.0:330; CHECK-NEXT: mov z0.d, z0.d[2]331; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0332; CHECK-NEXT: ret333 %b = extractelement <vscale x 2 x half> %a, i32 2334 ret half %b335}336 337define bfloat @test_lane0_8xbf16(<vscale x 8 x bfloat> %a) #0 {338; CHECK-LABEL: test_lane0_8xbf16:339; CHECK: // %bb.0:340; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0341; CHECK-NEXT: ret342 %b = extractelement <vscale x 8 x bfloat> %a, i32 0343 ret bfloat %b344}345 346define bfloat @test_lane7_8xbf16(<vscale x 8 x bfloat> %a) #0 {347; CHECK-LABEL: test_lane7_8xbf16:348; CHECK: // %bb.0:349; CHECK-NEXT: mov z0.h, z0.h[7]350; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0351; CHECK-NEXT: ret352 %b = extractelement <vscale x 8 x bfloat> %a, i32 7353 ret bfloat %b354}355 356define bfloat @test_lane8_8xbf16(<vscale x 8 x bfloat> %a) #0 {357; CHECK-LABEL: test_lane8_8xbf16:358; CHECK: // %bb.0:359; CHECK-NEXT: mov z0.h, z0.h[8]360; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0361; CHECK-NEXT: ret362 %b = extractelement <vscale x 8 x bfloat> %a, i32 8363 ret bfloat %b364}365 366define bfloat @test_lane0_4xbf16(<vscale x 4 x bfloat> %a) #0 {367; CHECK-LABEL: test_lane0_4xbf16:368; CHECK: // %bb.0:369; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0370; CHECK-NEXT: ret371 %b = extractelement <vscale x 4 x bfloat> %a, i32 0372 ret bfloat %b373}374 375define bfloat @test_lane3_4xbf16(<vscale x 4 x bfloat> %a) #0 {376; CHECK-LABEL: test_lane3_4xbf16:377; CHECK: // %bb.0:378; CHECK-NEXT: mov z0.s, z0.s[3]379; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0380; CHECK-NEXT: ret381 %b = extractelement <vscale x 4 x bfloat> %a, i32 3382 ret bfloat %b383}384 385define bfloat @test_lane4_4xbf16(<vscale x 4 x bfloat> %a) #0 {386; CHECK-LABEL: test_lane4_4xbf16:387; CHECK: // %bb.0:388; CHECK-NEXT: mov z0.s, z0.s[4]389; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0390; CHECK-NEXT: ret391 %b = extractelement <vscale x 4 x bfloat> %a, i32 4392 ret bfloat %b393}394 395define bfloat @test_lane0_2xbf16(<vscale x 2 x bfloat> %a) #0 {396; CHECK-LABEL: test_lane0_2xbf16:397; CHECK: // %bb.0:398; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0399; CHECK-NEXT: ret400 %b = extractelement <vscale x 2 x bfloat> %a, i32 0401 ret bfloat %b402}403 404define bfloat @test_lane1_2xbf16(<vscale x 2 x bfloat> %a) #0 {405; CHECK-LABEL: test_lane1_2xbf16:406; CHECK: // %bb.0:407; CHECK-NEXT: mov z0.d, z0.d[1]408; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0409; CHECK-NEXT: ret410 %b = extractelement <vscale x 2 x bfloat> %a, i32 1411 ret bfloat %b412}413 414define bfloat @test_lane2_2xbf16(<vscale x 2 x bfloat> %a) #0 {415; CHECK-LABEL: test_lane2_2xbf16:416; CHECK: // %bb.0:417; CHECK-NEXT: mov z0.d, z0.d[2]418; CHECK-NEXT: // kill: def $h0 killed $h0 killed $z0419; CHECK-NEXT: ret420 %b = extractelement <vscale x 2 x bfloat> %a, i32 2421 ret bfloat %b422}423 424define float @test_lane0_4xf32(<vscale x 4 x float> %a) #0 {425; CHECK-LABEL: test_lane0_4xf32:426; CHECK: // %bb.0:427; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0428; CHECK-NEXT: ret429 %b = extractelement <vscale x 4 x float> %a, i32 0430 ret float %b431}432 433define float @test_lane3_4xf32(<vscale x 4 x float> %a) #0 {434; CHECK-LABEL: test_lane3_4xf32:435; CHECK: // %bb.0:436; CHECK-NEXT: mov z0.s, z0.s[3]437; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0438; CHECK-NEXT: ret439 %b = extractelement <vscale x 4 x float> %a, i32 3440 ret float %b441}442 443define float @test_lane4_4xf32(<vscale x 4 x float> %a) #0 {444; CHECK-LABEL: test_lane4_4xf32:445; CHECK: // %bb.0:446; CHECK-NEXT: mov z0.s, z0.s[4]447; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0448; CHECK-NEXT: ret449 %b = extractelement <vscale x 4 x float> %a, i32 4450 ret float %b451}452 453define float @test_lane0_2xf32(<vscale x 2 x float> %a) #0 {454; CHECK-LABEL: test_lane0_2xf32:455; CHECK: // %bb.0:456; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0457; CHECK-NEXT: ret458 %b = extractelement <vscale x 2 x float> %a, i32 0459 ret float %b460}461 462define float @test_lane1_2xf32(<vscale x 2 x float> %a) #0 {463; CHECK-LABEL: test_lane1_2xf32:464; CHECK: // %bb.0:465; CHECK-NEXT: mov z0.d, z0.d[1]466; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0467; CHECK-NEXT: ret468 %b = extractelement <vscale x 2 x float> %a, i32 1469 ret float %b470}471 472define float @test_lane2_2xf32(<vscale x 2 x float> %a) #0 {473; CHECK-LABEL: test_lane2_2xf32:474; CHECK: // %bb.0:475; CHECK-NEXT: mov z0.d, z0.d[2]476; CHECK-NEXT: // kill: def $s0 killed $s0 killed $z0477; CHECK-NEXT: ret478 %b = extractelement <vscale x 2 x float> %a, i32 2479 ret float %b480}481 482define double @test_lane0_2xf64(<vscale x 2 x double> %a) #0 {483; CHECK-LABEL: test_lane0_2xf64:484; CHECK: // %bb.0:485; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0486; CHECK-NEXT: ret487 %b = extractelement <vscale x 2 x double> %a, i32 0488 ret double %b489}490 491define double @test_lane1_2xf64(<vscale x 2 x double> %a) #0 {492; CHECK-LABEL: test_lane1_2xf64:493; CHECK: // %bb.0:494; CHECK-NEXT: mov z0.d, z0.d[1]495; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0496; CHECK-NEXT: ret497 %b = extractelement <vscale x 2 x double> %a, i32 1498 ret double %b499}500 501define double @test_lane2_2xf64(<vscale x 2 x double> %a) #0 {502; CHECK-LABEL: test_lane2_2xf64:503; CHECK: // %bb.0:504; CHECK-NEXT: mov z0.d, z0.d[2]505; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0506; CHECK-NEXT: ret507 %b = extractelement <vscale x 2 x double> %a, i32 2508 ret double %b509}510 511define i8 @test_lanex_16xi8(<vscale x 16 x i8> %a, i32 %x) #0 {512; CHECK-LABEL: test_lanex_16xi8:513; CHECK: // %bb.0:514; CHECK-NEXT: mov w8, w0515; CHECK-NEXT: whilels p0.b, xzr, x8516; CHECK-NEXT: lastb w0, p0, z0.b517; CHECK-NEXT: ret518 %b = extractelement <vscale x 16 x i8> %a, i32 %x519 ret i8 %b520}521 522define i16 @test_lanex_8xi16(<vscale x 8 x i16> %a, i32 %x) #0 {523; CHECK-LABEL: test_lanex_8xi16:524; CHECK: // %bb.0:525; CHECK-NEXT: mov w8, w0526; CHECK-NEXT: whilels p0.h, xzr, x8527; CHECK-NEXT: lastb w0, p0, z0.h528; CHECK-NEXT: ret529 %b = extractelement <vscale x 8 x i16> %a, i32 %x530 ret i16 %b531}532 533define i32 @test_lanex_4xi32(<vscale x 4 x i32> %a, i32 %x) #0 {534; CHECK-LABEL: test_lanex_4xi32:535; CHECK: // %bb.0:536; CHECK-NEXT: mov w8, w0537; CHECK-NEXT: whilels p0.s, xzr, x8538; CHECK-NEXT: lastb w0, p0, z0.s539; CHECK-NEXT: ret540 %b = extractelement <vscale x 4 x i32> %a, i32 %x541 ret i32 %b542}543 544define i64 @test_lanex_2xi64(<vscale x 2 x i64> %a, i32 %x) #0 {545; CHECK-LABEL: test_lanex_2xi64:546; CHECK: // %bb.0:547; CHECK-NEXT: mov w8, w0548; CHECK-NEXT: whilels p0.d, xzr, x8549; CHECK-NEXT: lastb x0, p0, z0.d550; CHECK-NEXT: ret551 %b = extractelement <vscale x 2 x i64> %a, i32 %x552 ret i64 %b553}554 555define half @test_lanex_8xf16(<vscale x 8 x half> %a, i32 %x) #0 {556; CHECK-LABEL: test_lanex_8xf16:557; CHECK: // %bb.0:558; CHECK-NEXT: mov w8, w0559; CHECK-NEXT: whilels p0.h, xzr, x8560; CHECK-NEXT: lastb h0, p0, z0.h561; CHECK-NEXT: ret562 %b = extractelement <vscale x 8 x half> %a, i32 %x563 ret half %b564}565 566define half @test_lanex_4xf16(<vscale x 4 x half> %a, i32 %x) #0 {567; CHECK-LABEL: test_lanex_4xf16:568; CHECK: // %bb.0:569; CHECK-NEXT: mov w8, w0570; CHECK-NEXT: whilels p0.s, xzr, x8571; CHECK-NEXT: lastb h0, p0, z0.h572; CHECK-NEXT: ret573 %b = extractelement <vscale x 4 x half> %a, i32 %x574 ret half %b575}576 577define half @test_lanex_2xf16(<vscale x 2 x half> %a, i32 %x) #0 {578; CHECK-LABEL: test_lanex_2xf16:579; CHECK: // %bb.0:580; CHECK-NEXT: mov w8, w0581; CHECK-NEXT: whilels p0.d, xzr, x8582; CHECK-NEXT: lastb h0, p0, z0.h583; CHECK-NEXT: ret584 %b = extractelement <vscale x 2 x half> %a, i32 %x585 ret half %b586}587 588define bfloat @test_lanex_8xbf16(<vscale x 8 x bfloat> %a, i32 %x) #0 {589; CHECK-LABEL: test_lanex_8xbf16:590; CHECK: // %bb.0:591; CHECK-NEXT: mov w8, w0592; CHECK-NEXT: whilels p0.h, xzr, x8593; CHECK-NEXT: lastb h0, p0, z0.h594; CHECK-NEXT: ret595 %b = extractelement <vscale x 8 x bfloat> %a, i32 %x596 ret bfloat %b597}598 599define bfloat @test_lanex_4xbf16(<vscale x 4 x bfloat> %a, i32 %x) #0 {600; CHECK-LABEL: test_lanex_4xbf16:601; CHECK: // %bb.0:602; CHECK-NEXT: mov w8, w0603; CHECK-NEXT: whilels p0.s, xzr, x8604; CHECK-NEXT: lastb h0, p0, z0.h605; CHECK-NEXT: ret606 %b = extractelement <vscale x 4 x bfloat> %a, i32 %x607 ret bfloat %b608}609 610define bfloat @test_lanex_2xbf16(<vscale x 2 x bfloat> %a, i32 %x) #0 {611; CHECK-LABEL: test_lanex_2xbf16:612; CHECK: // %bb.0:613; CHECK-NEXT: mov w8, w0614; CHECK-NEXT: whilels p0.d, xzr, x8615; CHECK-NEXT: lastb h0, p0, z0.h616; CHECK-NEXT: ret617 %b = extractelement <vscale x 2 x bfloat> %a, i32 %x618 ret bfloat %b619}620 621define float @test_lanex_4xf32(<vscale x 4 x float> %a, i32 %x) #0 {622; CHECK-LABEL: test_lanex_4xf32:623; CHECK: // %bb.0:624; CHECK-NEXT: mov w8, w0625; CHECK-NEXT: whilels p0.s, xzr, x8626; CHECK-NEXT: lastb s0, p0, z0.s627; CHECK-NEXT: ret628 %b = extractelement <vscale x 4 x float> %a, i32 %x629 ret float %b630}631 632define float @test_lanex_2xf32(<vscale x 2 x float> %a, i32 %x) #0 {633; CHECK-LABEL: test_lanex_2xf32:634; CHECK: // %bb.0:635; CHECK-NEXT: mov w8, w0636; CHECK-NEXT: whilels p0.d, xzr, x8637; CHECK-NEXT: lastb s0, p0, z0.s638; CHECK-NEXT: ret639 %b = extractelement <vscale x 2 x float> %a, i32 %x640 ret float %b641}642 643define double @test_lanex_2xf64(<vscale x 2 x double> %a, i32 %x) #0 {644; CHECK-LABEL: test_lanex_2xf64:645; CHECK: // %bb.0:646; CHECK-NEXT: mov w8, w0647; CHECK-NEXT: whilels p0.d, xzr, x8648; CHECK-NEXT: lastb d0, p0, z0.d649; CHECK-NEXT: ret650 %b = extractelement <vscale x 2 x double> %a, i32 %x651 ret double %b652}653 654; Deliberately choose an index that is undefined655define i32 @test_undef_lane_4xi32(<vscale x 4 x i32> %a) #0 {656; CHECK-LABEL: test_undef_lane_4xi32:657; CHECK: // %bb.0:658; CHECK-NEXT: ret659 %b = extractelement <vscale x 4 x i32> %a, i32 poison660 ret i32 %b661}662 663define i8 @extract_of_insert_undef_16xi8(i8 %a) #0 {664; CHECK-LABEL: extract_of_insert_undef_16xi8:665; CHECK: // %bb.0:666; CHECK-NEXT: ret667 %b = insertelement <vscale x 16 x i8> poison, i8 %a, i32 0668 %c = extractelement <vscale x 16 x i8> %b, i32 0669 ret i8 %c670}671 672define i8 @extract0_of_insert0_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {673; CHECK-LABEL: extract0_of_insert0_16xi8:674; CHECK: // %bb.0:675; CHECK-NEXT: ret676 %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 0677 %d = extractelement <vscale x 16 x i8> %c, i32 0678 ret i8 %d679}680 681define i8 @extract64_of_insert64_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {682; CHECK-LABEL: extract64_of_insert64_16xi8:683; CHECK: // %bb.0:684; CHECK-NEXT: ret685 %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 64686 %d = extractelement <vscale x 16 x i8> %c, i32 64687 ret i8 %d688}689 690define i8 @extract_of_insert_diff_lanes_16xi8(<vscale x 16 x i8> %a, i8 %b) #0 {691; CHECK-LABEL: extract_of_insert_diff_lanes_16xi8:692; CHECK: // %bb.0:693; CHECK-NEXT: umov w0, v0.b[3]694; CHECK-NEXT: ret695 %c = insertelement <vscale x 16 x i8> %a, i8 %b, i32 0696 %d = extractelement <vscale x 16 x i8> %c, i32 3697 ret i8 %d698}699 700define i8 @test_lane0_zero_16xi8(<vscale x 16 x i8> %a) #0 {701; CHECK-LABEL: test_lane0_zero_16xi8:702; CHECK: // %bb.0:703; CHECK-NEXT: mov w0, wzr704; CHECK-NEXT: ret705 %b = extractelement <vscale x 16 x i8> zeroinitializer, i32 0706 ret i8 %b707}708 709; The DAG combiner should fold the extract of a splat to give element zero710; of the splat, i.e. %x. If the index is beyond the end of the scalable711; vector the result is undefined anyway.712define i64 @test_lanex_splat_2xi64(i64 %x, i32 %y) #0 {713; CHECK-LABEL: test_lanex_splat_2xi64:714; CHECK: // %bb.0:715; CHECK-NEXT: ret716 %a = insertelement <vscale x 2 x i64> poison, i64 %x, i32 0717 %b = shufflevector <vscale x 2 x i64> %a, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer718 %c = extractelement <vscale x 2 x i64> %b, i32 %y719 ret i64 %c720}721 722define i1 @test_lane0_16xi1(<vscale x 16 x i1> %a) #0 {723; CHECK-LABEL: test_lane0_16xi1:724; CHECK: // %bb.0:725; CHECK-NEXT: mov z0.b, p0/z, #1 // =0x1726; CHECK-NEXT: fmov w8, s0727; CHECK-NEXT: and w0, w8, #0x1728; CHECK-NEXT: ret729 %b = extractelement <vscale x 16 x i1> %a, i32 0730 ret i1 %b731}732 733define i1 @test_lane9_8xi1(<vscale x 8 x i1> %a) #0 {734; CHECK-LABEL: test_lane9_8xi1:735; CHECK: // %bb.0:736; CHECK-NEXT: mov z0.h, p0/z, #1 // =0x1737; CHECK-NEXT: mov z0.h, z0.h[9]738; CHECK-NEXT: fmov w8, s0739; CHECK-NEXT: and w0, w8, #0x1740; CHECK-NEXT: ret741 %b = extractelement <vscale x 8 x i1> %a, i32 9742 ret i1 %b743}744 745define i1 @test_last_8xi1(<vscale x 8 x i1> %a) #0 {746; CHECK-LABEL: test_last_8xi1:747; CHECK: // %bb.0:748; CHECK-NEXT: mov x8, #-1 // =0xffffffffffffffff749; CHECK-NEXT: mov z0.h, p0/z, #1 // =0x1750; CHECK-NEXT: whilels p0.h, xzr, x8751; CHECK-NEXT: lastb w8, p0, z0.h752; CHECK-NEXT: and w0, w8, #0x1753; CHECK-NEXT: ret754 %vscale = call i64 @llvm.vscale.i64()755 %shl = shl nuw nsw i64 %vscale, 3756 %idx = add nuw nsw i64 %shl, -1757 %bit = extractelement <vscale x 8 x i1> %a, i64 %idx758 ret i1 %bit759}760 761define i1 @test_lanex_4xi1(<vscale x 4 x i1> %a, i32 %x) #0 {762; CHECK-LABEL: test_lanex_4xi1:763; CHECK: // %bb.0:764; CHECK-NEXT: mov z0.s, p0/z, #1 // =0x1765; CHECK-NEXT: mov w8, w0766; CHECK-NEXT: whilels p0.s, xzr, x8767; CHECK-NEXT: lastb w8, p0, z0.s768; CHECK-NEXT: and w0, w8, #0x1769; CHECK-NEXT: ret770 %b = extractelement <vscale x 4 x i1> %a, i32 %x771 ret i1 %b772}773 774define i1 @test_lane4_2xi1(<vscale x 2 x i1> %a) #0 {775; CHECK-LABEL: test_lane4_2xi1:776; CHECK: // %bb.0:777; CHECK-NEXT: mov z0.d, p0/z, #1 // =0x1778; CHECK-NEXT: mov z0.s, z0.s[8]779; CHECK-NEXT: fmov w8, s0780; CHECK-NEXT: and w0, w8, #0x1781; CHECK-NEXT: ret782 %b = extractelement <vscale x 2 x i1> %a, i32 4783 ret i1 %b784}785 786declare i64 @llvm.vscale.i64()787 788attributes #0 = { "target-features"="+sve,+bf16" }789