diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1811,85 +1811,76 @@ // been built. This will work only if all of the necessary shuffle masks // are legal. - // We do this in two phases; first to check the legality of the shuffles, - // and next, assuming that all shuffles are legal, to create the new nodes. - for (int Phase = 0; Phase < 2; ++Phase) { - SmallVector>, 16> IntermedVals, - NewIntermedVals; - for (unsigned i = 0; i < NumElems; ++i) { - SDValue V = Node->getOperand(i); - if (V.isUndef()) - continue; - - SDValue Vec; - if (Phase) - Vec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, V); - IntermedVals.push_back(std::make_pair(Vec, SmallVector(1, i))); - } + SmallVector>, 16> IntermedVals, + NewIntermedVals; + for (unsigned i = 0; i < NumElems; ++i) { + SDValue V = Node->getOperand(i); + if (V.isUndef()) + continue; - while (IntermedVals.size() > 2) { - NewIntermedVals.clear(); - for (unsigned i = 0, e = (IntermedVals.size() & ~1u); i < e; i += 2) { - // This vector and the next vector are shuffled together (simply to - // append the one to the other). - SmallVector ShuffleVec(NumElems, -1); - - SmallVector FinalIndices; - FinalIndices.reserve(IntermedVals[i].second.size() + - IntermedVals[i+1].second.size()); - - int k = 0; - for (unsigned j = 0, f = IntermedVals[i].second.size(); j != f; - ++j, ++k) { - ShuffleVec[k] = j; - FinalIndices.push_back(IntermedVals[i].second[j]); - } - for (unsigned j = 0, f = IntermedVals[i+1].second.size(); j != f; - ++j, ++k) { - ShuffleVec[k] = NumElems + j; - FinalIndices.push_back(IntermedVals[i+1].second[j]); - } + SDValue Vec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, V); + IntermedVals.push_back(std::make_pair(Vec, SmallVector(1, i))); + } - SDValue Shuffle; - if (Phase) - Shuffle = DAG.getVectorShuffle(VT, dl, IntermedVals[i].first, - IntermedVals[i+1].first, - ShuffleVec); - else if (!TLI.isShuffleMaskLegal(ShuffleVec, VT)) - return false; - NewIntermedVals.push_back( - std::make_pair(Shuffle, std::move(FinalIndices))); + while (IntermedVals.size() > 2) { + NewIntermedVals.clear(); + for (unsigned i = 0, e = (IntermedVals.size() & ~1u); i < e; i += 2) { + // This vector and the next vector are shuffled together (simply to + // append the one to the other). + SmallVector ShuffleVec(NumElems, -1); + + SmallVector FinalIndices; + FinalIndices.reserve(IntermedVals[i].second.size() + + IntermedVals[i + 1].second.size()); + + int k = 0; + for (unsigned j = 0, f = IntermedVals[i].second.size(); j != f; + ++j, ++k) { + ShuffleVec[k] = j; + FinalIndices.push_back(IntermedVals[i].second[j]); + } + for (unsigned j = 0, f = IntermedVals[i + 1].second.size(); j != f; + ++j, ++k) { + ShuffleVec[k] = NumElems + j; + FinalIndices.push_back(IntermedVals[i + 1].second[j]); } - // If we had an odd number of defined values, then append the last - // element to the array of new vectors. - if ((IntermedVals.size() & 1) != 0) - NewIntermedVals.push_back(IntermedVals.back()); + if (!TLI.isShuffleMaskLegal(ShuffleVec, VT)) + return false; - IntermedVals.swap(NewIntermedVals); + SDValue Shuffle = DAG.getVectorShuffle( + VT, dl, IntermedVals[i].first, IntermedVals[i + 1].first, ShuffleVec); + NewIntermedVals.push_back( + std::make_pair(Shuffle, std::move(FinalIndices))); } - assert(IntermedVals.size() <= 2 && IntermedVals.size() > 0 && - "Invalid number of intermediate vectors"); - SDValue Vec1 = IntermedVals[0].first; - SDValue Vec2; - if (IntermedVals.size() > 1) - Vec2 = IntermedVals[1].first; - else if (Phase) - Vec2 = DAG.getUNDEF(VT); - - SmallVector ShuffleVec(NumElems, -1); - for (unsigned i = 0, e = IntermedVals[0].second.size(); i != e; ++i) - ShuffleVec[IntermedVals[0].second[i]] = i; - for (unsigned i = 0, e = IntermedVals[1].second.size(); i != e; ++i) - ShuffleVec[IntermedVals[1].second[i]] = NumElems + i; - - if (Phase) - Res = DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec); - else if (!TLI.isShuffleMaskLegal(ShuffleVec, VT)) - return false; + // If we had an odd number of defined values, then append the last + // element to the array of new vectors. + if ((IntermedVals.size() & 1) != 0) + NewIntermedVals.push_back(IntermedVals.back()); + + IntermedVals.swap(NewIntermedVals); } + assert(IntermedVals.size() <= 2 && IntermedVals.size() > 0 && + "Invalid number of intermediate vectors"); + SDValue Vec1 = IntermedVals[0].first; + SDValue Vec2; + if (IntermedVals.size() > 1) + Vec2 = IntermedVals[1].first; + else + Vec2 = DAG.getUNDEF(VT); + + SmallVector ShuffleVec(NumElems, -1); + for (unsigned i = 0, e = IntermedVals[0].second.size(); i != e; ++i) + ShuffleVec[IntermedVals[0].second[i]] = i; + for (unsigned i = 0, e = IntermedVals[1].second.size(); i != e; ++i) + ShuffleVec[IntermedVals[1].second[i]] = NumElems + i; + + if (!TLI.isShuffleMaskLegal(ShuffleVec, VT)) + return false; + Res = DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec); + return true; }