diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1682,6 +1682,11 @@ const APInt &Constant::getUniqueInteger() const { if (const ConstantInt *CI = dyn_cast(this)) return CI->getValue(); + // Scalable vectors can use a ConstantExpr to build a splat. + if (isa(this)) + return cast(this->getSplatValue())->getValue(); + // For non-ConstantExpr we use getAggregateElement as a fast path to avoid + // calling getSplatValue in release builds. assert(this->getSplatValue() && "Doesn't contain a unique integer!"); const Constant *C = this->getAggregateElement(0U); assert(C && isa(C) && "Not a vector of numbers!"); diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -3395,3 +3395,16 @@ %v = select i1 %cond, i32 %s, i32 %z ret i32 %v } + +; This previously crashed due to Constant::getUniqueInteger not handling +; scalable vector splat ConstantExprs. +define @and_constant_select_svec( %x, %cond) { +; CHECK-LABEL: @and_constant_select_svec( +; CHECK-NEXT: [[A:%.*]] = and [[X:%.*]], shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) +; CHECK-NEXT: [[B:%.*]] = select [[COND:%.*]], [[A]], [[X]] +; CHECK-NEXT: ret [[B]] +; + %a = and %x, shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) + %b = select %cond, %a, %x + ret %b +}