diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -1258,22 +1258,25 @@ GetSplitVector(Vec, Lo, Hi); EVT VecVT = Vec.getValueType(); + EVT LoVT = Lo.getValueType(); unsigned VecElems = VecVT.getVectorNumElements(); unsigned SubElems = SubVec.getValueType().getVectorNumElements(); + unsigned LoElems = LoVT.getVectorNumElements(); - // If we know the index is 0, and we know the subvector doesn't cross the - // boundary between the halves, we can avoid spilling the vector, and insert - // into the lower half of the split vector directly. - // TODO: The IdxVal == 0 constraint is artificial, we could do this whenever - // there is no boundary crossing. But those cases don't seem to get hit in - // practice. + // If we know the index is in the first half, and we know the subvector + // doesn't cross the boundary between the halves, we can avoid spilling the + // vector, and insert into the lower half of the split vector directly. + // Similarly if the subvector is fully in the high half. unsigned IdxVal = cast(Idx)->getZExtValue(); - if ((IdxVal == 0) && (IdxVal + SubElems <= VecElems / 2)) { - EVT LoVT, HiVT; - std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); + if (IdxVal >= 0 && (IdxVal + SubElems <= LoElems)) { Lo = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, LoVT, Lo, SubVec, Idx); return; } + if ((IdxVal >= LoElems) && (IdxVal + SubElems <= VecElems)) { + Hi = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, Hi.getValueType(), Hi, SubVec, + DAG.getVectorIdxConstant(IdxVal - LoElems, dl)); + return; + } // Spill the vector to the stack. // In cases where the vector is illegal it will be broken down into parts diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector.ll @@ -393,15 +393,13 @@ ret void } -; FIXME: SplitVecRes_INSERT_SUBVECTOR crashes on this one when trying to spill -; to the stack. -;define void @insert_v32i1_v8i1_16(<32 x i1>* %vp, <8 x i1>* %svp) { -; %v = load <32 x i1>, <32 x i1>* %vp -; %sv = load <8 x i1>, <8 x i1>* %svp -; %c = call <32 x i1> @llvm.experimental.vector.insert.v8i1.v32i1(<32 x i1> %v, <8 x i1> %sv, i64 16) -; store <32 x i1> %c, <32 x i1>* %vp -; ret void -;} +define void @insert_v32i1_v8i1_16(<32 x i1>* %vp, <8 x i1>* %svp) { + %v = load <32 x i1>, <32 x i1>* %vp + %sv = load <8 x i1>, <8 x i1>* %svp + %c = call <32 x i1> @llvm.experimental.vector.insert.v8i1.v32i1(<32 x i1> %v, <8 x i1> %sv, i64 16) + store <32 x i1> %c, <32 x i1>* %vp + ret void +} define void @insert_v8i1_v4i1_0(<8 x i1>* %vp, <4 x i1>* %svp) { ; CHECK-LABEL: insert_v8i1_v4i1_0: