Skip to content

Commit 34eae80

Browse files
committed
[RISCV] Fix crash when lowering fixed length insert_subvector into undef at 0
This fixes a crash seen in iree-org/iree#15038 and elsewhere. We were reducing the LMUL for inserts into undef at 0 without inserting it back into the original LMUL at the end. But we don't actually perform the slidedown in this path, so we can just skip reducing LMUL here.
1 parent ace20e2 commit 34eae80

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8664,6 +8664,14 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
86648664
Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget);
86658665
}
86668666

8667+
if (OrigIdx == 0 && Vec.isUndef() && VecVT.isFixedLengthVector()) {
8668+
SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT,
8669+
DAG.getUNDEF(ContainerVT), SubVec,
8670+
DAG.getConstant(0, DL, XLenVT));
8671+
SubVec = convertFromScalableVector(VecVT, SubVec, DAG, Subtarget);
8672+
return DAG.getBitcast(Op.getValueType(), SubVec);
8673+
}
8674+
86678675
// Shrink down Vec so we're performing the slideup on a smaller LMUL.
86688676
unsigned LastIdx = OrigIdx + SubVecVT.getVectorNumElements() - 1;
86698677
MVT OrigContainerVT = ContainerVT;
@@ -8678,10 +8686,6 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
86788686
SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT,
86798687
DAG.getUNDEF(ContainerVT), SubVec,
86808688
DAG.getConstant(0, DL, XLenVT));
8681-
if (OrigIdx == 0 && Vec.isUndef() && VecVT.isFixedLengthVector()) {
8682-
SubVec = convertFromScalableVector(VecVT, SubVec, DAG, Subtarget);
8683-
return DAG.getBitcast(Op.getValueType(), SubVec);
8684-
}
86858689
SDValue Mask =
86868690
getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).first;
86878691
// Set the vector length to only the number of elements we care about. Note

llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,3 +636,21 @@ declare <vscale x 2 x i16> @llvm.vector.insert.v2i16.nxv2i16(<vscale x 2 x i16>,
636636
declare <vscale x 8 x i32> @llvm.vector.insert.v2i32.nxv8i32(<vscale x 8 x i32>, <2 x i32>, i64)
637637
declare <vscale x 8 x i32> @llvm.vector.insert.v4i32.nxv8i32(<vscale x 8 x i32>, <4 x i32>, i64)
638638
declare <vscale x 8 x i32> @llvm.vector.insert.v8i32.nxv8i32(<vscale x 8 x i32>, <8 x i32>, i64)
639+
640+
; We emit insert_subvectors of fixed vectors at index 0 into undefs as a
641+
; copy_to_regclass or insert_subreg, depending on the register classes of the
642+
; vector types. Make sure that we use the correct type and not the shrunken
643+
; LMUL=1 type, otherwise we will end up with an invalid extract_subvector when
644+
; converting it from scalable->fixed, e.g. we get this for VLEN=128:
645+
;
646+
; t14: nxv2i32 = insert_subvector undef:nxv2i32, t4, Constant:i64<0>
647+
; t15: v8i32 = extract_subvector t14, Constant:i64<0>
648+
declare <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32>, i64)
649+
define <4 x i32> @insert_extract_v8i32_v2i32_0(<2 x i32> %v) {
650+
; CHECK-LABEL: insert_extract_v8i32_v2i32_0:
651+
; CHECK: # %bb.0:
652+
; CHECK-NEXT: ret
653+
%1 = call <8 x i32> @llvm.vector.insert.v2i32.v8i32(<8 x i32> poison, <2 x i32> %v, i64 0)
654+
%2 = call <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32> %1, i64 0)
655+
ret <4 x i32> %2
656+
}

0 commit comments

Comments
 (0)