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
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index e0fd3ab..ebffb85 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7795,19 +7795,20 @@
}
// 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 @@
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();