brintos

brintos / llvm-project-archived public Read only

0
0
Text · 37.3 KiB · 7b43874 Raw
983 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; RUN: llc -aarch64-sve-vector-bits-min=2048 < %s | FileCheck %s -check-prefixes=CHECK,VBITS_GE_5125 6target triple = "aarch64-unknown-linux-gnu"7 8; Note that both the vector.extract intrinsics and SK_ExtractSubvector9; shufflevector instructions get detected as a extract_subvector ISD node in10; SelectionDAG. We'll test both cases for the sake of completeness, even though11; vector.extract intrinsics should get lowered into shufflevector by the time we12; reach the backend.13 14; i815 16; Don't use SVE for 64-bit vectors.17define <4 x i8> @extract_subvector_v8i8(<8 x i8> %op) vscale_range(2,0) #0 {18; CHECK-LABEL: extract_subvector_v8i8:19; CHECK:       // %bb.0:20; CHECK-NEXT:    zip2 v0.8b, v0.8b, v0.8b21; CHECK-NEXT:    ret22  %ret = call <4 x i8> @llvm.vector.extract.v4i8.v8i8(<8 x i8> %op, i64 4)23  ret <4 x i8> %ret24}25 26; Don't use SVE for 128-bit vectors.27define <8 x i8> @extract_subvector_v16i8(<16 x i8> %op) vscale_range(2,0) #0 {28; CHECK-LABEL: extract_subvector_v16i8:29; CHECK:       // %bb.0:30; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #831; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q032; CHECK-NEXT:    ret33  %ret = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> %op, i64 8)34  ret <8 x i8> %ret35}36 37define void @extract_subvector_v32i8(ptr %a, ptr %b) vscale_range(2,0) #0 {38; CHECK-LABEL: extract_subvector_v32i8:39; CHECK:       // %bb.0:40; CHECK-NEXT:    ldr q0, [x0, #16]41; CHECK-NEXT:    str q0, [x1]42; CHECK-NEXT:    ret43  %op = load <32 x i8>, ptr %a44  %ret = call <16 x i8> @llvm.vector.extract.v16i8.v32i8(<32 x i8> %op, i64 16)45  store <16 x i8> %ret, ptr %b46  ret void47}48 49define void @extract_v32i8_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {50; CHECK-LABEL: extract_v32i8_halves:51; CHECK:       // %bb.0: // %entry52; CHECK-NEXT:    ldr z0, [x0]53; CHECK-NEXT:    movprfx z1, z054; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #1655; CHECK-NEXT:    str q1, [x1]56; CHECK-NEXT:    str q0, [x2]57; CHECK-NEXT:    ret58entry:59  %b = load <32 x i8>, ptr %in60  %hi = shufflevector <32 x i8> %b, <32 x i8> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>61  store <16 x i8> %hi, ptr %out62  %lo = shufflevector <32 x i8> %b, <32 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>63  store <16 x i8> %lo, ptr %out264  ret void65}66 67define void @extract_v32i8_half_unaligned(ptr %in, ptr %out) #0 vscale_range(2,2) {68; CHECK-LABEL: extract_v32i8_half_unaligned:69; CHECK:       // %bb.0: // %entry70; CHECK-NEXT:    ldr z0, [x0]71; CHECK-NEXT:    movprfx z1, z072; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #1673; CHECK-NEXT:    ext v0.16b, v0.16b, v1.16b, #474; CHECK-NEXT:    str q0, [x1]75; CHECK-NEXT:    ret76entry:77  %b = load <32 x i8>, ptr %in78  %d = shufflevector <32 x i8> %b, <32 x i8> poison, <16 x i32> <i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19>79  store <16 x i8> %d, ptr %out80  ret void81}82 83define void @extract_v32i8_quarters(ptr %in, ptr %out, ptr %out2, ptr %out3, ptr %out4) #0 vscale_range(2,2) {84; CHECK-LABEL: extract_v32i8_quarters:85; CHECK:       // %bb.0: // %entry86; CHECK-NEXT:    ldr z0, [x0]87; CHECK-NEXT:    movprfx z1, z088; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #1689; CHECK-NEXT:    movprfx z2, z090; CHECK-NEXT:    ext z2.b, z2.b, z0.b, #2491; CHECK-NEXT:    movprfx z3, z092; CHECK-NEXT:    ext z3.b, z3.b, z0.b, #893; CHECK-NEXT:    str d1, [x1]94; CHECK-NEXT:    str d2, [x2]95; CHECK-NEXT:    str d0, [x3]96; CHECK-NEXT:    str d3, [x4]97; CHECK-NEXT:    ret98entry:99  %b = load <32 x i8>, ptr %in100  %hilo = shufflevector <32 x i8> %b, <32 x i8> poison, <8 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23>101  store <8 x i8> %hilo, ptr %out102  %hihi = shufflevector <32 x i8> %b, <32 x i8> poison, <8 x i32> <i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>103  store <8 x i8> %hihi, ptr %out2104  %lolo = shufflevector <32 x i8> %b, <32 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>105  store <8 x i8> %lolo, ptr %out3106  %lohi = shufflevector <32 x i8> %b, <32 x i8> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>107  store <8 x i8> %lohi, ptr %out4108  ret void109}110 111define void @extract_subvector_v64i8(ptr %a, ptr %b) #0 {112; CHECK-LABEL: extract_subvector_v64i8:113; CHECK:       // %bb.0:114; CHECK-NEXT:    ptrue p0.b, vl32115; CHECK-NEXT:    mov w8, #32 // =0x20116; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]117; CHECK-NEXT:    st1b { z0.b }, p0, [x1]118; CHECK-NEXT:    ret119  %op = load <64 x i8>, ptr %a120  %ret = call <32 x i8> @llvm.vector.extract.v32i8.v64i8(<64 x i8> %op, i64 32)121  store <32 x i8> %ret, ptr %b122  ret void123}124 125define void @extract_v64i8_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {126; CHECK-LABEL: extract_v64i8_halves:127; CHECK:       // %bb.0: // %entry128; CHECK-NEXT:    ldr z0, [x0]129; CHECK-NEXT:    ptrue p0.b, vl32130; CHECK-NEXT:    movprfx z1, z0131; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #32132; CHECK-NEXT:    st1b { z1.b }, p0, [x1]133; CHECK-NEXT:    st1b { z0.b }, p0, [x2]134; CHECK-NEXT:    ret135entry:136  %b = load <64 x i8>, ptr %in137  %hi = shufflevector <64 x i8> %b, <64 x i8> poison, <32 x i32> <i32 32, i32 33, i32 34, i32 35, i32 36, i32 37, i32 38, i32 39, i32 40, i32 41, i32 42, i32 43, i32 44, i32 45, i32 46, i32 47, i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55, i32 56, i32 57, i32 58, i32 59, i32 60, i32 61, i32 62, i32 63>138  store <32 x i8> %hi, ptr %out139  %lo = shufflevector <64 x i8> %b, <64 x i8> poison, <32 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>140  store <32 x i8> %lo, ptr %out2141  ret void142}143 144define void @extract_subvector_v128i8(ptr %a, ptr %b) vscale_range(8,0) #0 {145; CHECK-LABEL: extract_subvector_v128i8:146; CHECK:       // %bb.0:147; CHECK-NEXT:    ptrue p0.b, vl64148; CHECK-NEXT:    mov w8, #64 // =0x40149; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]150; CHECK-NEXT:    st1b { z0.b }, p0, [x1]151; CHECK-NEXT:    ret152  %op = load <128 x i8>, ptr %a153  %ret = call <64 x i8> @llvm.vector.extract.v64i8.v128i8(<128 x i8> %op, i64 64)154  store <64 x i8> %ret, ptr %b155  ret void156}157 158define void @extract_subvector_v256i8(ptr %a, ptr %b) vscale_range(16,0) #0 {159; CHECK-LABEL: extract_subvector_v256i8:160; CHECK:       // %bb.0:161; CHECK-NEXT:    ptrue p0.b, vl128162; CHECK-NEXT:    mov w8, #128 // =0x80163; CHECK-NEXT:    ld1b { z0.b }, p0/z, [x0, x8]164; CHECK-NEXT:    st1b { z0.b }, p0, [x1]165; CHECK-NEXT:    ret166  %op = load <256 x i8>, ptr %a167  %ret = call <128 x i8> @llvm.vector.extract.v128i8.v256i8(<256 x i8> %op, i64 128)168  store <128 x i8> %ret, ptr %b169  ret void170}171 172; i16173 174; Don't use SVE for 64-bit vectors.175define <2 x i16> @extract_subvector_v4i16(<4 x i16> %op) vscale_range(2,0) #0 {176; CHECK-LABEL: extract_subvector_v4i16:177; CHECK:       // %bb.0:178; CHECK-NEXT:    zip2 v0.4h, v0.4h, v0.4h179; CHECK-NEXT:    ret180  %ret = call <2 x i16> @llvm.vector.extract.v2i16.v4i16(<4 x i16> %op, i64 2)181  ret <2 x i16> %ret182}183 184; Don't use SVE for 128-bit vectors.185define <4 x i16> @extract_subvector_v8i16(<8 x i16> %op) vscale_range(2,0) #0 {186; CHECK-LABEL: extract_subvector_v8i16:187; CHECK:       // %bb.0:188; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8189; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0190; CHECK-NEXT:    ret191  %ret = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %op, i64 4)192  ret <4 x i16> %ret193}194 195define void @extract_subvector_v16i16(ptr %a, ptr %b) vscale_range(2,0) #0 {196; CHECK-LABEL: extract_subvector_v16i16:197; CHECK:       // %bb.0:198; CHECK-NEXT:    ldr q0, [x0, #16]199; CHECK-NEXT:    str q0, [x1]200; CHECK-NEXT:    ret201  %op = load <16 x i16>, ptr %a202  %ret = call <8 x i16> @llvm.vector.extract.v8i16.v16i16(<16 x i16> %op, i64 8)203  store <8 x i16> %ret, ptr %b204  ret void205}206 207define void @extract_v16i16_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {208; CHECK-LABEL: extract_v16i16_halves:209; CHECK:       // %bb.0: // %entry210; CHECK-NEXT:    ldr z0, [x0]211; CHECK-NEXT:    movprfx z1, z0212; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #16213; CHECK-NEXT:    str q1, [x1]214; CHECK-NEXT:    str q0, [x2]215; CHECK-NEXT:    ret216entry:217  %b = load <16 x i16>, ptr %in218  %hi = shufflevector <16 x i16> %b, <16 x i16> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>219  store <8 x i16> %hi, ptr %out220  %lo = shufflevector <16 x i16> %b, <16 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>221  store <8 x i16> %lo, ptr %out2222  ret void223}224 225define void @extract_subvector_v32i16(ptr %a, ptr %b) #0 {226; CHECK-LABEL: extract_subvector_v32i16:227; CHECK:       // %bb.0:228; CHECK-NEXT:    ptrue p0.h, vl16229; CHECK-NEXT:    mov x8, #16 // =0x10230; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]231; CHECK-NEXT:    st1h { z0.h }, p0, [x1]232; CHECK-NEXT:    ret233  %op = load <32 x i16>, ptr %a234  %ret = call <16 x i16> @llvm.vector.extract.v16i16.v32i16(<32 x i16> %op, i64 16)235  store <16 x i16> %ret, ptr %b236  ret void237}238 239define void @extract_v32i16_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {240; CHECK-LABEL: extract_v32i16_halves:241; CHECK:       // %bb.0: // %entry242; CHECK-NEXT:    ldr z0, [x0]243; CHECK-NEXT:    ptrue p0.h, vl16244; CHECK-NEXT:    movprfx z1, z0245; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #32246; CHECK-NEXT:    st1h { z1.h }, p0, [x1]247; CHECK-NEXT:    st1h { z0.h }, p0, [x2]248; CHECK-NEXT:    ret249entry:250  %b = load <32 x i16>, ptr %in251  %hi = shufflevector <32 x i16> %b, <32 x i16> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>252  store <16 x i16> %hi, ptr %out253  %lo = shufflevector <32 x i16> %b, <32 x i16> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>254  store <16 x i16> %lo, ptr %out2255  ret void256}257 258define void @extract_subvector_v64i16(ptr %a, ptr %b) vscale_range(8,0) #0 {259; CHECK-LABEL: extract_subvector_v64i16:260; CHECK:       // %bb.0:261; CHECK-NEXT:    ptrue p0.h, vl32262; CHECK-NEXT:    mov x8, #32 // =0x20263; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]264; CHECK-NEXT:    st1h { z0.h }, p0, [x1]265; CHECK-NEXT:    ret266  %op = load <64 x i16>, ptr %a267  %ret = call <32 x i16> @llvm.vector.extract.v32i16.v64i16(<64 x i16> %op, i64 32)268  store <32 x i16> %ret, ptr %b269  ret void270}271 272define void @extract_subvector_v128i16(ptr %a, ptr %b) vscale_range(16,0) #0 {273; CHECK-LABEL: extract_subvector_v128i16:274; CHECK:       // %bb.0:275; CHECK-NEXT:    ptrue p0.h, vl64276; CHECK-NEXT:    mov x8, #64 // =0x40277; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]278; CHECK-NEXT:    st1h { z0.h }, p0, [x1]279; CHECK-NEXT:    ret280  %op = load <128 x i16>, ptr %a281  %ret = call <64 x i16> @llvm.vector.extract.v64i16.v128i16(<128 x i16> %op, i64 64)282  store <64 x i16> %ret, ptr %b283  ret void284}285 286; i32287 288; Don't use SVE for 64-bit vectors.289define <1 x i32> @extract_subvector_v2i32(<2 x i32> %op) vscale_range(2,0) #0 {290; CHECK-LABEL: extract_subvector_v2i32:291; CHECK:       // %bb.0:292; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0293; CHECK-NEXT:    dup v0.2s, v0.s[1]294; CHECK-NEXT:    ret295  %ret = call <1 x i32> @llvm.vector.extract.v1i32.v2i32(<2 x i32> %op, i64 1)296  ret <1 x i32> %ret297}298 299; Don't use SVE for 128-bit vectors.300define <2 x i32> @extract_subvector_v4i32(<4 x i32> %op) vscale_range(2,0) #0 {301; CHECK-LABEL: extract_subvector_v4i32:302; CHECK:       // %bb.0:303; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8304; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0305; CHECK-NEXT:    ret306  %ret = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %op, i64 2)307  ret <2 x i32> %ret308}309 310define void @extract_subvector_v8i32(ptr %a, ptr %b) vscale_range(2,0) #0 {311; CHECK-LABEL: extract_subvector_v8i32:312; CHECK:       // %bb.0:313; CHECK-NEXT:    ldr q0, [x0, #16]314; CHECK-NEXT:    str q0, [x1]315; CHECK-NEXT:    ret316  %op = load <8 x i32>, ptr %a317  %ret = call <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32> %op, i64 4)318  store <4 x i32> %ret, ptr %b319  ret void320}321 322define void @extract_v8i32_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {323; CHECK-LABEL: extract_v8i32_halves:324; CHECK:       // %bb.0: // %entry325; CHECK-NEXT:    ldr z0, [x0]326; CHECK-NEXT:    movprfx z1, z0327; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #16328; CHECK-NEXT:    str q1, [x1]329; CHECK-NEXT:    str q0, [x2]330; CHECK-NEXT:    ret331entry:332  %b = load <8 x i32>, ptr %in333  %hi = shufflevector <8 x i32> %b, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>334  store <4 x i32> %hi, ptr %out335  %lo = shufflevector <8 x i32> %b, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>336  store <4 x i32> %lo, ptr %out2337  ret void338}339 340define void @extract_subvector_v16i32(ptr %a, ptr %b) #0 {341; CHECK-LABEL: extract_subvector_v16i32:342; CHECK:       // %bb.0:343; CHECK-NEXT:    ptrue p0.s, vl8344; CHECK-NEXT:    mov x8, #8 // =0x8345; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]346; CHECK-NEXT:    st1w { z0.s }, p0, [x1]347; CHECK-NEXT:    ret348  %op = load <16 x i32>, ptr %a349  %ret = call <8 x i32> @llvm.vector.extract.v8i32.v16i32(<16 x i32> %op, i64 8)350  store <8 x i32> %ret, ptr %b351  ret void352}353 354define void @extract_v16i32_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {355; CHECK-LABEL: extract_v16i32_halves:356; CHECK:       // %bb.0: // %entry357; CHECK-NEXT:    ldr z0, [x0]358; CHECK-NEXT:    ptrue p0.s, vl8359; CHECK-NEXT:    movprfx z1, z0360; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #32361; CHECK-NEXT:    st1w { z1.s }, p0, [x1]362; CHECK-NEXT:    st1w { z0.s }, p0, [x2]363; CHECK-NEXT:    ret364entry:365  %b = load <16 x i32>, ptr %in366  %hi = shufflevector <16 x i32> %b, <16 x i32> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>367  store <8 x i32> %hi, ptr %out368  %lo = shufflevector <16 x i32> %b, <16 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>369  store <8 x i32> %lo, ptr %out2370  ret void371}372 373define void @extract_subvector_v32i32(ptr %a, ptr %b) vscale_range(8,0) #0 {374; CHECK-LABEL: extract_subvector_v32i32:375; CHECK:       // %bb.0:376; CHECK-NEXT:    ptrue p0.s, vl16377; CHECK-NEXT:    mov x8, #16 // =0x10378; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]379; CHECK-NEXT:    st1w { z0.s }, p0, [x1]380; CHECK-NEXT:    ret381  %op = load <32 x i32>, ptr %a382  %ret = call <16 x i32> @llvm.vector.extract.v16i32.v32i32(<32 x i32> %op, i64 16)383  store <16 x i32> %ret, ptr %b384  ret void385}386 387define void @extract_subvector_v64i32(ptr %a, ptr %b) vscale_range(16,0) #0 {388; CHECK-LABEL: extract_subvector_v64i32:389; CHECK:       // %bb.0:390; CHECK-NEXT:    ptrue p0.s, vl32391; CHECK-NEXT:    mov x8, #32 // =0x20392; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]393; CHECK-NEXT:    st1w { z0.s }, p0, [x1]394; CHECK-NEXT:    ret395  %op = load <64 x i32>, ptr %a396  %ret = call <32 x i32> @llvm.vector.extract.v32i32.v64i32(<64 x i32> %op, i64 32)397  store <32 x i32> %ret, ptr %b398  ret void399}400 401; i64402 403; Don't use SVE for 128-bit vectors.404define <1 x i64> @extract_subvector_v2i64(<2 x i64> %op) vscale_range(2,0) #0 {405; CHECK-LABEL: extract_subvector_v2i64:406; CHECK:       // %bb.0:407; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8408; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0409; CHECK-NEXT:    ret410  %ret = call <1 x i64> @llvm.vector.extract.v1i64.v2i64(<2 x i64> %op, i64 1)411  ret <1 x i64> %ret412}413 414define void @extract_subvector_v4i64(ptr %a, ptr %b) vscale_range(2,0) #0 {415; CHECK-LABEL: extract_subvector_v4i64:416; CHECK:       // %bb.0:417; CHECK-NEXT:    ldr q0, [x0, #16]418; CHECK-NEXT:    str q0, [x1]419; CHECK-NEXT:    ret420  %op = load <4 x i64>, ptr %a421  %ret = call <2 x i64> @llvm.vector.extract.v2i64.v4i64(<4 x i64> %op, i64 2)422  store <2 x i64> %ret, ptr %b423  ret void424}425 426define void @extract_v4i64_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {427; CHECK-LABEL: extract_v4i64_halves:428; CHECK:       // %bb.0: // %entry429; CHECK-NEXT:    ldr z0, [x0]430; CHECK-NEXT:    movprfx z1, z0431; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #16432; CHECK-NEXT:    str q1, [x1]433; CHECK-NEXT:    str q0, [x2]434; CHECK-NEXT:    ret435entry:436  %b = load <4 x i64>, ptr %in437  %hi = shufflevector <4 x i64> %b, <4 x i64> poison, <2 x i32> <i32 2, i32 3>438  store <2 x i64> %hi, ptr %out439  %lo = shufflevector <4 x i64> %b, <4 x i64> poison, <2 x i32> <i32 0, i32 1>440  store <2 x i64> %lo, ptr %out2441  ret void442}443 444define void @extract_subvector_v8i64(ptr %a, ptr %b) vscale_range(2,0) #0 {445; CHECK-LABEL: extract_subvector_v8i64:446; CHECK:       // %bb.0:447; CHECK-NEXT:    ptrue p0.d, vl4448; CHECK-NEXT:    mov x8, #4 // =0x4449; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]450; CHECK-NEXT:    st1d { z0.d }, p0, [x1]451; CHECK-NEXT:    ret452  %op = load <8 x i64>, ptr %a453  %ret = call <4 x i64> @llvm.vector.extract.v4i64.v8i64(<8 x i64> %op, i64 4)454  store <4 x i64> %ret, ptr %b455  ret void456}457 458define void @extract_v8i64_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {459; CHECK-LABEL: extract_v8i64_halves:460; CHECK:       // %bb.0: // %entry461; CHECK-NEXT:    ldr z0, [x0]462; CHECK-NEXT:    ptrue p0.d, vl4463; CHECK-NEXT:    movprfx z1, z0464; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #32465; CHECK-NEXT:    st1d { z1.d }, p0, [x1]466; CHECK-NEXT:    st1d { z0.d }, p0, [x2]467; CHECK-NEXT:    ret468entry:469  %b = load <8 x i64>, ptr %in470  %hi = shufflevector <8 x i64> %b, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>471  store <4 x i64> %hi, ptr %out472  %lo = shufflevector <8 x i64> %b, <8 x i64> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>473  store <4 x i64> %lo, ptr %out2474  ret void475}476 477define void @extract_subvector_v16i64(ptr %a, ptr %b) #0 {478; VBITS_GE_256-LABEL: extract_subvector_v16i64:479; VBITS_GE_256:       // %bb.0:480; VBITS_GE_256-NEXT:    ptrue p0.d, vl4481; VBITS_GE_256-NEXT:    mov x8, #12 // =0xc482; VBITS_GE_256-NEXT:    mov x9, #8 // =0x8483; VBITS_GE_256-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]484; VBITS_GE_256-NEXT:    ld1d { z1.d }, p0/z, [x0, x9, lsl #3]485; VBITS_GE_256-NEXT:    mov x8, #4 // =0x4486; VBITS_GE_256-NEXT:    st1d { z0.d }, p0, [x1, x8, lsl #3]487; VBITS_GE_256-NEXT:    st1d { z1.d }, p0, [x1]488; VBITS_GE_256-NEXT:    ret489;490; VBITS_GE_512-LABEL: extract_subvector_v16i64:491; VBITS_GE_512:       // %bb.0:492; VBITS_GE_512-NEXT:    ptrue p0.d, vl8493; VBITS_GE_512-NEXT:    mov x8, #8 // =0x8494; VBITS_GE_512-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]495; VBITS_GE_512-NEXT:    st1d { z0.d }, p0, [x1]496; VBITS_GE_512-NEXT:    ret497  %op = load <16 x i64>, ptr %a498  %ret = call <8 x i64> @llvm.vector.extract.v8i64.v16i64(<16 x i64> %op, i64 8)499  store <8 x i64> %ret, ptr %b500  ret void501}502 503define void @extract_subvector_v32i64(ptr %a, ptr %b) vscale_range(8,0) #0 {504; CHECK-LABEL: extract_subvector_v32i64:505; CHECK:       // %bb.0:506; CHECK-NEXT:    ptrue p0.d, vl16507; CHECK-NEXT:    mov x8, #16 // =0x10508; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]509; CHECK-NEXT:    st1d { z0.d }, p0, [x1]510; CHECK-NEXT:    ret511  %op = load <32 x i64>, ptr %a512  %ret = call <16 x i64> @llvm.vector.extract.v16i64.v32i64(<32 x i64> %op, i64 16)513  store <16 x i64> %ret, ptr %b514  ret void515}516 517; f16518 519; Don't use SVE for 64-bit vectors.520define <2 x half> @extract_subvector_v4f16(<4 x half> %op) vscale_range(16,0) #0 {521; CHECK-LABEL: extract_subvector_v4f16:522; CHECK:       // %bb.0:523; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0524; CHECK-NEXT:    dup v0.2s, v0.s[1]525; CHECK-NEXT:    ret526  %ret = call <2 x half> @llvm.vector.extract.v2f16.v4f16(<4 x half> %op, i64 2)527  ret <2 x half> %ret528}529 530; Don't use SVE for 128-bit vectors.531define <4 x half> @extract_subvector_v8f16(<8 x half> %op) vscale_range(2,0) #0 {532; CHECK-LABEL: extract_subvector_v8f16:533; CHECK:       // %bb.0:534; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8535; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0536; CHECK-NEXT:    ret537  %ret = call <4 x half> @llvm.vector.extract.v4f16.v8f16(<8 x half> %op, i64 4)538  ret <4 x half> %ret539}540 541define void @extract_subvector_v16f16(ptr %a, ptr %b) vscale_range(2,0) #0 {542; CHECK-LABEL: extract_subvector_v16f16:543; CHECK:       // %bb.0:544; CHECK-NEXT:    ldr q0, [x0, #16]545; CHECK-NEXT:    str q0, [x1]546; CHECK-NEXT:    ret547  %op = load <16 x half>, ptr %a548  %ret = call <8 x half> @llvm.vector.extract.v8f16.v16f16(<16 x half> %op, i64 8)549  store <8 x half> %ret, ptr %b550  ret void551}552 553define void @extract_v16half_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {554; CHECK-LABEL: extract_v16half_halves:555; CHECK:       // %bb.0: // %entry556; CHECK-NEXT:    ldr z0, [x0]557; CHECK-NEXT:    movprfx z1, z0558; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #16559; CHECK-NEXT:    str q1, [x1]560; CHECK-NEXT:    str q0, [x2]561; CHECK-NEXT:    ret562entry:563  %b = load <16 x half>, ptr %in564  %hi = shufflevector <16 x half> %b, <16 x half> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>565  store <8 x half> %hi, ptr %out566  %lo = shufflevector <16 x half> %b, <16 x half> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>567  store <8 x half> %lo, ptr %out2568  ret void569}570 571define void @extract_subvector_v32f16(ptr %a, ptr %b) #0 {572; CHECK-LABEL: extract_subvector_v32f16:573; CHECK:       // %bb.0:574; CHECK-NEXT:    ptrue p0.h, vl16575; CHECK-NEXT:    mov x8, #16 // =0x10576; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]577; CHECK-NEXT:    st1h { z0.h }, p0, [x1]578; CHECK-NEXT:    ret579  %op = load <32 x half>, ptr %a580  %ret = call <16 x half> @llvm.vector.extract.v16f16.v32f16(<32 x half> %op, i64 16)581  store <16 x half> %ret, ptr %b582  ret void583}584 585define void @extract_v32half_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {586; CHECK-LABEL: extract_v32half_halves:587; CHECK:       // %bb.0: // %entry588; CHECK-NEXT:    ldr z0, [x0]589; CHECK-NEXT:    ptrue p0.h, vl16590; CHECK-NEXT:    movprfx z1, z0591; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #32592; CHECK-NEXT:    st1h { z1.h }, p0, [x1]593; CHECK-NEXT:    st1h { z0.h }, p0, [x2]594; CHECK-NEXT:    ret595entry:596  %b = load <32 x half>, ptr %in597  %hi = shufflevector <32 x half> %b, <32 x half> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>598  store <16 x half> %hi, ptr %out599  %lo = shufflevector <32 x half> %b, <32 x half> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>600  store <16 x half> %lo, ptr %out2601  ret void602}603 604define void @extract_subvector_v64f16(ptr %a, ptr %b) vscale_range(8,0) #0 {605; CHECK-LABEL: extract_subvector_v64f16:606; CHECK:       // %bb.0:607; CHECK-NEXT:    ptrue p0.h, vl32608; CHECK-NEXT:    mov x8, #32 // =0x20609; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]610; CHECK-NEXT:    st1h { z0.h }, p0, [x1]611; CHECK-NEXT:    ret612  %op = load <64 x half>, ptr %a613  %ret = call <32 x half> @llvm.vector.extract.v32f16.v64f16(<64 x half> %op, i64 32)614  store <32 x half> %ret, ptr %b615  ret void616}617 618define void @extract_subvector_v128f16(ptr %a, ptr %b) vscale_range(16,0) #0 {619; CHECK-LABEL: extract_subvector_v128f16:620; CHECK:       // %bb.0:621; CHECK-NEXT:    ptrue p0.h, vl64622; CHECK-NEXT:    mov x8, #64 // =0x40623; CHECK-NEXT:    ld1h { z0.h }, p0/z, [x0, x8, lsl #1]624; CHECK-NEXT:    st1h { z0.h }, p0, [x1]625; CHECK-NEXT:    ret626  %op = load <128 x half>, ptr %a627  %ret = call <64 x half> @llvm.vector.extract.v64f16.v128f16(<128 x half> %op, i64 64)628  store <64 x half> %ret, ptr %b629  ret void630}631 632; f32633 634; Don't use SVE for 64-bit vectors.635define <1 x float> @extract_subvector_v2f32(<2 x float> %op) vscale_range(2,0) #0 {636; CHECK-LABEL: extract_subvector_v2f32:637; CHECK:       // %bb.0:638; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0639; CHECK-NEXT:    dup v0.2s, v0.s[1]640; CHECK-NEXT:    ret641  %ret = call <1 x float> @llvm.vector.extract.v1f32.v2f32(<2 x float> %op, i64 1)642  ret <1 x float> %ret643}644 645; Don't use SVE for 128-bit vectors.646define <2 x float> @extract_subvector_v4f32(<4 x float> %op) vscale_range(2,0) #0 {647; CHECK-LABEL: extract_subvector_v4f32:648; CHECK:       // %bb.0:649; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8650; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0651; CHECK-NEXT:    ret652  %ret = call <2 x float> @llvm.vector.extract.v2f32.v4f32(<4 x float> %op, i64 2)653  ret <2 x float> %ret654}655 656define void @extract_subvector_v8f32(ptr %a, ptr %b) vscale_range(2,0) #0 {657; CHECK-LABEL: extract_subvector_v8f32:658; CHECK:       // %bb.0:659; CHECK-NEXT:    ldr q0, [x0, #16]660; CHECK-NEXT:    str q0, [x1]661; CHECK-NEXT:    ret662  %op = load <8 x float>, ptr %a663  %ret = call <4 x float> @llvm.vector.extract.v4f32.v8f32(<8 x float> %op, i64 4)664  store <4 x float> %ret, ptr %b665  ret void666}667 668define void @extract_v8float_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {669; CHECK-LABEL: extract_v8float_halves:670; CHECK:       // %bb.0: // %entry671; CHECK-NEXT:    ldr z0, [x0]672; CHECK-NEXT:    movprfx z1, z0673; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #16674; CHECK-NEXT:    str q1, [x1]675; CHECK-NEXT:    str q0, [x2]676; CHECK-NEXT:    ret677entry:678  %b = load <8 x float>, ptr %in679  %hi = shufflevector <8 x float> %b, <8 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>680  store <4 x float> %hi, ptr %out681  %lo = shufflevector <8 x float> %b, <8 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>682  store <4 x float> %lo, ptr %out2683  ret void684}685 686define void @extract_subvector_v16f32(ptr %a, ptr %b) #0 {687; CHECK-LABEL: extract_subvector_v16f32:688; CHECK:       // %bb.0:689; CHECK-NEXT:    ptrue p0.s, vl8690; CHECK-NEXT:    mov x8, #8 // =0x8691; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]692; CHECK-NEXT:    st1w { z0.s }, p0, [x1]693; CHECK-NEXT:    ret694  %op = load <16 x float>, ptr %a695  %ret = call <8 x float> @llvm.vector.extract.v8f32.v16f32(<16 x float> %op, i64 8)696  store <8 x float> %ret, ptr %b697  ret void698}699 700define void @extract_v16float_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {701; CHECK-LABEL: extract_v16float_halves:702; CHECK:       // %bb.0: // %entry703; CHECK-NEXT:    ldr z0, [x0]704; CHECK-NEXT:    ptrue p0.s, vl8705; CHECK-NEXT:    movprfx z1, z0706; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #32707; CHECK-NEXT:    st1w { z1.s }, p0, [x1]708; CHECK-NEXT:    st1w { z0.s }, p0, [x2]709; CHECK-NEXT:    ret710entry:711  %b = load <16 x float>, ptr %in712  %hi = shufflevector <16 x float> %b, <16 x float> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>713  store <8 x float> %hi, ptr %out714  %lo = shufflevector <16 x float> %b, <16 x float> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>715  store <8 x float> %lo, ptr %out2716  ret void717}718 719define void @extract_subvector_v32f32(ptr %a, ptr %b) vscale_range(8,0) #0 {720; CHECK-LABEL: extract_subvector_v32f32:721; CHECK:       // %bb.0:722; CHECK-NEXT:    ptrue p0.s, vl16723; CHECK-NEXT:    mov x8, #16 // =0x10724; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]725; CHECK-NEXT:    st1w { z0.s }, p0, [x1]726; CHECK-NEXT:    ret727  %op = load <32 x float>, ptr %a728  %ret = call <16 x float> @llvm.vector.extract.v16f32.v32f32(<32 x float> %op, i64 16)729  store <16 x float> %ret, ptr %b730  ret void731}732 733define void @extract_subvector_v64f32(ptr %a, ptr %b) vscale_range(16,0) #0 {734; CHECK-LABEL: extract_subvector_v64f32:735; CHECK:       // %bb.0:736; CHECK-NEXT:    ptrue p0.s, vl32737; CHECK-NEXT:    mov x8, #32 // =0x20738; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x0, x8, lsl #2]739; CHECK-NEXT:    st1w { z0.s }, p0, [x1]740; CHECK-NEXT:    ret741  %op = load <64 x float>, ptr %a742  %ret = call <32 x float> @llvm.vector.extract.v32f32.v64f32(<64 x float> %op, i64 32)743  store <32 x float> %ret, ptr %b744  ret void745}746 747; f64748 749; Don't use SVE for 128-bit vectors.750define <1 x double> @extract_subvector_v2f64(<2 x double> %op) vscale_range(2,0) #0 {751; CHECK-LABEL: extract_subvector_v2f64:752; CHECK:       // %bb.0:753; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8754; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0755; CHECK-NEXT:    ret756  %ret = call <1 x double> @llvm.vector.extract.v1f64.v2f64(<2 x double> %op, i64 1)757  ret <1 x double> %ret758}759 760define void @extract_subvector_v4f64(ptr %a, ptr %b) vscale_range(2,0) #0 {761; CHECK-LABEL: extract_subvector_v4f64:762; CHECK:       // %bb.0:763; CHECK-NEXT:    ldr q0, [x0, #16]764; CHECK-NEXT:    str q0, [x1]765; CHECK-NEXT:    ret766  %op = load <4 x double>, ptr %a767  %ret = call <2 x double> @llvm.vector.extract.v2f64.v4f64(<4 x double> %op, i64 2)768  store <2 x double> %ret, ptr %b769  ret void770}771 772define void @extract_v4double_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {773; CHECK-LABEL: extract_v4double_halves:774; CHECK:       // %bb.0: // %entry775; CHECK-NEXT:    ldr z0, [x0]776; CHECK-NEXT:    movprfx z1, z0777; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #16778; CHECK-NEXT:    str q1, [x1]779; CHECK-NEXT:    str q0, [x2]780; CHECK-NEXT:    ret781entry:782  %b = load <4 x double>, ptr %in783  %hi = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 2, i32 3>784  store <2 x double> %hi, ptr %out785  %lo = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 1>786  store <2 x double> %lo, ptr %out2787  ret void788}789 790define void @extract_subvector_v8f64(ptr %a, ptr %b) #0 {791; CHECK-LABEL: extract_subvector_v8f64:792; CHECK:       // %bb.0:793; CHECK-NEXT:    ptrue p0.d, vl4794; CHECK-NEXT:    mov x8, #4 // =0x4795; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]796; CHECK-NEXT:    st1d { z0.d }, p0, [x1]797; CHECK-NEXT:    ret798  %op = load <8 x double>, ptr %a799  %ret = call <4 x double> @llvm.vector.extract.v4f64.v8f64(<8 x double> %op, i64 4)800  store <4 x double> %ret, ptr %b801  ret void802}803 804define void @extract_v8double_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {805; CHECK-LABEL: extract_v8double_halves:806; CHECK:       // %bb.0: // %entry807; CHECK-NEXT:    ldr z0, [x0]808; CHECK-NEXT:    ptrue p0.d, vl4809; CHECK-NEXT:    movprfx z1, z0810; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #32811; CHECK-NEXT:    st1d { z1.d }, p0, [x1]812; CHECK-NEXT:    st1d { z0.d }, p0, [x2]813; CHECK-NEXT:    ret814entry:815  %b = load <8 x double>, ptr %in816  %hi = shufflevector <8 x double> %b, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>817  store <4 x double> %hi, ptr %out818  %lo = shufflevector <8 x double> %b, <8 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>819  store <4 x double> %lo, ptr %out2820  ret void821}822 823define void @extract_subvector_v16f64(ptr %a, ptr %b) vscale_range(8,0) #0 {824; CHECK-LABEL: extract_subvector_v16f64:825; CHECK:       // %bb.0:826; CHECK-NEXT:    ptrue p0.d, vl8827; CHECK-NEXT:    mov x8, #8 // =0x8828; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]829; CHECK-NEXT:    st1d { z0.d }, p0, [x1]830; CHECK-NEXT:    ret831  %op = load <16 x double>, ptr %a832  %ret = call <8 x double> @llvm.vector.extract.v8f64.v16f64(<16 x double> %op, i64 8)833  store <8 x double> %ret, ptr %b834  ret void835}836 837define void @extract_subvector_v32f64(ptr %a, ptr %b) vscale_range(16,0) #0 {838; CHECK-LABEL: extract_subvector_v32f64:839; CHECK:       // %bb.0:840; CHECK-NEXT:    ptrue p0.d, vl16841; CHECK-NEXT:    mov x8, #16 // =0x10842; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x0, x8, lsl #3]843; CHECK-NEXT:    st1d { z0.d }, p0, [x1]844; CHECK-NEXT:    ret845  %op = load <32 x double>, ptr %a846  %ret = call <16 x double> @llvm.vector.extract.v16f64.v32f64(<32 x double> %op, i64 16)847  store <16 x double> %ret, ptr %b848  ret void849}850 851; bf16852 853define void @extract_v8bfloat_halves(ptr %in, ptr %out, ptr %out2) #0 {854; CHECK-LABEL: extract_v8bfloat_halves:855; CHECK:       // %bb.0: // %entry856; CHECK-NEXT:    ldr q0, [x0]857; CHECK-NEXT:    ext v1.16b, v0.16b, v0.16b, #8858; CHECK-NEXT:    str d1, [x1]859; CHECK-NEXT:    str d0, [x2]860; CHECK-NEXT:    ret861entry:862  %b = load <8 x bfloat>, ptr %in863  %hi = shufflevector <8 x bfloat> %b, <8 x bfloat> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>864  store <4 x bfloat> %hi, ptr %out865  %lo = shufflevector <8 x bfloat> %b, <8 x bfloat> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>866  store <4 x bfloat> %lo, ptr %out2867  ret void868}869 870define void @extract_v16bfloat_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(2,2) {871; CHECK-LABEL: extract_v16bfloat_halves:872; CHECK:       // %bb.0: // %entry873; CHECK-NEXT:    ldp q1, q0, [x0]874; CHECK-NEXT:    str q0, [x1]875; CHECK-NEXT:    str q1, [x2]876; CHECK-NEXT:    ret877entry:878  %b = load <16 x bfloat>, ptr %in879  %hi = shufflevector <16 x bfloat> %b, <16 x bfloat> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>880  store <8 x bfloat> %hi, ptr %out881  %lo = shufflevector <16 x bfloat> %b, <16 x bfloat> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>882  store <8 x bfloat> %lo, ptr %out2883  ret void884}885 886define void @extract_v32bfloat_halves(ptr %in, ptr %out, ptr %out2) #0 vscale_range(4,4) {887; CHECK-LABEL: extract_v32bfloat_halves:888; CHECK:       // %bb.0: // %entry889; CHECK-NEXT:    ldp q0, q1, [x0, #32]890; CHECK-NEXT:    ldp q3, q2, [x0]891; CHECK-NEXT:    stp q0, q1, [x1]892; CHECK-NEXT:    stp q3, q2, [x2]893; CHECK-NEXT:    ret894entry:895  %b = load <32 x bfloat>, ptr %in896  %hi = shufflevector <32 x bfloat> %b, <32 x bfloat> poison, <16 x i32> <i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>897  store <16 x bfloat> %hi, ptr %out898  %lo = shufflevector <32 x bfloat> %b, <32 x bfloat> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>899  store <16 x bfloat> %lo, ptr %out2900  ret void901}902 903; Test for infinite loop due to fold:904; extract_subvector(insert_subvector(x,y,c1),c2)--> extract_subvector(y,c2-c1)905define void @extract_subvector_legalization_v8i32() vscale_range(2,2) #0 {906; CHECK-LABEL: extract_subvector_legalization_v8i32:907; CHECK:       // %bb.0: // %entry908; CHECK-NEXT:    adrp x8, .LCPI59_0909; CHECK-NEXT:    add x8, x8, :lo12:.LCPI59_0910; CHECK-NEXT:    ptrue p1.d911; CHECK-NEXT:    ldr z0, [x8]912; CHECK-NEXT:    movprfx z1, z0913; CHECK-NEXT:    ext z1.b, z1.b, z0.b, #16914; CHECK-NEXT:    cmeq v0.4s, v0.4s, #0915; CHECK-NEXT:    cmeq v1.4s, v1.4s, #0916; CHECK-NEXT:    sunpklo z0.d, z0.s917; CHECK-NEXT:    sunpklo z1.d, z1.s918; CHECK-NEXT:    cmpne p0.d, p1/z, z1.d, #0919; CHECK-NEXT:    cmpne p1.d, p1/z, z0.d, #0920; CHECK-NEXT:  .LBB59_1: // %body921; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1922; CHECK-NEXT:    st1d { z0.d }, p1, [x8]923; CHECK-NEXT:    st1d { z0.d }, p0, [x8]924; CHECK-NEXT:    b .LBB59_1925entry:926  %splat = shufflevector <8 x i32> poison, <8 x i32> poison, <8 x i32> zeroinitializer927  br label %body928body:929  %0 = icmp eq <8 x i32> zeroinitializer, %splat930  tail call void @llvm.masked.store.v8f64.p0(<8 x double> poison, ptr poison, i32 8, <8 x i1> %0)931  br label %body932}933declare void @llvm.masked.store.v8f64.p0(<8 x double>, ptr nocapture, i32 immarg, <8 x i1>)934 935declare <4 x i8> @llvm.vector.extract.v4i8.v8i8(<8 x i8>, i64)936declare <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8>, i64)937declare <16 x i8> @llvm.vector.extract.v16i8.v32i8(<32 x i8>, i64)938declare <32 x i8> @llvm.vector.extract.v32i8.v64i8(<64 x i8>, i64)939declare <64 x i8> @llvm.vector.extract.v64i8.v128i8(<128 x i8>, i64)940declare <128 x i8> @llvm.vector.extract.v128i8.v256i8(<256 x i8>, i64)941 942declare <2 x i16> @llvm.vector.extract.v2i16.v4i16(<4 x i16>, i64)943declare <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16>, i64)944declare <8 x i16> @llvm.vector.extract.v8i16.v16i16(<16 x i16>, i64)945declare <16 x i16> @llvm.vector.extract.v16i16.v32i16(<32 x i16>, i64)946declare <32 x i16> @llvm.vector.extract.v32i16.v64i16(<64 x i16>, i64)947declare <64 x i16> @llvm.vector.extract.v64i16.v128i16(<128 x i16>, i64)948 949declare <1 x i32> @llvm.vector.extract.v1i32.v2i32(<2 x i32>, i64)950declare <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32>, i64)951declare <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32>, i64)952declare <8 x i32> @llvm.vector.extract.v8i32.v16i32(<16 x i32>, i64)953declare <16 x i32> @llvm.vector.extract.v16i32.v32i32(<32 x i32>, i64)954declare <32 x i32> @llvm.vector.extract.v32i32.v64i32(<64 x i32>, i64)955 956declare <1 x i64> @llvm.vector.extract.v1i64.v2i64(<2 x i64>, i64)957declare <2 x i64> @llvm.vector.extract.v2i64.v4i64(<4 x i64>, i64)958declare <4 x i64> @llvm.vector.extract.v4i64.v8i64(<8 x i64>, i64)959declare <8 x i64> @llvm.vector.extract.v8i64.v16i64(<16 x i64>, i64)960declare <16 x i64> @llvm.vector.extract.v16i64.v32i64(<32 x i64>, i64)961 962declare <2 x half> @llvm.vector.extract.v2f16.v4f16(<4 x half>, i64)963declare <4 x half> @llvm.vector.extract.v4f16.v8f16(<8 x half>, i64)964declare <8 x half> @llvm.vector.extract.v8f16.v16f16(<16 x half>, i64)965declare <16 x half> @llvm.vector.extract.v16f16.v32f16(<32 x half>, i64)966declare <32 x half> @llvm.vector.extract.v32f16.v64f16(<64 x half>, i64)967declare <64 x half> @llvm.vector.extract.v64f16.v128f16(<128 x half>, i64)968 969declare <1 x float> @llvm.vector.extract.v1f32.v2f32(<2 x float>, i64)970declare <2 x float> @llvm.vector.extract.v2f32.v4f32(<4 x float>, i64)971declare <4 x float> @llvm.vector.extract.v4f32.v8f32(<8 x float>, i64)972declare <8 x float> @llvm.vector.extract.v8f32.v16f32(<16 x float>, i64)973declare <16 x float> @llvm.vector.extract.v16f32.v32f32(<32 x float>, i64)974declare <32 x float> @llvm.vector.extract.v32f32.v64f32(<64 x float>, i64)975 976declare <1 x double> @llvm.vector.extract.v1f64.v2f64(<2 x double>, i64)977declare <2 x double> @llvm.vector.extract.v2f64.v4f64(<4 x double>, i64)978declare <4 x double> @llvm.vector.extract.v4f64.v8f64(<8 x double>, i64)979declare <8 x double> @llvm.vector.extract.v8f64.v16f64(<16 x double>, i64)980declare <16 x double> @llvm.vector.extract.v16f64.v32f64(<32 x double>, i64)981 982attributes #0 = { "target-features"="+sve" }983