diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index f2cacba0ff773..cf5f8af50240e 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -9616,12 +9616,15 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op, if (OrigIdx == 0) return Op; - // If the subvector vector is a fixed-length type, we cannot use subregister - // manipulation to simplify the codegen; we don't know which register of a - // LMUL group contains the specific subvector as we only know the minimum - // register size. Therefore we must slide the vector group down the full - // amount. - if (SubVecVT.isFixedLengthVector()) { + const unsigned MinVLen = Subtarget.getRealMinVLen(); + const unsigned MaxVLen = Subtarget.getRealMaxVLen(); + + // If the subvector vector is a fixed-length type and we don't know VLEN + // exactly, we cannot use subregister manipulation to simplify the codegen; we + // don't know which register of a LMUL group contains the specific subvector + // as we only know the minimum register size. Therefore we must slide the + // vector group down the full amount. + if (SubVecVT.isFixedLengthVector() && MinVLen != MaxVLen) { MVT ContainerVT = VecVT; if (VecVT.isFixedLengthVector()) { ContainerVT = getContainerForFixedLengthVector(VecVT); @@ -9653,19 +9656,47 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op, return DAG.getBitcast(Op.getValueType(), Slidedown); } + if (VecVT.isFixedLengthVector()) { + VecVT = getContainerForFixedLengthVector(VecVT); + Vec = convertToScalableVector(VecVT, Vec, DAG, Subtarget); + } + + MVT ContainerSubVecVT = SubVecVT; + if (SubVecVT.isFixedLengthVector()) + ContainerSubVecVT = getContainerForFixedLengthVector(SubVecVT); + unsigned SubRegIdx, RemIdx; - std::tie(SubRegIdx, RemIdx) = - RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs( - VecVT, SubVecVT, OrigIdx, TRI); + // extract_subvector scales the index by vscale is the subvector is scalable, + // and decomposeSubvectorInsertExtractToSubRegs takes this into account. So if + // we have a fixed length subvector, we need to adjust the index by 1/vscale. + if (SubVecVT.isFixedLengthVector()) { + assert(MinVLen == MaxVLen); + unsigned Vscale = MinVLen / RISCV::RVVBitsPerBlock; + std::tie(SubRegIdx, RemIdx) = + RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs( + VecVT, ContainerSubVecVT, OrigIdx / Vscale, TRI); + RemIdx = (RemIdx * Vscale) + (OrigIdx % Vscale); + } else { + std::tie(SubRegIdx, RemIdx) = + RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs( + VecVT, ContainerSubVecVT, OrigIdx, TRI); + } // If the Idx has been completely eliminated then this is a subvector extract // which naturally aligns to a vector register. These can easily be handled // using subregister manipulation. - if (RemIdx == 0) + if (RemIdx == 0) { + if (SubVecVT.isFixedLengthVector()) { + Vec = DAG.getTargetExtractSubreg(SubRegIdx, DL, ContainerSubVecVT, Vec); + return convertFromScalableVector(SubVecVT, Vec, DAG, Subtarget); + } return Op; + } - // Else SubVecVT is a fractional LMUL and may need to be slid down. - assert(RISCVVType::decodeVLMUL(getLMUL(SubVecVT)).second); + // Else SubVecVT is a fractional LMUL and may need to be slid down: if + // SubVecVT was > M1 then the index would need to be a multiple of VLMAX, and + // so would divide exactly. + assert(RISCVVType::decodeVLMUL(getLMUL(ContainerSubVecVT)).second); // If the vector type is an LMUL-group type, extract a subvector equal to the // nearest full vector register type. @@ -9680,10 +9711,17 @@ SDValue RISCVTargetLowering::lowerEXTRACT_SUBVECTOR(SDValue Op, // Slide this vector register down by the desired number of elements in order // to place the desired subvector starting at element 0. - SDValue SlidedownAmt = - DAG.getVScale(DL, XLenVT, APInt(XLenVT.getSizeInBits(), RemIdx)); + SDValue SlidedownAmt; + if (SubVecVT.isFixedLengthVector()) + SlidedownAmt = DAG.getConstant(RemIdx, DL, Subtarget.getXLenVT()); + else + SlidedownAmt = + DAG.getVScale(DL, XLenVT, APInt(XLenVT.getSizeInBits(), RemIdx)); auto [Mask, VL] = getDefaultScalableVLOps(InterSubVT, DL, DAG, Subtarget); + if (SubVecVT.isFixedLengthVector()) + VL = getVLOp(SubVecVT.getVectorNumElements(), InterSubVT, DL, DAG, + Subtarget); SDValue Slidedown = getVSlidedown(DAG, Subtarget, DL, InterSubVT, DAG.getUNDEF(InterSubVT), Vec, SlidedownAmt, Mask, VL); diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll index 8b51a38830420..7d29b194f041e 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-extract-subvector.ll @@ -76,10 +76,8 @@ define void @extract_v1i32_v8i32_4(ptr %x, ptr %y) { ; CHECK-KNOWNVLEN128-LABEL: extract_v1i32_v8i32_4: ; CHECK-KNOWNVLEN128: # %bb.0: ; CHECK-KNOWNVLEN128-NEXT: vl2re32.v v8, (a0) -; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 1, e32, m2, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 4 ; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 1, e32, mf2, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vse32.v v8, (a1) +; CHECK-KNOWNVLEN128-NEXT: vse32.v v9, (a1) ; CHECK-KNOWNVLEN128-NEXT: ret %a = load <8 x i32>, ptr %x %c = call <1 x i32> @llvm.vector.extract.v1i32.v8i32(<8 x i32> %a, i64 4) @@ -101,8 +99,8 @@ define void @extract_v1i32_v8i32_5(ptr %x, ptr %y) { ; CHECK-KNOWNVLEN128-LABEL: extract_v1i32_v8i32_5: ; CHECK-KNOWNVLEN128: # %bb.0: ; CHECK-KNOWNVLEN128-NEXT: vl2re32.v v8, (a0) -; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 1, e32, m2, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 5 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 1, e32, m1, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v9, 1 ; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 1, e32, mf2, ta, ma ; CHECK-KNOWNVLEN128-NEXT: vse32.v v8, (a1) ; CHECK-KNOWNVLEN128-NEXT: ret @@ -172,10 +170,8 @@ define void @extract_v2i32_v8i32_4(ptr %x, ptr %y) { ; CHECK-KNOWNVLEN128-LABEL: extract_v2i32_v8i32_4: ; CHECK-KNOWNVLEN128: # %bb.0: ; CHECK-KNOWNVLEN128-NEXT: vl2re32.v v8, (a0) -; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, m2, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 4 ; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vse32.v v8, (a1) +; CHECK-KNOWNVLEN128-NEXT: vse32.v v9, (a1) ; CHECK-KNOWNVLEN128-NEXT: ret %a = load <8 x i32>, ptr %x %c = call <2 x i32> @llvm.vector.extract.v2i32.v8i32(<8 x i32> %a, i64 4) @@ -197,8 +193,8 @@ define void @extract_v2i32_v8i32_6(ptr %x, ptr %y) { ; CHECK-KNOWNVLEN128-LABEL: extract_v2i32_v8i32_6: ; CHECK-KNOWNVLEN128: # %bb.0: ; CHECK-KNOWNVLEN128-NEXT: vl2re32.v v8, (a0) -; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, m2, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 6 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, m1, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v9, 2 ; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, mf2, ta, ma ; CHECK-KNOWNVLEN128-NEXT: vse32.v v8, (a1) ; CHECK-KNOWNVLEN128-NEXT: ret @@ -234,39 +230,59 @@ define void @extract_v2i32_nxv16i32_2( %x, ptr %y) { } define void @extract_v2i32_nxv16i32_4( %x, ptr %y) { -; CHECK-LABEL: extract_v2i32_nxv16i32_4: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 4 -; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-NEXT: vse32.v v8, (a0) -; CHECK-NEXT: ret +; CHECK-V-LABEL: extract_v2i32_nxv16i32_4: +; CHECK-V: # %bb.0: +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, ta, ma +; CHECK-V-NEXT: vslidedown.vi v8, v8, 4 +; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vse32.v v8, (a0) +; CHECK-V-NEXT: ret +; +; CHECK-KNOWNVLEN128-LABEL: extract_v2i32_nxv16i32_4: +; CHECK-KNOWNVLEN128: # %bb.0: +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vse32.v v9, (a0) +; CHECK-KNOWNVLEN128-NEXT: ret %c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32( %x, i64 4) store <2 x i32> %c, ptr %y ret void } define void @extract_v2i32_nxv16i32_6( %x, ptr %y) { -; CHECK-LABEL: extract_v2i32_nxv16i32_6: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 6 -; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-NEXT: vse32.v v8, (a0) -; CHECK-NEXT: ret +; CHECK-V-LABEL: extract_v2i32_nxv16i32_6: +; CHECK-V: # %bb.0: +; CHECK-V-NEXT: vsetivli zero, 2, e32, m2, ta, ma +; CHECK-V-NEXT: vslidedown.vi v8, v8, 6 +; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vse32.v v8, (a0) +; CHECK-V-NEXT: ret +; +; CHECK-KNOWNVLEN128-LABEL: extract_v2i32_nxv16i32_6: +; CHECK-KNOWNVLEN128: # %bb.0: +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, m1, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v9, 2 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vse32.v v8, (a0) +; CHECK-KNOWNVLEN128-NEXT: ret %c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32( %x, i64 6) store <2 x i32> %c, ptr %y ret void } define void @extract_v2i32_nxv16i32_8( %x, ptr %y) { -; CHECK-LABEL: extract_v2i32_nxv16i32_8: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 2, e32, m4, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 8 -; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma -; CHECK-NEXT: vse32.v v8, (a0) -; CHECK-NEXT: ret +; CHECK-V-LABEL: extract_v2i32_nxv16i32_8: +; CHECK-V: # %bb.0: +; CHECK-V-NEXT: vsetivli zero, 2, e32, m4, ta, ma +; CHECK-V-NEXT: vslidedown.vi v8, v8, 8 +; CHECK-V-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-V-NEXT: vse32.v v8, (a0) +; CHECK-V-NEXT: ret +; +; CHECK-KNOWNVLEN128-LABEL: extract_v2i32_nxv16i32_8: +; CHECK-KNOWNVLEN128: # %bb.0: +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vse32.v v10, (a0) +; CHECK-KNOWNVLEN128-NEXT: ret %c = call <2 x i32> @llvm.vector.extract.v2i32.nxv16i32( %x, i64 8) store <2 x i32> %c, ptr %y ret void @@ -333,9 +349,7 @@ define void @extract_v8i32_nxv16i32_8( %x, ptr %y) { ; ; CHECK-KNOWNVLEN128-LABEL: extract_v8i32_nxv16i32_8: ; CHECK-KNOWNVLEN128: # %bb.0: -; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e32, m4, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v8, 8 -; CHECK-KNOWNVLEN128-NEXT: vs2r.v v8, (a0) +; CHECK-KNOWNVLEN128-NEXT: vs2r.v v10, (a0) ; CHECK-KNOWNVLEN128-NEXT: ret %c = call <8 x i32> @llvm.vector.extract.v8i32.nxv16i32( %x, i64 8) store <8 x i32> %c, ptr %y @@ -611,9 +625,8 @@ define void @extract_v2i1_v64i1_42(ptr %x, ptr %y) { ; CHECK-KNOWNVLEN128-NEXT: vlm.v v0, (a0) ; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0 ; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0 -; CHECK-KNOWNVLEN128-NEXT: li a0, 42 -; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, m4, ta, ma -; CHECK-KNOWNVLEN128-NEXT: vslidedown.vx v8, v8, a0 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v10, 10 ; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf8, ta, ma ; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v0, v8, 0 ; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0 @@ -741,51 +754,91 @@ define void @extract_v2i1_nxv64i1_2( %x, ptr %y) { } define void @extract_v2i1_nxv64i1_42( %x, ptr %y) { -; CHECK-LABEL: extract_v2i1_nxv64i1_42: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetvli a1, zero, e8, m8, ta, ma -; CHECK-NEXT: vmv.v.i v8, 0 -; CHECK-NEXT: vmerge.vim v8, v8, 1, v0 -; CHECK-NEXT: li a1, 42 -; CHECK-NEXT: vsetivli zero, 2, e8, m4, ta, ma -; CHECK-NEXT: vslidedown.vx v8, v8, a1 -; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma -; CHECK-NEXT: vmsne.vi v0, v8, 0 -; CHECK-NEXT: vmv.v.i v8, 0 -; CHECK-NEXT: vmerge.vim v8, v8, 1, v0 -; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma -; CHECK-NEXT: vmv.v.i v9, 0 -; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma -; CHECK-NEXT: vmv.v.v v9, v8 -; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma -; CHECK-NEXT: vmsne.vi v8, v9, 0 -; CHECK-NEXT: vsm.v v8, (a0) -; CHECK-NEXT: ret +; CHECK-V-LABEL: extract_v2i1_nxv64i1_42: +; CHECK-V: # %bb.0: +; CHECK-V-NEXT: vsetvli a1, zero, e8, m8, ta, ma +; CHECK-V-NEXT: vmv.v.i v8, 0 +; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-V-NEXT: li a1, 42 +; CHECK-V-NEXT: vsetivli zero, 2, e8, m4, ta, ma +; CHECK-V-NEXT: vslidedown.vx v8, v8, a1 +; CHECK-V-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-V-NEXT: vmsne.vi v0, v8, 0 +; CHECK-V-NEXT: vmv.v.i v8, 0 +; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-V-NEXT: vmv.v.i v9, 0 +; CHECK-V-NEXT: vsetivli zero, 2, e8, mf2, tu, ma +; CHECK-V-NEXT: vmv.v.v v9, v8 +; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-V-NEXT: vmsne.vi v8, v9, 0 +; CHECK-V-NEXT: vsm.v v8, (a0) +; CHECK-V-NEXT: ret +; +; CHECK-KNOWNVLEN128-LABEL: extract_v2i1_nxv64i1_42: +; CHECK-KNOWNVLEN128: # %bb.0: +; CHECK-KNOWNVLEN128-NEXT: vsetvli a1, zero, e8, m8, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0 +; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v10, 10 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v0, v8, 0 +; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0 +; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v9, 0 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf2, tu, ma +; CHECK-KNOWNVLEN128-NEXT: vmv.v.v v9, v8 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v8, v9, 0 +; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a0) +; CHECK-KNOWNVLEN128-NEXT: ret %c = call <2 x i1> @llvm.vector.extract.v2i1.nxv64i1( %x, i64 42) store <2 x i1> %c, ptr %y ret void } define void @extract_v2i1_nxv32i1_26( %x, ptr %y) { -; CHECK-LABEL: extract_v2i1_nxv32i1_26: -; CHECK: # %bb.0: -; CHECK-NEXT: vsetvli a1, zero, e8, m4, ta, ma -; CHECK-NEXT: vmv.v.i v8, 0 -; CHECK-NEXT: vmerge.vim v8, v8, 1, v0 -; CHECK-NEXT: vsetivli zero, 2, e8, m2, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 26 -; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma -; CHECK-NEXT: vmsne.vi v0, v8, 0 -; CHECK-NEXT: vmv.v.i v8, 0 -; CHECK-NEXT: vmerge.vim v8, v8, 1, v0 -; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma -; CHECK-NEXT: vmv.v.i v9, 0 -; CHECK-NEXT: vsetivli zero, 2, e8, mf2, tu, ma -; CHECK-NEXT: vmv.v.v v9, v8 -; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma -; CHECK-NEXT: vmsne.vi v8, v9, 0 -; CHECK-NEXT: vsm.v v8, (a0) -; CHECK-NEXT: ret +; CHECK-V-LABEL: extract_v2i1_nxv32i1_26: +; CHECK-V: # %bb.0: +; CHECK-V-NEXT: vsetvli a1, zero, e8, m4, ta, ma +; CHECK-V-NEXT: vmv.v.i v8, 0 +; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-V-NEXT: vsetivli zero, 2, e8, m2, ta, ma +; CHECK-V-NEXT: vslidedown.vi v8, v8, 26 +; CHECK-V-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-V-NEXT: vmsne.vi v0, v8, 0 +; CHECK-V-NEXT: vmv.v.i v8, 0 +; CHECK-V-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-V-NEXT: vmv.v.i v9, 0 +; CHECK-V-NEXT: vsetivli zero, 2, e8, mf2, tu, ma +; CHECK-V-NEXT: vmv.v.v v9, v8 +; CHECK-V-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-V-NEXT: vmsne.vi v8, v9, 0 +; CHECK-V-NEXT: vsm.v v8, (a0) +; CHECK-V-NEXT: ret +; +; CHECK-KNOWNVLEN128-LABEL: extract_v2i1_nxv32i1_26: +; CHECK-KNOWNVLEN128: # %bb.0: +; CHECK-KNOWNVLEN128-NEXT: vsetvli a1, zero, e8, m4, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0 +; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vslidedown.vi v8, v9, 10 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v0, v8, 0 +; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v8, 0 +; CHECK-KNOWNVLEN128-NEXT: vmerge.vim v8, v8, 1, v0 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmv.v.i v9, 0 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 2, e8, mf2, tu, ma +; CHECK-KNOWNVLEN128-NEXT: vmv.v.v v9, v8 +; CHECK-KNOWNVLEN128-NEXT: vsetivli zero, 8, e8, mf2, ta, ma +; CHECK-KNOWNVLEN128-NEXT: vmsne.vi v8, v9, 0 +; CHECK-KNOWNVLEN128-NEXT: vsm.v v8, (a0) +; CHECK-KNOWNVLEN128-NEXT: ret %c = call <2 x i1> @llvm.vector.extract.v2i1.nxv32i1( %x, i64 26) store <2 x i1> %c, ptr %y ret void