Skip to content

Commit c338ec1

Browse files
lukel97legrosbuffle
authored andcommitted
[RISCV] Fix crash when lowering fixed length insert_subvector into undef at 0 (llvm#67535)
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 bcef21f commit c338ec1

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
@@ -8702,6 +8702,14 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
87028702
Vec = convertToScalableVector(ContainerVT, Vec, DAG, Subtarget);
87038703
}
87048704

8705+
if (OrigIdx == 0 && Vec.isUndef() && VecVT.isFixedLengthVector()) {
8706+
SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT,
8707+
DAG.getUNDEF(ContainerVT), SubVec,
8708+
DAG.getConstant(0, DL, XLenVT));
8709+
SubVec = convertFromScalableVector(VecVT, SubVec, DAG, Subtarget);
8710+
return DAG.getBitcast(Op.getValueType(), SubVec);
8711+
}
8712+
87058713
// Shrink down Vec so we're performing the slideup on a smaller LMUL.
87068714
unsigned LastIdx = OrigIdx + SubVecVT.getVectorNumElements() - 1;
87078715
MVT OrigContainerVT = ContainerVT;
@@ -8716,10 +8724,6 @@ SDValue RISCVTargetLowering::lowerINSERT_SUBVECTOR(SDValue Op,
87168724
SubVec = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ContainerVT,
87178725
DAG.getUNDEF(ContainerVT), SubVec,
87188726
DAG.getConstant(0, DL, XLenVT));
8719-
if (OrigIdx == 0 && Vec.isUndef() && VecVT.isFixedLengthVector()) {
8720-
SubVec = convertFromScalableVector(VecVT, SubVec, DAG, Subtarget);
8721-
return DAG.getBitcast(Op.getValueType(), SubVec);
8722-
}
87238727
SDValue Mask =
87248728
getDefaultVLOps(VecVT, ContainerVT, DL, DAG, Subtarget).first;
87258729
// 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)