]> granicus.if.org Git - llvm/commitdiff
[SelectionDAG] soften splat mask assert/unreachable (PR41535)
authorSanjay Patel <spatel@rotateright.com>
Fri, 19 Apr 2019 15:31:11 +0000 (15:31 +0000)
committerSanjay Patel <spatel@rotateright.com>
Fri, 19 Apr 2019 15:31:11 +0000 (15:31 +0000)
These are general queries, so they should not die when given
a degenerate input like an all undef mask. Callers should be
able to deal with an op that will eventually be simplified away.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358761 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
test/CodeGen/AArch64/shuffle-mask-legal.ll [new file with mode: 0644]

index 4bf37b631bdb11856591b9ad3542b092cc0e853a..d9f930d725a84e77f3688e02f389acde1f9a9a4b 100644 (file)
@@ -1499,14 +1499,16 @@ public:
 
   bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
 
-  int  getSplatIndex() const {
+  int getSplatIndex() const {
     assert(isSplat() && "Cannot get splat index for non-splat!");
     EVT VT = getValueType(0);
-    for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i) {
+    for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i)
       if (Mask[i] >= 0)
         return Mask[i];
-    }
-    llvm_unreachable("Splat with all undef indices?");
+
+    // We can choose any index value here and be correct because all elements
+    // are undefined. Return 0 for better potential for callers to simplify.
+    return 0;
   }
 
   static bool isSplatMask(const int *Mask, EVT VT);
index 5689a152ca550e40237d0d343f2cca40ac9c885e..b2de2a4f343c9325b50f324b4382d91c850843a7 100644 (file)
@@ -9350,7 +9350,10 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {
   for (i = 0, e = VT.getVectorNumElements(); i != e && Mask[i] < 0; ++i)
     /* search */;
 
-  assert(i != e && "VECTOR_SHUFFLE node with all undef indices!");
+  // If all elements are undefined, this shuffle can be considered a splat
+  // (although it should eventually get simplified away completely).
+  if (i == e)
+    return true;
 
   // Make sure all remaining elements are either undef or the same as the first
   // non-undef value.
diff --git a/test/CodeGen/AArch64/shuffle-mask-legal.ll b/test/CodeGen/AArch64/shuffle-mask-legal.ll
new file mode 100644 (file)
index 0000000..7aa7013
--- /dev/null
@@ -0,0 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
+
+; A shuffle mask with all undef elements is always legal.
+
+define <4 x i32> @PR41535(<2 x i32> %p1, <2 x i32> %p2) {
+; CHECK-LABEL: PR41535:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ext v0.8b, v0.8b, v1.8b, #4
+; CHECK-NEXT:    mov v0.d[1], v0.d[0]
+; CHECK-NEXT:    ret
+  %cat1 = shufflevector <2 x i32> %p1, <2 x i32> undef, <4 x i32> <i32 undef, i32 1, i32 undef, i32 undef>
+  %cat2 = shufflevector <2 x i32> %p2, <2 x i32> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
+  %r = shufflevector <4 x i32> %cat1, <4 x i32> %cat2, <4 x i32> <i32 undef, i32 undef, i32 1, i32 4>
+  ret <4 x i32> %r
+}