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