brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.2 KiB · 42f9bec Raw
418 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -aarch64-sve-vector-bits-min=256 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_2563; RUN: llc -aarch64-sve-vector-bits-min=512 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_5124 5target triple = "aarch64-unknown-linux-gnu"6 7; REVB pattern for shuffle v32i8 -> v16i168define void @test_revbv16i16(ptr %a) #0 {9; CHECK-LABEL: test_revbv16i16:10; CHECK:       // %bb.0:11; CHECK-NEXT:    ptrue p0.b, vl3212; CHECK-NEXT:    ptrue p1.h13; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]14; CHECK-NEXT:    revb z0.h, p1/m, z0.h15; CHECK-NEXT:    st1b { z0.b }, p0, [x0]16; CHECK-NEXT:    ret17  %tmp1 = load <32 x i8>, ptr %a18  %tmp2 = shufflevector <32 x i8> %tmp1, <32 x i8> poison, <32 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14, i32 17, i32 16, i32 19, i32 18, i32 21, i32 20, i32 23, i32 22, i32 poison, i32 24, i32 27, i32 poison, i32 29, i32 28, i32 poison, i32 poison>19  store <32 x i8> %tmp2, ptr %a20  ret void21}22 23; REVB pattern for shuffle v32i8 -> v8i3224define void @test_revbv8i32(ptr %a) #0 {25; CHECK-LABEL: test_revbv8i32:26; CHECK:       // %bb.0:27; CHECK-NEXT:    ptrue p0.b, vl3228; CHECK-NEXT:    ptrue p1.s29; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]30; CHECK-NEXT:    revb z0.s, p1/m, z0.s31; CHECK-NEXT:    st1b { z0.b }, p0, [x0]32; CHECK-NEXT:    ret33  %tmp1 = load <32 x i8>, ptr %a34  %tmp2 = shufflevector <32 x i8> %tmp1, <32 x i8> poison, <32 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12, i32 19, i32 18, i32 17, i32 16, i32 23, i32 22, i32 21, i32 20, i32 27, i32 poison, i32 poison, i32 poison, i32 31, i32 30, i32 29, i32 poison>35  store <32 x i8> %tmp2, ptr %a36  ret void37}38 39; REVB pattern for shuffle v32i8 -> v4i6440define void @test_revbv4i64(ptr %a) #0 {41; CHECK-LABEL: test_revbv4i64:42; CHECK:       // %bb.0:43; CHECK-NEXT:    ptrue p0.b, vl3244; CHECK-NEXT:    ptrue p1.d45; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0]46; CHECK-NEXT:    revb z0.d, p1/m, z0.d47; CHECK-NEXT:    st1b { z0.b }, p0, [x0]48; CHECK-NEXT:    ret49  %tmp1 = load <32 x i8>, ptr %a50  %tmp2 = shufflevector <32 x i8> %tmp1, <32 x i8> poison, <32 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 23, i32 22, i32 21, i32 20, i32 19, i32 18, i32 17, i32 16, i32 31, i32 30, i32 29, i32 poison, i32 27, i32 poison, i32 poison, i32 poison>51  store <32 x i8> %tmp2, ptr %a52  ret void53}54 55; REVH pattern for shuffle v16i16 -> v8i3256define void @test_revhv8i32(ptr %a) #0 {57; CHECK-LABEL: test_revhv8i32:58; CHECK:       // %bb.0:59; CHECK-NEXT:    ptrue p0.h, vl1660; CHECK-NEXT:    ptrue p1.s61; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]62; CHECK-NEXT:    revh z0.s, p1/m, z0.s63; CHECK-NEXT:    st1h { z0.h }, p0, [x0]64; CHECK-NEXT:    ret65  %tmp1 = load <16 x i16>, ptr %a66  %tmp2 = shufflevector <16 x i16> %tmp1, <16 x i16> poison, <16 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>67  store <16 x i16> %tmp2, ptr %a68  ret void69}70 71; REVH pattern for shuffle v16f16 -> v8f3272define void @test_revhv8f32(ptr %a) #0 {73; CHECK-LABEL: test_revhv8f32:74; CHECK:       // %bb.0:75; CHECK-NEXT:    ptrue p0.h, vl1676; CHECK-NEXT:    ptrue p1.s77; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]78; CHECK-NEXT:    revh z0.s, p1/m, z0.s79; CHECK-NEXT:    st1h { z0.h }, p0, [x0]80; CHECK-NEXT:    ret81  %tmp1 = load <16 x half>, ptr %a82  %tmp2 = shufflevector <16 x half> %tmp1, <16 x half> poison, <16 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>83  store <16 x half> %tmp2, ptr %a84  ret void85}86 87; REVH pattern for shuffle v16i16 -> v4i6488define void @test_revhv4i64(ptr %a) #0 {89; CHECK-LABEL: test_revhv4i64:90; CHECK:       // %bb.0:91; CHECK-NEXT:    ptrue p0.h, vl1692; CHECK-NEXT:    ptrue p1.d93; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0]94; CHECK-NEXT:    revh z0.d, p1/m, z0.d95; CHECK-NEXT:    st1h { z0.h }, p0, [x0]96; CHECK-NEXT:    ret97  %tmp1 = load <16 x i16>, ptr %a98  %tmp2 = shufflevector <16 x i16> %tmp1, <16 x i16> poison, <16 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12>99  store <16 x i16> %tmp2, ptr %a100  ret void101}102 103; REVW pattern for shuffle v8i32 -> v4i64104define void @test_revwv4i64(ptr %a) #0 {105; CHECK-LABEL: test_revwv4i64:106; CHECK:       // %bb.0:107; CHECK-NEXT:    ptrue p0.s, vl8108; CHECK-NEXT:    ptrue p1.d109; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]110; CHECK-NEXT:    revw z0.d, p1/m, z0.d111; CHECK-NEXT:    st1w { z0.s }, p0, [x0]112; CHECK-NEXT:    ret113  %tmp1 = load <8 x i32>, ptr %a114  %tmp2 = shufflevector <8 x i32> %tmp1, <8 x i32> poison, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>115  store <8 x i32> %tmp2, ptr %a116  ret void117}118 119; REVW pattern for shuffle v8f32 -> v4f64120define void @test_revwv4f64(ptr %a) #0 {121; CHECK-LABEL: test_revwv4f64:122; CHECK:       // %bb.0:123; CHECK-NEXT:    ptrue p0.s, vl8124; CHECK-NEXT:    ptrue p1.d125; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0]126; CHECK-NEXT:    revw z0.d, p1/m, z0.d127; CHECK-NEXT:    st1w { z0.s }, p0, [x0]128; CHECK-NEXT:    ret129  %tmp1 = load <8 x float>, ptr %a130  %tmp2 = shufflevector <8 x float> %tmp1, <8 x float> poison, <8 x i32> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>131  store <8 x float> %tmp2, ptr %a132  ret void133}134 135; Don't use SVE for 128-bit vectors136define <16 x i8> @test_revv16i8(ptr %a) #0 {137; CHECK-LABEL: test_revv16i8:138; CHECK:       // %bb.0:139; CHECK-NEXT:    ldr q0, [x0]140; CHECK-NEXT:    rev64 v0.16b, v0.16b141; CHECK-NEXT:    ret142  %tmp1 = load <16 x i8>, ptr %a143  %tmp2 = shufflevector <16 x i8> %tmp1, <16 x i8> poison, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>144  ret <16 x i8> %tmp2145}146 147; REVW pattern for shuffle two v8i32 inputs with the second input available.148define void @test_revwv8i32v8i32(ptr %a, ptr %b) #0 {149; CHECK-LABEL: test_revwv8i32v8i32:150; CHECK:       // %bb.0:151; CHECK-NEXT:    ptrue p0.s, vl8152; CHECK-NEXT:    ptrue p1.d153; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x1]154; CHECK-NEXT:    revw z0.d, p1/m, z0.d155; CHECK-NEXT:    st1w { z0.s }, p0, [x0]156; CHECK-NEXT:    ret157  %tmp1 = load <8 x i32>, ptr %a158  %tmp2 = load <8 x i32>, ptr %b159  %tmp3 = shufflevector <8 x i32> %tmp1, <8 x i32> %tmp2, <8 x i32> <i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>160  store <8 x i32> %tmp3, ptr %a161  ret void162}163 164; REVH pattern for shuffle v32i16 with 256 bits and 512 bits SVE.165define void @test_revhv32i16(ptr %a) #0 {166; VBITS_GE_256-LABEL: test_revhv32i16:167; VBITS_GE_256:       // %bb.0:168; VBITS_GE_256-NEXT:    ptrue p0.h, vl16169; VBITS_GE_256-NEXT:    mov x8, #16 // =0x10170; VBITS_GE_256-NEXT:    ptrue p1.d171; VBITS_GE_256-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]172; VBITS_GE_256-NEXT:    ld1h { z1.h }, p0/z, [x0]173; VBITS_GE_256-NEXT:    revh z0.d, p1/m, z0.d174; VBITS_GE_256-NEXT:    revh z1.d, p1/m, z1.d175; VBITS_GE_256-NEXT:    st1h { z0.h }, p0, [x0, x8, lsl #1]176; VBITS_GE_256-NEXT:    st1h { z1.h }, p0, [x0]177; VBITS_GE_256-NEXT:    ret178;179; VBITS_GE_512-LABEL: test_revhv32i16:180; VBITS_GE_512:       // %bb.0:181; VBITS_GE_512-NEXT:    ptrue p0.h, vl32182; VBITS_GE_512-NEXT:    ptrue p1.d183; VBITS_GE_512-NEXT:    ld1h { z0.h }, p0/z, [x0]184; VBITS_GE_512-NEXT:    revh z0.d, p1/m, z0.d185; VBITS_GE_512-NEXT:    st1h { z0.h }, p0, [x0]186; VBITS_GE_512-NEXT:    ret187  %tmp1 = load <32 x i16>, ptr %a188  %tmp2 = shufflevector <32 x i16> %tmp1, <32 x i16> poison, <32 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12, i32 19, i32 18, i32 17, i32 16, i32 23, i32 22, i32 21, i32 20, i32 27, i32 poison, i32 poison, i32 poison, i32 31, i32 30, i32 29, i32 poison>189  store <32 x i16> %tmp2, ptr %a190  ret void191}192 193; Only support to reverse bytes / halfwords / words within elements194define void @test_rev_elts_fail(ptr %a) #1 {195; CHECK-LABEL: test_rev_elts_fail:196; CHECK:       // %bb.0:197; CHECK-NEXT:    adrp x8, .LCPI11_0198; CHECK-NEXT:    add x8, x8, :lo12:.LCPI11_0199; CHECK-NEXT:    ldr z0, [x0]200; CHECK-NEXT:    ldr z1, [x8]201; CHECK-NEXT:    tbl z0.d, { z0.d }, z1.d202; CHECK-NEXT:    str z0, [x0]203; CHECK-NEXT:    ret204  %tmp1 = load <4 x i64>, ptr %a205  %tmp2 = shufflevector <4 x i64> %tmp1, <4 x i64> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2>206  store <4 x i64> %tmp2, ptr %a207  ret void208}209 210; This is the same test as above, but with sve2p1 it can use the REVD instruction to reverse211; the double-words within quard-words.212define void @test_revdv4i64_sve2p1(ptr %a) #2 {213; CHECK-LABEL: test_revdv4i64_sve2p1:214; CHECK:       // %bb.0:215; CHECK-NEXT:    ptrue p0.d, vl4216; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]217; CHECK-NEXT:    revd z0.q, p0/m, z0.q218; CHECK-NEXT:    st1d { z0.d }, p0, [x0]219; CHECK-NEXT:    ret220  %tmp1 = load <4 x i64>, ptr %a221  %tmp2 = shufflevector <4 x i64> %tmp1, <4 x i64> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2>222  store <4 x i64> %tmp2, ptr %a223  ret void224}225 226define void @test_revdv4f64_sve2p1(ptr %a) #2 {227; CHECK-LABEL: test_revdv4f64_sve2p1:228; CHECK:       // %bb.0:229; CHECK-NEXT:    ptrue p0.d, vl4230; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0]231; CHECK-NEXT:    revd z0.q, p0/m, z0.q232; CHECK-NEXT:    st1d { z0.d }, p0, [x0]233; CHECK-NEXT:    ret234  %tmp1 = load <4 x double>, ptr %a235  %tmp2 = shufflevector <4 x double> %tmp1, <4 x double> poison, <4 x i32> <i32 1, i32 0, i32 3, i32 2>236  store <4 x double> %tmp2, ptr %a237  ret void238}239 240; REV instruction will reverse the order of all elements in the vector.241; When the vector length and the target register size are inconsistent,242; the correctness of generated REV instruction for shuffle pattern cannot be guaranteed.243 244; sve-vector-bits-min=256, sve-vector-bits-max is not set, REV inst can't be generated.245define void @test_revv8i32(ptr %a) #0 {246; VBITS_GE_256-LABEL: test_revv8i32:247; VBITS_GE_256:       // %bb.0:248; VBITS_GE_256-NEXT:    ptrue p0.s, vl8249; VBITS_GE_256-NEXT:    index z0.s, #7, #-1250; VBITS_GE_256-NEXT:    ld1w { z1.s }, p0/z, [x0]251; VBITS_GE_256-NEXT:    tbl z0.s, { z1.s }, z0.s252; VBITS_GE_256-NEXT:    st1w { z0.s }, p0, [x0]253; VBITS_GE_256-NEXT:    ret254;255; VBITS_GE_512-LABEL: test_revv8i32:256; VBITS_GE_512:       // %bb.0:257; VBITS_GE_512-NEXT:    ptrue p0.s, vl8258; VBITS_GE_512-NEXT:    adrp x8, .LCPI14_0259; VBITS_GE_512-NEXT:    add x8, x8, :lo12:.LCPI14_0260; VBITS_GE_512-NEXT:    ptrue p1.s, vl16261; VBITS_GE_512-NEXT:    ld1w { z0.s }, p0/z, [x0]262; VBITS_GE_512-NEXT:    ld1w { z1.s }, p1/z, [x8]263; VBITS_GE_512-NEXT:    tbl z0.s, { z0.s }, z1.s264; VBITS_GE_512-NEXT:    st1w { z0.s }, p0, [x0]265; VBITS_GE_512-NEXT:    ret266  %tmp1 = load <8 x i32>, ptr %a267  %tmp2 = shufflevector <8 x i32> %tmp1, <8 x i32> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>268  store <8 x i32> %tmp2, ptr %a269  ret void270}271 272; REV pattern for v32i8 shuffle with vscale_range(2,2)273define void @test_revv32i8_vl256(ptr %a) #1 {274; CHECK-LABEL: test_revv32i8_vl256:275; CHECK:       // %bb.0:276; CHECK-NEXT:    ldr z0, [x0]277; CHECK-NEXT:    rev z0.b, z0.b278; CHECK-NEXT:    str z0, [x0]279; CHECK-NEXT:    ret280  %tmp1 = load <32 x i8>, ptr %a281  %tmp2 = shufflevector <32 x i8> %tmp1, <32 x i8> poison, <32 x i32> <i32 31, i32 30, i32 29, i32 28, i32 27, i32 26, i32 25, i32 24, i32 23, i32 22, i32 21, i32 20, i32 19, i32 18, i32 17, i32 16, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>282  store <32 x i8> %tmp2, ptr %a283  ret void284}285 286; REV pattern for v16i16 shuffle with vscale_range(2,2)287define void @test_revv16i16_vl256(ptr %a) #1 {288; CHECK-LABEL: test_revv16i16_vl256:289; CHECK:       // %bb.0:290; CHECK-NEXT:    ldr z0, [x0]291; CHECK-NEXT:    rev z0.h, z0.h292; CHECK-NEXT:    str z0, [x0]293; CHECK-NEXT:    ret294  %tmp1 = load <16 x i16>, ptr %a295  %tmp2 = shufflevector <16 x i16> %tmp1, <16 x i16> poison, <16 x i32> <i32 poison, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>296  store <16 x i16> %tmp2, ptr %a297  ret void298}299 300; REV pattern for v8f32 shuffle with vscale_range(2,2)301define void @test_revv8f32_vl256(ptr %a) #1 {302; CHECK-LABEL: test_revv8f32_vl256:303; CHECK:       // %bb.0:304; CHECK-NEXT:    ldr z0, [x0]305; CHECK-NEXT:    rev z0.s, z0.s306; CHECK-NEXT:    str z0, [x0]307; CHECK-NEXT:    ret308  %tmp1 = load <8 x float>, ptr %a309  %tmp2 = shufflevector <8 x float> %tmp1, <8 x float> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>310  store <8 x float> %tmp2, ptr %a311  ret void312}313 314; REV pattern for v4f64 shuffle with vscale_range(2,2)315define void @test_revv4f64_vl256(ptr %a) #1 {316; CHECK-LABEL: test_revv4f64_vl256:317; CHECK:       // %bb.0:318; CHECK-NEXT:    ldr z0, [x0]319; CHECK-NEXT:    rev z0.d, z0.d320; CHECK-NEXT:    str z0, [x0]321; CHECK-NEXT:    ret322  %tmp1 = load <4 x double>, ptr %a323  %tmp2 = shufflevector <4 x double> %tmp1, <4 x double> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>324  store <4 x double> %tmp2, ptr %a325  ret void326}327 328; REV pattern for shuffle two v8i32 inputs with the second input available, vscale_range(2,2).329define void @test_revv8i32v8i32(ptr %a, ptr %b) #1 {330; CHECK-LABEL: test_revv8i32v8i32:331; CHECK:       // %bb.0:332; CHECK-NEXT:    ldr z0, [x1]333; CHECK-NEXT:    rev z0.s, z0.s334; CHECK-NEXT:    str z0, [x0]335; CHECK-NEXT:    ret336  %tmp1 = load <8 x i32>, ptr %a337  %tmp2 = load <8 x i32>, ptr %b338  %tmp3 = shufflevector <8 x i32> %tmp1, <8 x i32> %tmp2, <8 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>339  store <8 x i32> %tmp3, ptr %a340  ret void341}342 343; Illegal REV pattern.344define void @test_rev_fail(ptr %a) #1 {345; CHECK-LABEL: test_rev_fail:346; CHECK:       // %bb.0:347; CHECK-NEXT:    adrp x8, .LCPI20_0348; CHECK-NEXT:    add x8, x8, :lo12:.LCPI20_0349; CHECK-NEXT:    ldr z0, [x0]350; CHECK-NEXT:    ldr z1, [x8]351; CHECK-NEXT:    tbl z0.h, { z0.h }, z1.h352; CHECK-NEXT:    str z0, [x0]353; CHECK-NEXT:    ret354  %tmp1 = load <16 x i16>, ptr %a355  %tmp2 = shufflevector <16 x i16> %tmp1, <16 x i16> poison, <16 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0, i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8>356  store <16 x i16> %tmp2, ptr %a357  ret void358}359 360; Don't use SVE for 128-bit shuffle with two inputs361define void @test_revv8i16v8i16(ptr %a, ptr %b, ptr %c) #1 {362; CHECK-LABEL: test_revv8i16v8i16:363; CHECK:       // %bb.0:364; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill365; CHECK-NEXT:    sub x9, sp, #48366; CHECK-NEXT:    mov x29, sp367; CHECK-NEXT:    and sp, x9, #0xffffffffffffffe0368; CHECK-NEXT:    .cfi_def_cfa w29, 16369; CHECK-NEXT:    .cfi_offset w30, -8370; CHECK-NEXT:    .cfi_offset w29, -16371; CHECK-NEXT:    ldr q0, [x1]372; CHECK-NEXT:    ldr q5, [x0]373; CHECK-NEXT:    mov x8, sp374; CHECK-NEXT:    mov h1, v0.h[4]375; CHECK-NEXT:    mov h2, v0.h[5]376; CHECK-NEXT:    mov h3, v0.h[6]377; CHECK-NEXT:    mov h4, v0.h[7]378; CHECK-NEXT:    str h0, [sp, #22]379; CHECK-NEXT:    st1 { v5.h }[3], [x8]380; CHECK-NEXT:    str h5, [sp, #6]381; CHECK-NEXT:    str h1, [sp, #30]382; CHECK-NEXT:    mov h1, v0.h[1]383; CHECK-NEXT:    str h2, [sp, #28]384; CHECK-NEXT:    mov h2, v0.h[2]385; CHECK-NEXT:    mov h0, v0.h[3]386; CHECK-NEXT:    str h3, [sp, #26]387; CHECK-NEXT:    mov h3, v5.h[2]388; CHECK-NEXT:    str h4, [sp, #24]389; CHECK-NEXT:    str h1, [sp, #20]390; CHECK-NEXT:    mov h1, v5.h[4]391; CHECK-NEXT:    str h2, [sp, #18]392; CHECK-NEXT:    mov h2, v5.h[5]393; CHECK-NEXT:    str h0, [sp, #16]394; CHECK-NEXT:    mov h0, v5.h[6]395; CHECK-NEXT:    str h3, [sp, #2]396; CHECK-NEXT:    str h1, [sp, #14]397; CHECK-NEXT:    mov h1, v5.h[7]398; CHECK-NEXT:    str h2, [sp, #12]399; CHECK-NEXT:    mov h2, v5.h[1]400; CHECK-NEXT:    str h0, [sp, #10]401; CHECK-NEXT:    str h1, [sp, #8]402; CHECK-NEXT:    str h2, [sp, #4]403; CHECK-NEXT:    ldr z0, [x8]404; CHECK-NEXT:    str z0, [x2]405; CHECK-NEXT:    mov sp, x29406; CHECK-NEXT:    ldp x29, x30, [sp], #16 // 16-byte Folded Reload407; CHECK-NEXT:    ret408  %tmp1 = load <8 x i16>, ptr %a409  %tmp2 = load <8 x i16>, ptr %b410  %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <16 x i32> <i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4, i32 11, i32 10, i32 9, i32 8, i32 15, i32 14, i32 13, i32 12>411  store <16 x i16> %tmp3, ptr %c412  ret void413}414 415attributes #0 = { "target-features"="+sve" }416attributes #1 = { "target-features"="+sve" vscale_range(2,2) }417attributes #2 = { "target-features"="+sve2p1" }418