diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 4bf37b631bd..d9f930d725a 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -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); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 5689a152ca5..b2de2a4f343 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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 index 00000000000..7aa7013da46 --- /dev/null +++ b/test/CodeGen/AArch64/shuffle-mask-legal.ll @@ -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> + %cat2 = shufflevector <2 x i32> %p2, <2 x i32> undef, <4 x i32> + %r = shufflevector <4 x i32> %cat1, <4 x i32> %cat2, <4 x i32> + ret <4 x i32> %r +}