diff options
author | Michael Kuperstein <michael.m.kuperstein@intel.com> | 2015-01-22 13:07:28 +0000 |
---|---|---|
committer | Michael Kuperstein <michael.m.kuperstein@intel.com> | 2015-01-22 13:07:28 +0000 |
commit | 25e34d11f3cab6a79b7fc22d5385f86523550e90 (patch) | |
tree | e3f6d83d0a06865c99eafe7b661aa45451e1dd9a /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | a007905e4eb7b1c2b134ee6a936d895ba9ac575a (diff) | |
download | bcm5719-llvm-25e34d11f3cab6a79b7fc22d5385f86523550e90.tar.gz bcm5719-llvm-25e34d11f3cab6a79b7fc22d5385f86523550e90.zip |
[DAGCombine] Produce better code for constant splats
This solves PR22276.
Splats of constants would sometimes produce redundant shuffles, sometimes ridiculously so (see the PR for details). Fold these shuffles into BUILD_VECTORs early on instead.
Differential Revision: http://reviews.llvm.org/D7093
Fixed recommit of r226811.
llvm-svn: 226816
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index a06f35ee937..72f458118da 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11490,7 +11490,7 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { } // If it is a splat, check if the argument vector is another splat or a - // build_vector with all scalar elements the same. + // build_vector. if (SVN->isSplat() && SVN->getSplatIndex() < (int)NumElts) { SDNode *V = N0.getNode(); @@ -11527,6 +11527,24 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { // Splat of <x, x, x, x>, return <x, x, x, x> if (AllSame) return N0; + + // If the splatted element is a constant, just build the vector out of + // constants directly. + const SDValue &Splatted = V->getOperand(SVN->getSplatIndex()); + if (isa<ConstantSDNode>(Splatted) || isa<ConstantFPSDNode>(Splatted)) { + SmallVector<SDValue, 8> Ops; + for (unsigned i = 0; i != NumElts; ++i) { + Ops.push_back(Splatted); + } + SDValue NewBV = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), + V->getValueType(0), Ops); + + // We may have jumped through bitcasts, so the type of the + // BUILD_VECTOR may not match the type of the shuffle. + if (V->getValueType(0) != VT) + NewBV = DAG.getNode(ISD::BITCAST, SDLoc(N), VT, NewBV); + return NewBV; + } } } |