1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s 3 4define <vscale x 16 x i8> @test_lane0_16xi8(<vscale x 16 x i8> %a) { 5; CHECK-LABEL: test_lane0_16xi8: 6; CHECK: // %bb.0: 7; CHECK-NEXT: ptrue p0.b, vl1 8; CHECK-NEXT: mov w8, #30 9; CHECK-NEXT: mov z0.b, p0/m, w8 10; CHECK-NEXT: ret 11 %b = insertelement <vscale x 16 x i8> %a, i8 30, i32 0 12 ret <vscale x 16 x i8> %b 13} 14 15define <vscale x 8 x i16> @test_lane0_8xi16(<vscale x 8 x i16> %a) { 16; CHECK-LABEL: test_lane0_8xi16: 17; CHECK: // %bb.0: 18; CHECK-NEXT: ptrue p0.h, vl1 19; CHECK-NEXT: mov w8, #30 20; CHECK-NEXT: mov z0.h, p0/m, w8 21; CHECK-NEXT: ret 22 %b = insertelement <vscale x 8 x i16> %a, i16 30, i32 0 23 ret <vscale x 8 x i16> %b 24} 25 26define <vscale x 4 x i32> @test_lane0_4xi32(<vscale x 4 x i32> %a) { 27; CHECK-LABEL: test_lane0_4xi32: 28; CHECK: // %bb.0: 29; CHECK-NEXT: ptrue p0.s, vl1 30; CHECK-NEXT: mov w8, #30 31; CHECK-NEXT: mov z0.s, p0/m, w8 32; CHECK-NEXT: ret 33 %b = insertelement <vscale x 4 x i32> %a, i32 30, i32 0 34 ret <vscale x 4 x i32> %b 35} 36 37define <vscale x 2 x i64> @test_lane0_2xi64(<vscale x 2 x i64> %a) { 38; CHECK-LABEL: test_lane0_2xi64: 39; CHECK: // %bb.0: 40; CHECK-NEXT: ptrue p0.d, vl1 41; CHECK-NEXT: mov w8, #30 42; CHECK-NEXT: mov z0.d, p0/m, x8 43; CHECK-NEXT: ret 44 %b = insertelement <vscale x 2 x i64> %a, i64 30, i32 0 45 ret <vscale x 2 x i64> %b 46} 47 48define <vscale x 2 x double> @test_lane0_2xf64(<vscale x 2 x double> %a) { 49; CHECK-LABEL: test_lane0_2xf64: 50; CHECK: // %bb.0: 51; CHECK-NEXT: fmov d1, #1.00000000 52; CHECK-NEXT: ptrue p0.d, vl1 53; CHECK-NEXT: mov z0.d, p0/m, z1.d 54; CHECK-NEXT: ret 55 %b = insertelement <vscale x 2 x double> %a, double 1.0, i32 0 56 ret <vscale x 2 x double> %b 57} 58 59define <vscale x 4 x float> @test_lane0_4xf32(<vscale x 4 x float> %a) { 60; CHECK-LABEL: test_lane0_4xf32: 61; CHECK: // %bb.0: 62; CHECK-NEXT: fmov s1, #1.00000000 63; CHECK-NEXT: ptrue p0.s, vl1 64; CHECK-NEXT: mov z0.s, p0/m, z1.s 65; CHECK-NEXT: ret 66 %b = insertelement <vscale x 4 x float> %a, float 1.0, i32 0 67 ret <vscale x 4 x float> %b 68} 69 70define <vscale x 8 x half> @test_lane0_8xf16(<vscale x 8 x half> %a) { 71; CHECK-LABEL: test_lane0_8xf16: 72; CHECK: // %bb.0: 73; CHECK-NEXT: fmov h1, #1.00000000 74; CHECK-NEXT: ptrue p0.h, vl1 75; CHECK-NEXT: mov z0.h, p0/m, z1.h 76; CHECK-NEXT: ret 77 %b = insertelement <vscale x 8 x half> %a, half 1.0, i32 0 78 ret <vscale x 8 x half> %b 79} 80 81; Undefined lane insert 82define <vscale x 2 x i64> @test_lane4_2xi64(<vscale x 2 x i64> %a) { 83; CHECK-LABEL: test_lane4_2xi64: 84; CHECK: // %bb.0: 85; CHECK-NEXT: mov w8, #4 86; CHECK-NEXT: index z1.d, #0, #1 87; CHECK-NEXT: ptrue p0.d 88; CHECK-NEXT: mov z2.d, x8 89; CHECK-NEXT: cmpeq p0.d, p0/z, z1.d, z2.d 90; CHECK-NEXT: mov w8, #30 91; CHECK-NEXT: mov z0.d, p0/m, x8 92; CHECK-NEXT: ret 93 %b = insertelement <vscale x 2 x i64> %a, i64 30, i32 4 94 ret <vscale x 2 x i64> %b 95} 96 97; Undefined lane insert 98define <vscale x 8 x half> @test_lane9_8xf16(<vscale x 8 x half> %a) { 99; CHECK-LABEL: test_lane9_8xf16: 100; CHECK: // %bb.0: 101; CHECK-NEXT: mov w8, #9 102; CHECK-NEXT: index z1.h, #0, #1 103; CHECK-NEXT: ptrue p0.h 104; CHECK-NEXT: mov z2.h, w8 105; CHECK-NEXT: cmpeq p0.h, p0/z, z1.h, z2.h 106; CHECK-NEXT: fmov h1, #1.00000000 107; CHECK-NEXT: mov z0.h, p0/m, h1 108; CHECK-NEXT: ret 109 %b = insertelement <vscale x 8 x half> %a, half 1.0, i32 9 110 ret <vscale x 8 x half> %b 111} 112 113define <vscale x 16 x i8> @test_lane1_16xi8(<vscale x 16 x i8> %a) { 114; CHECK-LABEL: test_lane1_16xi8: 115; CHECK: // %bb.0: 116; CHECK-NEXT: mov w8, #1 117; CHECK-NEXT: index z1.b, #0, #1 118; CHECK-NEXT: ptrue p0.b 119; CHECK-NEXT: mov z2.b, w8 120; CHECK-NEXT: cmpeq p0.b, p0/z, z1.b, z2.b 121; CHECK-NEXT: mov w8, #30 122; CHECK-NEXT: mov z0.b, p0/m, w8 123; CHECK-NEXT: ret 124 %b = insertelement <vscale x 16 x i8> %a, i8 30, i32 1 125 ret <vscale x 16 x i8> %b 126} 127 128define <vscale x 16 x i8> @test_lanex_16xi8(<vscale x 16 x i8> %a, i32 %x) { 129; CHECK-LABEL: test_lanex_16xi8: 130; CHECK: // %bb.0: 131; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0 132; CHECK-NEXT: sxtw x8, w0 133; CHECK-NEXT: index z1.b, #0, #1 134; CHECK-NEXT: ptrue p0.b 135; CHECK-NEXT: mov z2.b, w8 136; CHECK-NEXT: cmpeq p0.b, p0/z, z1.b, z2.b 137; CHECK-NEXT: mov w8, #30 138; CHECK-NEXT: mov z0.b, p0/m, w8 139; CHECK-NEXT: ret 140 %b = insertelement <vscale x 16 x i8> %a, i8 30, i32 %x 141 ret <vscale x 16 x i8> %b 142} 143 144 145; Redundant lane insert 146define <vscale x 4 x i32> @extract_insert_4xi32(<vscale x 4 x i32> %a) { 147; CHECK-LABEL: extract_insert_4xi32: 148; CHECK: // %bb.0: 149; CHECK-NEXT: ret 150 %b = extractelement <vscale x 4 x i32> %a, i32 2 151 %c = insertelement <vscale x 4 x i32> %a, i32 %b, i32 2 152 ret <vscale x 4 x i32> %c 153} 154 155define <vscale x 8 x i16> @test_lane6_undef_8xi16(i16 %a) { 156; CHECK-LABEL: test_lane6_undef_8xi16: 157; CHECK: // %bb.0: 158; CHECK-NEXT: mov w8, #6 159; CHECK-NEXT: index z0.h, #0, #1 160; CHECK-NEXT: mov z1.h, w8 161; CHECK-NEXT: ptrue p0.h 162; CHECK-NEXT: cmpeq p0.h, p0/z, z0.h, z1.h 163; CHECK-NEXT: mov z0.h, p0/m, w0 164; CHECK-NEXT: ret 165 %b = insertelement <vscale x 8 x i16> undef, i16 %a, i32 6 166 ret <vscale x 8 x i16> %b 167} 168 169define <vscale x 16 x i8> @test_lane0_undef_16xi8(i8 %a) { 170; CHECK-LABEL: test_lane0_undef_16xi8: 171; CHECK: // %bb.0: 172; CHECK-NEXT: fmov s0, w0 173; CHECK-NEXT: ret 174 %b = insertelement <vscale x 16 x i8> undef, i8 %a, i32 0 175 ret <vscale x 16 x i8> %b 176} 177 178define <vscale x 16 x i8> @test_insert0_of_extract0_16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) { 179; CHECK-LABEL: test_insert0_of_extract0_16xi8: 180; CHECK: // %bb.0: 181; CHECK-NEXT: fmov w8, s1 182; CHECK-NEXT: ptrue p0.b, vl1 183; CHECK-NEXT: mov z0.b, p0/m, w8 184; CHECK-NEXT: ret 185 %c = extractelement <vscale x 16 x i8> %b, i32 0 186 %d = insertelement <vscale x 16 x i8> %a, i8 %c, i32 0 187 ret <vscale x 16 x i8> %d 188} 189 190define <vscale x 16 x i8> @test_insert64_of_extract64_16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) { 191; CHECK-LABEL: test_insert64_of_extract64_16xi8: 192; CHECK: // %bb.0: 193; CHECK-NEXT: mov w8, #64 194; CHECK-NEXT: index z2.b, #0, #1 195; CHECK-NEXT: ptrue p0.b 196; CHECK-NEXT: whilels p1.b, xzr, x8 197; CHECK-NEXT: mov z3.b, w8 198; CHECK-NEXT: lastb w8, p1, z1.b 199; CHECK-NEXT: cmpeq p0.b, p0/z, z2.b, z3.b 200; CHECK-NEXT: mov z0.b, p0/m, w8 201; CHECK-NEXT: ret 202 %c = extractelement <vscale x 16 x i8> %b, i32 64 203 %d = insertelement <vscale x 16 x i8> %a, i8 %c, i32 64 204 ret <vscale x 16 x i8> %d 205} 206 207define <vscale x 16 x i8> @test_insert3_of_extract1_16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) { 208; CHECK-LABEL: test_insert3_of_extract1_16xi8: 209; CHECK: // %bb.0: 210; CHECK-NEXT: mov w9, #3 211; CHECK-NEXT: umov w8, v1.b[1] 212; CHECK-NEXT: index z1.b, #0, #1 213; CHECK-NEXT: mov z2.b, w9 214; CHECK-NEXT: ptrue p0.b 215; CHECK-NEXT: cmpeq p0.b, p0/z, z1.b, z2.b 216; CHECK-NEXT: mov z0.b, p0/m, w8 217; CHECK-NEXT: ret 218 %c = extractelement <vscale x 16 x i8> %b, i32 1 219 %d = insertelement <vscale x 16 x i8> %a, i8 %c, i32 3 220 ret <vscale x 16 x i8> %d 221} 222 223define <vscale x 8 x half> @test_insert_into_undef_nxv8f16(half %a) { 224; CHECK-LABEL: test_insert_into_undef_nxv8f16: 225; CHECK: // %bb.0: 226; CHECK-NEXT: // kill: def $h0 killed $h0 def $z0 227; CHECK-NEXT: ret 228 %b = insertelement <vscale x 8 x half> undef, half %a, i32 0 229 ret <vscale x 8 x half> %b 230} 231 232define <vscale x 4 x half> @test_insert_into_undef_nxv4f16(half %a) { 233; CHECK-LABEL: test_insert_into_undef_nxv4f16: 234; CHECK: // %bb.0: 235; CHECK-NEXT: // kill: def $h0 killed $h0 def $z0 236; CHECK-NEXT: ret 237 %b = insertelement <vscale x 4 x half> undef, half %a, i32 0 238 ret <vscale x 4 x half> %b 239} 240 241define <vscale x 2 x half> @test_insert_into_undef_nxv2f16(half %a) { 242; CHECK-LABEL: test_insert_into_undef_nxv2f16: 243; CHECK: // %bb.0: 244; CHECK-NEXT: // kill: def $h0 killed $h0 def $z0 245; CHECK-NEXT: ret 246 %b = insertelement <vscale x 2 x half> undef, half %a, i32 0 247 ret <vscale x 2 x half> %b 248} 249 250define <vscale x 4 x float> @test_insert_into_undef_nxv4f32(float %a) { 251; CHECK-LABEL: test_insert_into_undef_nxv4f32: 252; CHECK: // %bb.0: 253; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0 254; CHECK-NEXT: ret 255 %b = insertelement <vscale x 4 x float> undef, float %a, i32 0 256 ret <vscale x 4 x float> %b 257} 258 259define <vscale x 2 x float> @test_insert_into_undef_nxv2f32(float %a) { 260; CHECK-LABEL: test_insert_into_undef_nxv2f32: 261; CHECK: // %bb.0: 262; CHECK-NEXT: // kill: def $s0 killed $s0 def $z0 263; CHECK-NEXT: ret 264 %b = insertelement <vscale x 2 x float> undef, float %a, i32 0 265 ret <vscale x 2 x float> %b 266} 267 268define <vscale x 2 x double> @test_insert_into_undef_nxv2f64(double %a) { 269; CHECK-LABEL: test_insert_into_undef_nxv2f64: 270; CHECK: // %bb.0: 271; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 272; CHECK-NEXT: ret 273 %b = insertelement <vscale x 2 x double> undef, double %a, i32 0 274 ret <vscale x 2 x double> %b 275} 276 277; Insert scalar at index 278define <vscale x 2 x half> @test_insert_with_index_nxv2f16(half %h, i64 %idx) { 279; CHECK-LABEL: test_insert_with_index_nxv2f16: 280; CHECK: // %bb.0: 281; CHECK-NEXT: mov z1.d, x0 282; CHECK-NEXT: index z2.d, #0, #1 283; CHECK-NEXT: ptrue p0.d 284; CHECK-NEXT: cmpeq p0.d, p0/z, z2.d, z1.d 285; CHECK-NEXT: mov z0.h, p0/m, h0 286; CHECK-NEXT: ret 287 %res = insertelement <vscale x 2 x half> undef, half %h, i64 %idx 288 ret <vscale x 2 x half> %res 289} 290 291define <vscale x 4 x half> @test_insert_with_index_nxv4f16(half %h, i64 %idx) { 292; CHECK-LABEL: test_insert_with_index_nxv4f16: 293; CHECK: // %bb.0: 294; CHECK-NEXT: mov z1.s, w0 295; CHECK-NEXT: index z2.s, #0, #1 296; CHECK-NEXT: ptrue p0.s 297; CHECK-NEXT: cmpeq p0.s, p0/z, z2.s, z1.s 298; CHECK-NEXT: mov z0.h, p0/m, h0 299; CHECK-NEXT: ret 300 %res = insertelement <vscale x 4 x half> undef, half %h, i64 %idx 301 ret <vscale x 4 x half> %res 302} 303 304define <vscale x 8 x half> @test_insert_with_index_nxv8f16(half %h, i64 %idx) { 305; CHECK-LABEL: test_insert_with_index_nxv8f16: 306; CHECK: // %bb.0: 307; CHECK-NEXT: mov z1.h, w0 308; CHECK-NEXT: index z2.h, #0, #1 309; CHECK-NEXT: ptrue p0.h 310; CHECK-NEXT: cmpeq p0.h, p0/z, z2.h, z1.h 311; CHECK-NEXT: mov z0.h, p0/m, h0 312; CHECK-NEXT: ret 313 %res = insertelement <vscale x 8 x half> undef, half %h, i64 %idx 314 ret <vscale x 8 x half> %res 315} 316 317define <vscale x 2 x float> @test_insert_with_index_nxv2f32(float %f, i64 %idx) { 318; CHECK-LABEL: test_insert_with_index_nxv2f32: 319; CHECK: // %bb.0: 320; CHECK-NEXT: mov z1.d, x0 321; CHECK-NEXT: index z2.d, #0, #1 322; CHECK-NEXT: ptrue p0.d 323; CHECK-NEXT: cmpeq p0.d, p0/z, z2.d, z1.d 324; CHECK-NEXT: mov z0.s, p0/m, s0 325; CHECK-NEXT: ret 326 %res = insertelement <vscale x 2 x float> undef, float %f, i64 %idx 327 ret <vscale x 2 x float> %res 328} 329 330define <vscale x 4 x float> @test_insert_with_index_nxv4f32(float %f, i64 %idx) { 331; CHECK-LABEL: test_insert_with_index_nxv4f32: 332; CHECK: // %bb.0: 333; CHECK-NEXT: mov z1.s, w0 334; CHECK-NEXT: index z2.s, #0, #1 335; CHECK-NEXT: ptrue p0.s 336; CHECK-NEXT: cmpeq p0.s, p0/z, z2.s, z1.s 337; CHECK-NEXT: mov z0.s, p0/m, s0 338; CHECK-NEXT: ret 339 %res = insertelement <vscale x 4 x float> undef, float %f, i64 %idx 340 ret <vscale x 4 x float> %res 341} 342 343define <vscale x 2 x double> @test_insert_with_index_nxv2f64(double %d, i64 %idx) { 344; CHECK-LABEL: test_insert_with_index_nxv2f64: 345; CHECK: // %bb.0: 346; CHECK-NEXT: mov z1.d, x0 347; CHECK-NEXT: index z2.d, #0, #1 348; CHECK-NEXT: ptrue p0.d 349; CHECK-NEXT: cmpeq p0.d, p0/z, z2.d, z1.d 350; CHECK-NEXT: mov z0.d, p0/m, d0 351; CHECK-NEXT: ret 352 %res = insertelement <vscale x 2 x double> undef, double %d, i64 %idx 353 ret <vscale x 2 x double> %res 354} 355