Fix PR15950 A bug in DAG Combiner about undef mask
authorHao Liu <Hao.Liu@arm.com>
Mon, 13 May 2013 02:07:05 +0000 (02:07 +0000)
committerHao Liu <Hao.Liu@arm.com>
Mon, 13 May 2013 02:07:05 +0000 (02:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181682 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll [new file with mode: 0644]

index c54dffbb132487afdb23da500cfb79d6d48bf44e..076684993aba30d7e424aa52073213c010eee7c4 100644 (file)
@@ -9254,19 +9254,34 @@ static SDValue partitionShuffleOfConcats(SDNode *N, SelectionDAG &DAG) {
   for (unsigned I = 0; I != NumConcats; ++I) {
     // Make sure we're dealing with a copy.
     unsigned Begin = I * NumElemsPerConcat;
-    if (SVN->getMaskElt(Begin) % NumElemsPerConcat != 0)
-      return SDValue();
+    bool AllUndef = true, NoUndef = true;
+    for (unsigned J = Begin; J != Begin + NumElemsPerConcat; ++J) {
+      if (SVN->getMaskElt(J) >= 0)
+        AllUndef = false;
+      else
+        NoUndef = false;
+    }
 
-    for (unsigned J = 1; J != NumElemsPerConcat; ++J) {
-      if (SVN->getMaskElt(Begin + J - 1) + 1 != SVN->getMaskElt(Begin + J))
+    if (NoUndef) {
+      unsigned Begin = I * NumElemsPerConcat;
+      if (SVN->getMaskElt(Begin) % NumElemsPerConcat != 0)
         return SDValue();
-    }
 
-    unsigned FirstElt = SVN->getMaskElt(Begin) / NumElemsPerConcat;
-    if (FirstElt < N0.getNumOperands())
-      Ops.push_back(N0.getOperand(FirstElt));
-    else
-      Ops.push_back(N1.getOperand(FirstElt - N0.getNumOperands()));
+      for (unsigned J = 1; J != NumElemsPerConcat; ++J)
+        if (SVN->getMaskElt(Begin + J - 1) + 1 != SVN->getMaskElt(Begin + J))
+          return SDValue();
+
+      unsigned FirstElt = SVN->getMaskElt(Begin) / NumElemsPerConcat;
+      if (FirstElt < N0.getNumOperands())
+        Ops.push_back(N0.getOperand(FirstElt));
+      else
+        Ops.push_back(N1.getOperand(FirstElt - N0.getNumOperands()));
+
+    } else if (AllUndef) {
+      Ops.push_back(DAG.getUNDEF(N0.getOperand(0).getValueType()));
+    } else { // Mixed with general masks and undefs, can't do optimization.
+      return SDValue();
+    }
   }
 
   return DAG.getNode(ISD::CONCAT_VECTORS, N->getDebugLoc(), VT, Ops.data(),
diff --git a/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll b/test/CodeGen/ARM/2013-05-13-DAGCombiner-undef-mask.ll
new file mode 100644 (file)
index 0000000..8f6709e
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llc < %s
+target triple = "armv7-none-linux-gnueabi"
+
+define <3 x i64> @shuffle(i1 %dec1, i1 %dec0, <3 x i64> %b) {
+entry:
+  %.sink = select i1 %dec1, <3 x i64> %b, <3 x i64> zeroinitializer
+  %.sink15 = select i1 %dec0, <3 x i64> %b, <3 x i64> zeroinitializer
+  %vecinit7 = shufflevector <3 x i64> %.sink, <3 x i64> %.sink15, <3 x i32> <i32 0, i32 4, i32 undef>
+  ret <3 x i64> %vecinit7
+}