From: Simon Pilgrim Date: Tue, 23 Apr 2019 14:07:49 +0000 (+0000) Subject: [X86] Pull out collectConcatOps helper. NFCI. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=363e1da675c72a9e28cb146823bde9f89d64ccff;p=llvm [X86] Pull out collectConcatOps helper. NFCI. Create collectConcatOps helper that returns all the subvector ops for CONCAT_VECTORS or a INSERT_SUBVECTOR series. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358989 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index f13e1147dd9..6f8894060d6 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -5434,6 +5434,39 @@ static SDValue widenSubVector(MVT VT, SDValue Vec, bool ZeroNewElements, DAG.getIntPtrConstant(0, dl)); } +// Helper function to collect subvector ops that are concated together, +// either by ISD::CONCAT_VECTORS or a ISD::INSERT_SUBVECTOR series. +// The subvectors in Ops are guaranteed to be the same type. +static bool collectConcatOps(SDNode *N, SmallVectorImpl &Ops) { + assert(Ops.empty() && "Expected an empty ops vector"); + + if (N->getOpcode() == ISD::CONCAT_VECTORS) { + Ops.append(N->op_begin(), N->op_end()); + return true; + } + + if (N->getOpcode() == ISD::INSERT_SUBVECTOR && + isa(N->getOperand(2))) { + SDValue Src = N->getOperand(0); + SDValue Sub = N->getOperand(1); + const APInt &Idx = N->getConstantOperandAPInt(2); + EVT VT = Src.getValueType(); + EVT SubVT = Sub.getValueType(); + + // TODO - Handle more general insert_subvector chains. + if (VT.getSizeInBits() == (SubVT.getSizeInBits() * 2) && + Idx == (VT.getVectorNumElements() / 2) && + Src.getOpcode() == ISD::INSERT_SUBVECTOR && + isNullConstant(Src.getOperand(2))) { + Ops.push_back(Src.getOperand(1)); + Ops.push_back(Sub); + return true; + } + } + + return false; +} + // Helper for splitting operands of an operation to legal target size and // apply a function on each part. // Useful for operations that are available on SSE2 in 128-bit, on AVX2 in @@ -42377,29 +42410,26 @@ static SDValue combineInsertSubvector(SDNode *N, SelectionDAG &DAG, } // Match concat_vector style patterns. + SmallVector SubVectorOps; + if (collectConcatOps(N, SubVectorOps)) + if (SDValue Fold = + combineConcatVectorOps(dl, OpVT, SubVectorOps, DAG, DCI, Subtarget)) + return Fold; + + // If we are inserting into both halves of the vector, the starting vector + // should be undef. If it isn't, make it so. Only do this if the early insert + // has no other uses. + // TODO: Should this be a generic DAG combine? + // TODO: Why doesn't SimplifyDemandedVectorElts catch this? if ((IdxVal == OpVT.getVectorNumElements() / 2) && Vec.getOpcode() == ISD::INSERT_SUBVECTOR && - OpVT.getSizeInBits() == SubVecVT.getSizeInBits() * 2) { - if (isNullConstant(Vec.getOperand(2))) { - SDValue SubVec2 = Vec.getOperand(1); - - SDValue Ops[] = {SubVec2, SubVec}; - if (SDValue Fold = - combineConcatVectorOps(dl, OpVT, Ops, DAG, DCI, Subtarget)) - return Fold; - - // If we are inserting into both halves of the vector, the starting - // vector should be undef. If it isn't, make it so. Only do this if the - // the early insert has no other uses. - // TODO: Should this be a generic DAG combine? - // TODO: Why doesn't SimplifyDemandedVectorElts catch this? - if (!Vec.getOperand(0).isUndef() && Vec.hasOneUse()) { - Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT, DAG.getUNDEF(OpVT), - SubVec2, Vec.getOperand(2)); - return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT, Vec, SubVec, - N->getOperand(2)); - } - } + OpVT.getSizeInBits() == SubVecVT.getSizeInBits() * 2 && + isNullConstant(Vec.getOperand(2)) && !Vec.getOperand(0).isUndef() && + Vec.hasOneUse()) { + Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT, DAG.getUNDEF(OpVT), + Vec.getOperand(1), Vec.getOperand(2)); + return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, OpVT, Vec, SubVec, + N->getOperand(2)); } // If this is a broadcast insert into an upper undef, use a larger broadcast.