From ec4881ad537562bae44c821ab74f28c9bee727d4 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 13 Mar 2018 22:36:07 +0000 Subject: [PATCH] [X86] Simplify the LowerAVXCONCAT_VECTORS code a little by creating a single path for insert_subvector handling. We now only create recursive concats if we have more than two non-zero values. This keeps our subvector broadcast DAG combine functioning. llvm-svn: 327457 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 39 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index e316b7b..4d31472 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -8585,6 +8585,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const { // 256-bit AVX can use the vinsertf128 instruction // to create 256-bit vectors from two other 128-bit ones. +// TODO: Detect subvector broadcast here instead of DAG combine? static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG, const X86Subtarget &Subtarget) { SDLoc dl(Op); @@ -8610,20 +8611,8 @@ static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG, } } - // If there are zero or one non-zeros we can handle this very simply. - if (NumNonZero <= 1) { - SDValue Vec = NumZero ? getZeroVector(ResVT, Subtarget, DAG, dl) - : DAG.getUNDEF(ResVT); - if (!NumNonZero) - return Vec; - unsigned Idx = countTrailingZeros(NonZeros); - SDValue SubVec = Op.getOperand(Idx); - unsigned SubVecNumElts = SubVec.getSimpleValueType().getVectorNumElements(); - return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, SubVec, - DAG.getIntPtrConstant(Idx * SubVecNumElts, dl)); - } - - if (NumOperands > 2) { + // If we have more than 2 non-zeros, build each half separately. + if (NumNonZero > 2) { MVT HalfVT = MVT::getVectorVT(ResVT.getVectorElementType(), ResVT.getVectorNumElements()/2); ArrayRef Ops = Op->ops(); @@ -8634,14 +8623,22 @@ static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG, return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi); } - assert(NumNonZero == 2 && "Simple cases not handled?"); + // Otherwise, build it up through insert_subvectors. + SDValue Vec = NumZero ? getZeroVector(ResVT, Subtarget, DAG, dl) + : DAG.getUNDEF(ResVT); - SDValue Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, - DAG.getUNDEF(ResVT), Op.getOperand(0), - DAG.getIntPtrConstant(0, dl)); - unsigned NumElems = ResVT.getVectorNumElements(); - return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, Op.getOperand(1), - DAG.getIntPtrConstant(NumElems/2, dl)); + MVT SubVT = Op.getOperand(0).getSimpleValueType(); + unsigned NumSubElems = SubVT.getVectorNumElements(); + for (unsigned i = 0; i != NumOperands; ++i) { + if ((NonZeros & (1 << i)) == 0) + continue; + + Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, + Op.getOperand(i), + DAG.getIntPtrConstant(i * NumSubElems, dl)); + } + + return Vec; } // Return true if all the operands of the given CONCAT_VECTORS node are zeros -- 2.7.4