Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.177 -> 1.178 --- Log message: If a shuffle is a splat, check if the argument is a build_vector with all elements being the same. If so, return the argument. --- Diffs of the changes: (+90 -8) DAGCombiner.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 90 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.177 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.178 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.177 Thu Jul 20 17:44:41 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Jul 21 03:25:53 2006 @@ -2601,16 +2601,23 @@ // Check if the shuffle is a unary shuffle, i.e. one of the vectors is not // needed at all. bool isUnary = true; + bool isSplat = true; int VecNum = -1; + unsigned BaseIdx; for (unsigned i = 0; i != NumElts; ++i) if (ShufMask.getOperand(i).getOpcode() != ISD::UNDEF) { unsigned Idx = cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue(); int V = (Idx < NumElts) ? 0 : 1; - if (VecNum == -1) + if (VecNum == -1) { VecNum = V; - else if (VecNum != V) { - isUnary = false; - break; + BaseIdx = Idx; + } else { + if (BaseIdx != Idx) + isSplat = false; + if (VecNum != V) { + isUnary = false; + break; + } } } @@ -2620,6 +2627,40 @@ if (isUnary && VecNum == 1) std::swap(N0, N1); + // If it is a splat, check if the argument vector is a build_vector with + // all scalar elements the same. + if (isSplat) { + SDNode *V = N0.Val; + if (V->getOpcode() == ISD::BIT_CONVERT) + V = V->getOperand(0).Val; + if (V->getOpcode() == ISD::BUILD_VECTOR) { + unsigned NumElems = V->getNumOperands()-2; + if (NumElems > BaseIdx) { + SDOperand Base; + bool AllSame = true; + for (unsigned i = 0; i != NumElems; ++i) { + if (V->getOperand(i).getOpcode() != ISD::UNDEF) { + Base = V->getOperand(i); + break; + } + } + // Splat of <u, u, u, u>, return <u, u, u, u> + if (!Base.Val) + return N0; + for (unsigned i = 0; i != NumElems; ++i) { + if (V->getOperand(i).getOpcode() != ISD::UNDEF && + V->getOperand(i) != Base) { + AllSame = false; + break; + } + } + // Splat of <x, x, x, x>, return <x, x, x, x> + if (AllSame) + return N0; + } + } + } + // If it is a unary or the LHS and the RHS are the same node, turn the RHS // into an undef. if (isUnary || N0 == N1) { @@ -2679,16 +2720,23 @@ // Check if the shuffle is a unary shuffle, i.e. one of the vectors is not // needed at all. bool isUnary = true; + bool isSplat = true; int VecNum = -1; + unsigned BaseIdx; for (unsigned i = 0; i != NumElts; ++i) if (ShufMask.getOperand(i).getOpcode() != ISD::UNDEF) { unsigned Idx = cast<ConstantSDNode>(ShufMask.getOperand(i))->getValue(); int V = (Idx < NumElts) ? 0 : 1; - if (VecNum == -1) + if (VecNum == -1) { VecNum = V; - else if (VecNum != V) { - isUnary = false; - break; + BaseIdx = Idx; + } else { + if (BaseIdx != Idx) + isSplat = false; + if (VecNum != V) { + isUnary = false; + break; + } } } @@ -2698,6 +2746,40 @@ if (isUnary && VecNum == 1) std::swap(N0, N1); + // If it is a splat, check if the argument vector is a build_vector with + // all scalar elements the same. + if (isSplat) { + SDNode *V = N0.Val; + if (V->getOpcode() == ISD::VBIT_CONVERT) + V = V->getOperand(0).Val; + if (V->getOpcode() == ISD::VBUILD_VECTOR) { + unsigned NumElems = V->getNumOperands()-2; + if (NumElems > BaseIdx) { + SDOperand Base; + bool AllSame = true; + for (unsigned i = 0; i != NumElems; ++i) { + if (V->getOperand(i).getOpcode() != ISD::UNDEF) { + Base = V->getOperand(i); + break; + } + } + // Splat of <u, u, u, u>, return <u, u, u, u> + if (!Base.Val) + return N0; + for (unsigned i = 0; i != NumElems; ++i) { + if (V->getOperand(i).getOpcode() != ISD::UNDEF && + V->getOperand(i) != Base) { + AllSame = false; + break; + } + } + // Splat of <x, x, x, x>, return <x, x, x, x> + if (AllSame) + return N0; + } + } + } + // If it is a unary or the LHS and the RHS are the same node, turn the RHS // into an undef. if (isUnary || N0 == N1) { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits