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 @@ -1261,19 +1261,24 @@ unsigned VecElems = VecVT.getVectorNumElements(); unsigned SubElems = SubVec.getValueType().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)) { + if (IdxVal >= 0 && (IdxVal + SubElems <= VecElems / 2)) { EVT LoVT, HiVT; std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); Lo = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, LoVT, Lo, SubVec, Idx); return; } + if ((IdxVal >= VecElems / 2) && (IdxVal + SubElems <= VecElems)) { + EVT LoVT, HiVT; + std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); + Hi = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, HiVT, Hi, SubVec, + DAG.getVectorIdxConstant(IdxVal - (VecElems / 2), dl)); + return; + } // Spill the vector to the stack. // In cases where the vector is illegal it will be broken down into parts