diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -2053,8 +2053,8 @@ if (UsesLHS && UsesRHS) return false; } - assert((UsesLHS ^ UsesRHS) && "Should have selected from exactly 1 source"); - return true; + // Allow for degenerate case: completely undef mask means neither source is used. + return UsesLHS || UsesRHS; } bool ShuffleVectorInst::isSingleSourceMask(ArrayRef Mask) { @@ -2182,6 +2182,8 @@ } bool ShuffleVectorInst::isIdentityWithPadding() const { + if (isa(Op<2>())) + return false; int NumOpElts = cast(Op<0>()->getType())->getNumElements(); int NumMaskElts = cast(getType())->getNumElements(); if (NumMaskElts <= NumOpElts) @@ -2201,6 +2203,8 @@ } bool ShuffleVectorInst::isIdentityWithExtract() const { + if (isa(Op<2>())) + return false; int NumOpElts = cast(Op<0>()->getType())->getNumElements(); int NumMaskElts = getType()->getNumElements(); if (NumMaskElts >= NumOpElts) @@ -2211,7 +2215,8 @@ bool ShuffleVectorInst::isConcat() const { // Vector concatenation is differentiated from identity with padding. - if (isa(Op<0>()) || isa(Op<1>())) + if (isa(Op<0>()) || isa(Op<1>()) || + isa(Op<2>())) return false; int NumOpElts = cast(Op<0>()->getType())->getNumElements(); diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/cgp_shuffle_crash.ll b/llvm/test/Transforms/CodeGenPrepare/X86/cgp_shuffle_crash.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/CodeGenPrepare/X86/cgp_shuffle_crash.ll @@ -0,0 +1,14 @@ +; RUN: opt -codegenprepare -S %s | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" + +; CHECK-LABEL: shuffle_one_source + +define <2 x i8> @shuffle_one_source(i32 %x) { + %Shuf = shufflevector <2 x i8> zeroinitializer, <2 x i8> zeroinitializer, <2 x i32> undef + %Cmp = icmp slt i32 480483, %x + %B = mul <2 x i8> %Shuf, %Shuf + %S = select i1 %Cmp, <2 x i8> %B, <2 x i8> zeroinitializer + ret <2 x i8> %Shuf +} +