466 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve,+neon < %s | FileCheck %s3 4; Inserting an element from the bottom 128-bits of an SVE type into a NEON vector should use INS (element) to5; avoid pointless FMOV trips.6 7; --------- extraction from nxv16i88 9define <8 x i8> @test_lane0_nxv16i8(<8 x i8> %a, <vscale x 16 x i8> %b) {10; CHECK-LABEL: test_lane0_nxv16i8:11; CHECK: // %bb.0:12; CHECK-NEXT: // kill: def $d0 killed $d0 def $q013; CHECK-NEXT: mov v0.b[0], v1.b[0]14; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q015; CHECK-NEXT: ret16 %c = extractelement <vscale x 16 x i8> %b, i32 017 %d = insertelement <8 x i8> %a, i8 %c, i32 018 ret <8 x i8> %d19}20 21define <8 x i8> @test_lane15_nxv16i8(<8 x i8> %a, <vscale x 16 x i8> %b) {22; CHECK-LABEL: test_lane15_nxv16i8:23; CHECK: // %bb.0:24; CHECK-NEXT: // kill: def $d0 killed $d0 def $q025; CHECK-NEXT: mov v0.b[7], v1.b[15]26; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q027; CHECK-NEXT: ret28 %c = extractelement <vscale x 16 x i8> %b, i32 1529 %d = insertelement <8 x i8> %a, i8 %c, i32 730 ret <8 x i8> %d31}32 33define <16 x i8> @test_q_lane0_nxv16i8(<16 x i8> %a, <vscale x 16 x i8> %b) {34; CHECK-LABEL: test_q_lane0_nxv16i8:35; CHECK: // %bb.0:36; CHECK-NEXT: mov v0.b[0], v1.b[0]37; CHECK-NEXT: ret38 %c = extractelement <vscale x 16 x i8> %b, i32 039 %d = insertelement <16 x i8> %a, i8 %c, i32 040 ret <16 x i8> %d41}42 43define <16 x i8> @test_q_lane15_nxv16i8(<16 x i8> %a, <vscale x 16 x i8> %b) {44; CHECK-LABEL: test_q_lane15_nxv16i8:45; CHECK: // %bb.0:46; CHECK-NEXT: mov v0.b[15], v1.b[15]47; CHECK-NEXT: ret48 %c = extractelement <vscale x 16 x i8> %b, i32 1549 %d = insertelement <16 x i8> %a, i8 %c, i32 1550 ret <16 x i8> %d51}52 53; (negative test) Extracted element is not within Vn54define <16 x i8> @test_q_lane16_nxv16i8(<16 x i8> %a, <vscale x 16 x i8> %b) {55; CHECK-LABEL: test_q_lane16_nxv16i8:56; CHECK: // %bb.0:57; CHECK-NEXT: mov z1.b, z1.b[16]58; CHECK-NEXT: fmov w8, s159; CHECK-NEXT: mov v0.b[15], w860; CHECK-NEXT: ret61 %c = extractelement <vscale x 16 x i8> %b, i32 1662 %d = insertelement <16 x i8> %a, i8 %c, i32 1563 ret <16 x i8> %d64}65 66; --------- extraction from nxv8f1667 68define <4 x half> @test_lane0_nxv8f16(<4 x half> %a, <vscale x 8 x half> %b) {69; CHECK-LABEL: test_lane0_nxv8f16:70; CHECK: // %bb.0:71; CHECK-NEXT: // kill: def $d0 killed $d0 def $q072; CHECK-NEXT: mov v0.h[0], v1.h[0]73; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q074; CHECK-NEXT: ret75 %c = extractelement <vscale x 8 x half> %b, i32 076 %d = insertelement <4 x half> %a, half %c, i32 077 ret <4 x half> %d78}79 80define <4 x half> @test_lane7_nxv8f16(<4 x half> %a, <vscale x 8 x half> %b) {81; CHECK-LABEL: test_lane7_nxv8f16:82; CHECK: // %bb.0:83; CHECK-NEXT: // kill: def $d0 killed $d0 def $q084; CHECK-NEXT: mov v0.h[3], v1.h[7]85; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q086; CHECK-NEXT: ret87 %c = extractelement <vscale x 8 x half> %b, i32 788 %d = insertelement <4 x half> %a, half %c, i32 389 ret <4 x half> %d90}91 92define <8 x half> @test_q_lane0_nxv8f16(<8 x half> %a, <vscale x 8 x half> %b) {93; CHECK-LABEL: test_q_lane0_nxv8f16:94; CHECK: // %bb.0:95; CHECK-NEXT: mov v0.h[0], v1.h[0]96; CHECK-NEXT: ret97 %c = extractelement <vscale x 8 x half> %b, i32 098 %d = insertelement <8 x half> %a, half %c, i32 099 ret <8 x half> %d100}101 102define <8 x half> @test_q_lane7_nxv8f16(<8 x half> %a, <vscale x 8 x half> %b) {103; CHECK-LABEL: test_q_lane7_nxv8f16:104; CHECK: // %bb.0:105; CHECK-NEXT: mov v0.h[7], v1.h[7]106; CHECK-NEXT: ret107 %c = extractelement <vscale x 8 x half> %b, i32 7108 %d = insertelement <8 x half> %a, half %c, i32 7109 ret <8 x half> %d110}111 112; (negative test) Extracted element is not within Vn113define <8 x half> @test_q_lane8_nxv8f16(<8 x half> %a, <vscale x 8 x half> %b) {114; CHECK-LABEL: test_q_lane8_nxv8f16:115; CHECK: // %bb.0:116; CHECK-NEXT: mov z1.h, z1.h[8]117; CHECK-NEXT: mov v0.h[7], v1.h[0]118; CHECK-NEXT: ret119 %c = extractelement <vscale x 8 x half> %b, i32 8120 %d = insertelement <8 x half> %a, half %c, i32 7121 ret <8 x half> %d122}123 124; --------- extraction from nxv8bf16125 126define <4 x bfloat> @test_lane0_nxv8bf16(<4 x bfloat> %a, <vscale x 8 x bfloat> %b) {127; CHECK-LABEL: test_lane0_nxv8bf16:128; CHECK: // %bb.0:129; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0130; CHECK-NEXT: mov v0.h[0], v1.h[0]131; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0132; CHECK-NEXT: ret133 %c = extractelement <vscale x 8 x bfloat> %b, i32 0134 %d = insertelement <4 x bfloat> %a, bfloat %c, i32 0135 ret <4 x bfloat> %d136}137 138define <4 x bfloat> @test_lane7_nxv8bf16(<4 x bfloat> %a, <vscale x 8 x bfloat> %b) {139; CHECK-LABEL: test_lane7_nxv8bf16:140; CHECK: // %bb.0:141; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0142; CHECK-NEXT: mov v0.h[3], v1.h[7]143; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0144; CHECK-NEXT: ret145 %c = extractelement <vscale x 8 x bfloat> %b, i32 7146 %d = insertelement <4 x bfloat> %a, bfloat %c, i32 3147 ret <4 x bfloat> %d148}149 150define <8 x bfloat> @test_q_lane0_nxv8bf16(<8 x bfloat> %a, <vscale x 8 x bfloat> %b) {151; CHECK-LABEL: test_q_lane0_nxv8bf16:152; CHECK: // %bb.0:153; CHECK-NEXT: mov v0.h[0], v1.h[0]154; CHECK-NEXT: ret155 %c = extractelement <vscale x 8 x bfloat> %b, i32 0156 %d = insertelement <8 x bfloat> %a, bfloat %c, i32 0157 ret <8 x bfloat> %d158}159 160define <8 x bfloat> @test_q_lane7_nxv8bf16(<8 x bfloat> %a, <vscale x 8 x bfloat> %b) {161; CHECK-LABEL: test_q_lane7_nxv8bf16:162; CHECK: // %bb.0:163; CHECK-NEXT: mov v0.h[7], v1.h[7]164; CHECK-NEXT: ret165 %c = extractelement <vscale x 8 x bfloat> %b, i32 7166 %d = insertelement <8 x bfloat> %a, bfloat %c, i32 7167 ret <8 x bfloat> %d168}169 170; (negative test) Extracted element is not within Vn171define <8 x bfloat> @test_q_lane8_nxv8bf16(<8 x bfloat> %a, <vscale x 8 x bfloat> %b) {172; CHECK-LABEL: test_q_lane8_nxv8bf16:173; CHECK: // %bb.0:174; CHECK-NEXT: mov z1.h, z1.h[8]175; CHECK-NEXT: mov v0.h[7], v1.h[0]176; CHECK-NEXT: ret177 %c = extractelement <vscale x 8 x bfloat> %b, i32 8178 %d = insertelement <8 x bfloat> %a, bfloat %c, i32 7179 ret <8 x bfloat> %d180}181 182; --------- extraction from nxv8i16183 184define <4 x i16> @test_lane0_nxv8i16(<4 x i16> %a, <vscale x 8 x i16> %b) {185; CHECK-LABEL: test_lane0_nxv8i16:186; CHECK: // %bb.0:187; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0188; CHECK-NEXT: mov v0.h[0], v1.h[0]189; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0190; CHECK-NEXT: ret191 %c = extractelement <vscale x 8 x i16> %b, i32 0192 %d = insertelement <4 x i16> %a, i16 %c, i32 0193 ret <4 x i16> %d194}195 196define <4 x i16> @test_lane7_nxv8i16(<4 x i16> %a, <vscale x 8 x i16> %b) {197; CHECK-LABEL: test_lane7_nxv8i16:198; CHECK: // %bb.0:199; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0200; CHECK-NEXT: mov v0.h[3], v1.h[7]201; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0202; CHECK-NEXT: ret203 %c = extractelement <vscale x 8 x i16> %b, i32 7204 %d = insertelement <4 x i16> %a, i16 %c, i32 3205 ret <4 x i16> %d206}207 208define <8 x i16> @test_q_lane0_nxv8i16(<8 x i16> %a, <vscale x 8 x i16> %b) {209; CHECK-LABEL: test_q_lane0_nxv8i16:210; CHECK: // %bb.0:211; CHECK-NEXT: mov v0.h[0], v1.h[0]212; CHECK-NEXT: ret213 %c = extractelement <vscale x 8 x i16> %b, i32 0214 %d = insertelement <8 x i16> %a, i16 %c, i32 0215 ret <8 x i16> %d216}217 218define <8 x i16> @test_q_lane7_nxv8i16(<8 x i16> %a, <vscale x 8 x i16> %b) {219; CHECK-LABEL: test_q_lane7_nxv8i16:220; CHECK: // %bb.0:221; CHECK-NEXT: mov v0.h[7], v1.h[7]222; CHECK-NEXT: ret223 %c = extractelement <vscale x 8 x i16> %b, i32 7224 %d = insertelement <8 x i16> %a, i16 %c, i32 7225 ret <8 x i16> %d226}227 228; (negative test) Extracted element is not within Vn229define <8 x i16> @test_q_lane8_nxv8i16(<8 x i16> %a, <vscale x 8 x i16> %b) {230; CHECK-LABEL: test_q_lane8_nxv8i16:231; CHECK: // %bb.0:232; CHECK-NEXT: mov z1.h, z1.h[8]233; CHECK-NEXT: fmov w8, s1234; CHECK-NEXT: mov v0.h[7], w8235; CHECK-NEXT: ret236 %c = extractelement <vscale x 8 x i16> %b, i32 8237 %d = insertelement <8 x i16> %a, i16 %c, i32 7238 ret <8 x i16> %d239}240 241; --------- extraction from nxv4f32242 243define <2 x float> @test_lane0_nxv4f32(<2 x float> %a, <vscale x 4 x float> %b) {244; CHECK-LABEL: test_lane0_nxv4f32:245; CHECK: // %bb.0:246; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0247; CHECK-NEXT: mov v0.s[0], v1.s[0]248; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0249; CHECK-NEXT: ret250 %c = extractelement <vscale x 4 x float> %b, i32 0251 %d = insertelement <2 x float> %a, float %c, i32 0252 ret <2 x float> %d253}254 255define <2 x float> @test_lane3_nxv4f32(<2 x float> %a, <vscale x 4 x float> %b) {256; CHECK-LABEL: test_lane3_nxv4f32:257; CHECK: // %bb.0:258; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0259; CHECK-NEXT: mov v0.s[1], v1.s[3]260; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0261; CHECK-NEXT: ret262 %c = extractelement <vscale x 4 x float> %b, i32 3263 %d = insertelement <2 x float> %a, float %c, i32 1264 ret <2 x float> %d265}266 267define <4 x float> @test_q_lane0_nxv4f32(<4 x float> %a, <vscale x 4 x float> %b) {268; CHECK-LABEL: test_q_lane0_nxv4f32:269; CHECK: // %bb.0:270; CHECK-NEXT: mov v0.s[0], v1.s[0]271; CHECK-NEXT: ret272 %c = extractelement <vscale x 4 x float> %b, i32 0273 %d = insertelement <4 x float> %a, float %c, i32 0274 ret <4 x float> %d275}276 277define <4 x float> @test_q_lane3_nxv4f32(<4 x float> %a, <vscale x 4 x float> %b) {278; CHECK-LABEL: test_q_lane3_nxv4f32:279; CHECK: // %bb.0:280; CHECK-NEXT: mov v0.s[3], v1.s[3]281; CHECK-NEXT: ret282 %c = extractelement <vscale x 4 x float> %b, i32 3283 %d = insertelement <4 x float> %a, float %c, i32 3284 ret <4 x float> %d285}286 287; (negative test) Extracted element is not within Vn288define <4 x float> @test_q_lane4_nxv4f32(<4 x float> %a, <vscale x 4 x float> %b) {289; CHECK-LABEL: test_q_lane4_nxv4f32:290; CHECK: // %bb.0:291; CHECK-NEXT: mov z1.s, z1.s[4]292; CHECK-NEXT: mov v0.s[3], v1.s[0]293; CHECK-NEXT: ret294 %c = extractelement <vscale x 4 x float> %b, i32 4295 %d = insertelement <4 x float> %a, float %c, i32 3296 ret <4 x float> %d297}298 299; --------- extraction from nxv4i32300 301define <2 x i32> @test_lane0_nxv4i32(<2 x i32> %a, <vscale x 4 x i32> %b) {302; CHECK-LABEL: test_lane0_nxv4i32:303; CHECK: // %bb.0:304; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0305; CHECK-NEXT: mov v0.s[0], v1.s[0]306; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0307; CHECK-NEXT: ret308 %c = extractelement <vscale x 4 x i32> %b, i32 0309 %d = insertelement <2 x i32> %a, i32 %c, i32 0310 ret <2 x i32> %d311}312 313define <2 x i32> @test_lane3_nxv4i32(<2 x i32> %a, <vscale x 4 x i32> %b) {314; CHECK-LABEL: test_lane3_nxv4i32:315; CHECK: // %bb.0:316; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0317; CHECK-NEXT: mov v0.s[1], v1.s[3]318; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0319; CHECK-NEXT: ret320 %c = extractelement <vscale x 4 x i32> %b, i32 3321 %d = insertelement <2 x i32> %a, i32 %c, i32 1322 ret <2 x i32> %d323}324 325define <4 x i32> @test_q_lane0_nxv4i32(<4 x i32> %a, <vscale x 4 x i32> %b) {326; CHECK-LABEL: test_q_lane0_nxv4i32:327; CHECK: // %bb.0:328; CHECK-NEXT: mov v0.s[0], v1.s[0]329; CHECK-NEXT: ret330 %c = extractelement <vscale x 4 x i32> %b, i32 0331 %d = insertelement <4 x i32> %a, i32 %c, i32 0332 ret <4 x i32> %d333}334 335define <4 x i32> @test_q_lane3_nxv4i32(<4 x i32> %a, <vscale x 4 x i32> %b) {336; CHECK-LABEL: test_q_lane3_nxv4i32:337; CHECK: // %bb.0:338; CHECK-NEXT: mov v0.s[3], v1.s[3]339; CHECK-NEXT: ret340 %c = extractelement <vscale x 4 x i32> %b, i32 3341 %d = insertelement <4 x i32> %a, i32 %c, i32 3342 ret <4 x i32> %d343}344 345; (negative test) Extracted element is not within Vn346define <4 x i32> @test_q_lane4_nxv4i32(<4 x i32> %a, <vscale x 4 x i32> %b) {347; CHECK-LABEL: test_q_lane4_nxv4i32:348; CHECK: // %bb.0:349; CHECK-NEXT: mov z1.s, z1.s[4]350; CHECK-NEXT: fmov w8, s1351; CHECK-NEXT: mov v0.s[3], w8352; CHECK-NEXT: ret353 %c = extractelement <vscale x 4 x i32> %b, i32 4354 %d = insertelement <4 x i32> %a, i32 %c, i32 3355 ret <4 x i32> %d356}357 358; --------- extraction from nxv2f64359 360define <1 x double> @test_lane0_nxv2f64(<1 x double> %a, <vscale x 2 x double> %b) {361; CHECK-LABEL: test_lane0_nxv2f64:362; CHECK: // %bb.0:363; CHECK-NEXT: mov d0, v1.d[0]364; CHECK-NEXT: ret365 %c = extractelement <vscale x 2 x double> %b, i32 0366 %d = insertelement <1 x double> %a, double %c, i32 0367 ret <1 x double> %d368}369 370define <1 x double> @test_lane1_nxv2f64(<1 x double> %a, <vscale x 2 x double> %b) {371; CHECK-LABEL: test_lane1_nxv2f64:372; CHECK: // %bb.0:373; CHECK-NEXT: mov d0, v1.d[1]374; CHECK-NEXT: ret375 %c = extractelement <vscale x 2 x double> %b, i32 1376 %d = insertelement <1 x double> %a, double %c, i32 0377 ret <1 x double> %d378}379 380define <2 x double> @test_q_lane0_nxv2f64(<2 x double> %a, <vscale x 2 x double> %b) {381; CHECK-LABEL: test_q_lane0_nxv2f64:382; CHECK: // %bb.0:383; CHECK-NEXT: mov v0.d[0], v1.d[0]384; CHECK-NEXT: ret385 %c = extractelement <vscale x 2 x double> %b, i32 0386 %d = insertelement <2 x double> %a, double %c, i32 0387 ret <2 x double> %d388}389 390define <2 x double> @test_q_lane1_nxv2f64(<2 x double> %a, <vscale x 2 x double> %b) {391; CHECK-LABEL: test_q_lane1_nxv2f64:392; CHECK: // %bb.0:393; CHECK-NEXT: mov v0.d[1], v1.d[1]394; CHECK-NEXT: ret395 %c = extractelement <vscale x 2 x double> %b, i32 1396 %d = insertelement <2 x double> %a, double %c, i32 1397 ret <2 x double> %d398}399 400; (negative test) Extracted element is not within Vn401define <2 x double> @test_q_lane2_nxv2f64(<2 x double> %a, <vscale x 2 x double> %b) {402; CHECK-LABEL: test_q_lane2_nxv2f64:403; CHECK: // %bb.0:404; CHECK-NEXT: mov z1.d, z1.d[2]405; CHECK-NEXT: mov v0.d[1], v1.d[0]406; CHECK-NEXT: ret407 %c = extractelement <vscale x 2 x double> %b, i32 2408 %d = insertelement <2 x double> %a, double %c, i32 1409 ret <2 x double> %d410}411 412; --------- extraction from nxv2i64413 414define <1 x i64> @test_lane0_nxv2i64(<1 x i64> %a, <vscale x 2 x i64> %b) {415; CHECK-LABEL: test_lane0_nxv2i64:416; CHECK: // %bb.0:417; CHECK-NEXT: mov d0, v1.d[0]418; CHECK-NEXT: ret419 %c = extractelement <vscale x 2 x i64> %b, i32 0420 %d = insertelement <1 x i64> %a, i64 %c, i32 0421 ret <1 x i64> %d422}423 424define <1 x i64> @test_lane1_nxv2i64(<1 x i64> %a, <vscale x 2 x i64> %b) {425; CHECK-LABEL: test_lane1_nxv2i64:426; CHECK: // %bb.0:427; CHECK-NEXT: mov d0, v1.d[1]428; CHECK-NEXT: ret429 %c = extractelement <vscale x 2 x i64> %b, i32 1430 %d = insertelement <1 x i64> %a, i64 %c, i32 0431 ret <1 x i64> %d432}433 434define <2 x i64> @test_q_lane0_nxv2i64(<2 x i64> %a, <vscale x 2 x i64> %b) {435; CHECK-LABEL: test_q_lane0_nxv2i64:436; CHECK: // %bb.0:437; CHECK-NEXT: mov v0.d[0], v1.d[0]438; CHECK-NEXT: ret439 %c = extractelement <vscale x 2 x i64> %b, i32 0440 %d = insertelement <2 x i64> %a, i64 %c, i32 0441 ret <2 x i64> %d442}443 444define <2 x i64> @test_q_lane1_nxv2i64(<2 x i64> %a, <vscale x 2 x i64> %b) {445; CHECK-LABEL: test_q_lane1_nxv2i64:446; CHECK: // %bb.0:447; CHECK-NEXT: mov v0.d[1], v1.d[1]448; CHECK-NEXT: ret449 %c = extractelement <vscale x 2 x i64> %b, i32 1450 %d = insertelement <2 x i64> %a, i64 %c, i32 1451 ret <2 x i64> %d452}453 454; (negative test) Extracted element is not within Vn455define <2 x i64> @test_q_lane2_nxv2i64(<2 x i64> %a, <vscale x 2 x i64> %b) {456; CHECK-LABEL: test_q_lane2_nxv2i64:457; CHECK: // %bb.0:458; CHECK-NEXT: mov z1.d, z1.d[2]459; CHECK-NEXT: fmov x8, d1460; CHECK-NEXT: mov v0.d[1], x8461; CHECK-NEXT: ret462 %c = extractelement <vscale x 2 x i64> %b, i32 2463 %d = insertelement <2 x i64> %a, i64 %c, i32 1464 ret <2 x i64> %d465}466