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();