From f63da12be90d5474a066a5957aab070b19d57da7 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Thu, 28 Oct 2010 17:06:14 +0000 Subject: Teach the DAG combiner to fold a splat of a splat. Radar 8597790. Also do some minor refactoring to reduce indentation. llvm-svn: 117558 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 52 ++++++++++++++------------- 1 file changed, 28 insertions(+), 24 deletions(-) (limited to 'llvm/lib/CodeGen') diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 35e1f27df59..d09ae2d20ef 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -6346,9 +6346,10 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { // FIXME: implement canonicalizations from DAG.getVectorShuffle() - // If it is a splat, check if the argument vector is a build_vector with - // all scalar elements the same. - if (cast(N)->isSplat()) { + // If it is a splat, check if the argument vector is another splat or a + // build_vector with all scalar elements the same. + ShuffleVectorSDNode *SVN = cast(N); + if (SVN->isSplat() && SVN->getSplatIndex() < (int)NumElts) { SDNode *V = N0.getNode(); // If this is a bit convert that changes the element type of the vector but @@ -6361,31 +6362,34 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { V = ConvInput.getNode(); } + // Fold a splat of a splat. + ShuffleVectorSDNode *SVV = dyn_cast(V); + if (SVV && SVV->isSplat()) + return N0; + if (V->getOpcode() == ISD::BUILD_VECTOR) { - unsigned NumElems = V->getNumOperands(); - unsigned BaseIdx = cast(N)->getSplatIndex(); - if (NumElems > BaseIdx) { - SDValue Base; - bool AllSame = true; - for (unsigned i = 0; i != NumElems; ++i) { - if (V->getOperand(i).getOpcode() != ISD::UNDEF) { - Base = V->getOperand(i); - break; - } + assert(V->getNumOperands() == NumElts && + "BUILD_VECTOR has wrong number of operands"); + SDValue Base; + bool AllSame = true; + for (unsigned i = 0; i != NumElts; ++i) { + if (V->getOperand(i).getOpcode() != ISD::UNDEF) { + Base = V->getOperand(i); + break; } - // Splat of , return - if (!Base.getNode()) - return N0; - for (unsigned i = 0; i != NumElems; ++i) { - if (V->getOperand(i) != Base) { - AllSame = false; - break; - } + } + // Splat of , return + if (!Base.getNode()) + return N0; + for (unsigned i = 0; i != NumElts; ++i) { + if (V->getOperand(i) != Base) { + AllSame = false; + break; } - // Splat of , return - if (AllSame) - return N0; } + // Splat of , return + if (AllSame) + return N0; } } return SDValue(); -- cgit v1.2.3