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