diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 2b8e5aeeb8640..81f0ca38022f3 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -8664,6 +8664,14 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op, Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget); } + if (OrigIdx == 0 && Vec.isUndef() && VecVT.isFixedLengthVector()) { + SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT, + DAG.getUNDEF(ContainerVT), SubVec, + DAG.getConstant(0, DL, XLenVT)); + SubVec = convertFromScalableVector(VecVT, SubVec, DAG, Subtarget); + return DAG.getBitcast(Op.getValueType(), SubVec); + } + // Shrink down Vec so we're performing the slideup on a smaller LMUL. unsigned LastIdx = OrigIdx + SubVecVT.getVectorNumElements() - 1; MVT OrigContainerVT = ContainerVT; @@ -8678,10 +8686,6 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op, SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT, DAG.getUNDEF(ContainerVT), SubVec, DAG.getConstant(0, DL, XLenVT)); - if (OrigIdx == 0 && Vec.isUndef() && VecVT.isFixedLengthVector()) { - SubVec = convertFromScalableVector(VecVT, SubVec, DAG, Subtarget); - return DAG.getBitcast(Op.getValueType(), SubVec); - } SDValue Mask = getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).first; // Set the vector length to only the number of elements we care about. Note diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll index 6a9212ed309a8..15669f03e893d 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll @@ -636,3 +636,21 @@ declare @llvm.vector.insert.v2i16.nxv2i16(, declare @llvm.vector.insert.v2i32.nxv8i32(, <2 x i32>, i64) declare @llvm.vector.insert.v4i32.nxv8i32(, <4 x i32>, i64) declare @llvm.vector.insert.v8i32.nxv8i32(, <8 x i32>, i64) + +; We emit insert_subvectors of fixed vectors at index 0 into undefs as a +; copy_to_regclass or insert_subreg, depending on the register classes of the +; vector types. Make sure that we use the correct type and not the shrunken +; LMUL=1 type, otherwise we will end up with an invalid extract_subvector when +; converting it from scalable->fixed, e.g. we get this for VLEN=128: +; +; t14: nxv2i32 = insert_subvector undef:nxv2i32, t4, Constant:i64<0> +; t15: v8i32 = extract_subvector t14, Constant:i64<0> +declare <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32>, i64) +define <4 x i32> @insert_extract_v8i32_v2i32_0(<2 x i32> %v) { +; CHECK-LABEL: insert_extract_v8i32_v2i32_0: +; CHECK: # %bb.0: +; CHECK-NEXT: ret + %1 = call <8 x i32> @llvm.vector.insert.v2i32.v8i32(<8 x i32> poison, <2 x i32> %v, i64 0) + %2 = call <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32> %1, i64 0) + ret <4 x i32> %2 +}