aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
authorNadav Rotem <nadav.rotem@intel.com>2012-04-07 21:19:08 +0000
committerNadav Rotem <nadav.rotem@intel.com>2012-04-07 21:19:08 +0000
commitd16c8d0d336638225378466bc17c9db156401817 (patch)
treea9afe1da5eb726f19fb7b331444edfdceffd9482 /lib/CodeGen/SelectionDAG/DAGCombiner.cpp
parent961d666be4f3714452ff9f15470f9255d85f0506 (diff)
1. Remove the part of r153848 which optimizes shuffle-of-shuffle into a new
shuffle node because it could introduce new shuffle nodes that were not supported efficiently by the target. 2. Add a more restrictive shuffle-of-shuffle optimization for cases where the second shuffle reverses the transformation of the first shuffle. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154266 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp26
1 files changed, 14 insertions, 12 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index e0fd3abfb4..ebffb8562e 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7795,19 +7795,20 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
}
// If this shuffle node is simply a swizzle of another shuffle node,
- // optimize shuffle(shuffle(x, y), undef) -> shuffle(x, y).
+ // and it reverses the swizzle of the previous shuffle then we can
+ // optimize shuffle(shuffle(x, undef), undef) -> x.
if (N0.getOpcode() == ISD::VECTOR_SHUFFLE && Level < AfterLegalizeDAG &&
N1.getOpcode() == ISD::UNDEF) {
- SmallVector<int, 8> NewMask;
ShuffleVectorSDNode *OtherSV = cast<ShuffleVectorSDNode>(N0);
- // If the source shuffle has more than one user then do not try to optimize
- // it because it may generate a more complex shuffle node. However, if the
- // source shuffle is also a swizzle (a single source shuffle), our
- // transformation is still likely to reduce the number of shuffles and only
- // generate a simple shuffle node.
- if (N0.getOperand(1).getOpcode() != ISD::UNDEF && !N0.hasOneUse())
+ // Shuffle nodes can only reverse shuffles with a single non-undef value.
+ if (N0.getOperand(1).getOpcode() != ISD::UNDEF)
+ return SDValue();
+
+ // The incoming shuffle must be of the same type as the result of the current
+ // shuffle.
+ if (OtherSV->getOperand(0).getValueType() != VT)
return SDValue();
EVT InVT = N0.getValueType();
@@ -7824,11 +7825,12 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) {
if (Idx >= 0)
Idx = OtherSV->getMaskElt(Idx);
- NewMask.push_back(Idx);
+ // The combined shuffle must map each index to itself.
+ if (Idx != i && Idx != -1)
+ return SDValue();
}
- assert(NewMask.size() == VT.getVectorNumElements() && "Invalid mask size");
- return DAG.getVectorShuffle(VT, N->getDebugLoc(), OtherSV->getOperand(0),
- OtherSV->getOperand(1), &NewMask[0]);
+
+ return OtherSV->getOperand(0);
}
return SDValue();