Repository navigation
Open
Open
Copy link
Labels
confirmedVerified by a second partyVerified by a second partycrash-on-validllvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passesCovers the InstCombine, InstSimplify and AggressiveInstCombine passesregression:24Regression in 24 releaseRegression in 24 release
Description
InstCombine's foldSelectToCmp folds a select with a scalar condition and vector operands (a legal form produced e.g. by the loop vectorizer for uniform conditions) into llvm.scmp() or llvm.ucmp() intrinsic call with a vector result and scalar operands. That is invalid IR and a later fold crashes on a type-mismatched RAUW (Value::doRAUW assert).
Here are three cases that demonstrate the issue by causing a crash:
https://godbolt.org/z/KMnqqbjs6 :
define <4 x i1> @scmp_scalar_cond_vector_vals(i32 %x, i32 %y) {
%gt = icmp sgt i32 %x, %y
%s1 = select i1 %gt, <4 x i32> splat (i32 1), <4 x i32> splat (i32 -1)
%eq = icmp eq i32 %x, %y
%r = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
%cmp = icmp sgt <4 x i32> %r, zeroinitializer
ret <4 x i1> %cmp
}https://godbolt.org/z/heGWYoG7o :
define <4 x i1> @ucmp_scalar_cond_vector_vals(i32 %x, i32 %y) {
%gt = icmp ugt i32 %x, %y
%s1 = select i1 %gt, <4 x i32> splat (i32 1), <4 x i32> splat (i32 -1)
%eq = icmp eq i32 %x, %y
%r = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
%cmp = icmp ugt <4 x i32> %r, zeroinitializer
ret <4 x i1> %cmp
}https://godbolt.org/z/Tq3GM3a4h :
; Constant special case: x == C ? 0 : (x > C-1 ? 1 : -1)
define <4 x i32> @scmp_scalar_cond_vector_vals_const(i32 %x) {
%gt = icmp sgt i32 %x, -5
%s1 = select i1 %gt, <4 x i32> splat (i32 1), <4 x i32> splat (i32 -1)
%eq = icmp eq i32 %x, -4
%r = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
ret <4 x i32> %r
}Here is the log for the first case:
INSTCOMBINE ITERATION #1 on scmp_scalar_cond_vector_vals
ADD: ret <4 x i1> %cmp
ADD: %cmp = icmp sgt <4 x i32> %r, zeroinitializer
ADD: %r = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
ADD: %eq = icmp eq i32 %x, %y
ADD: %s1 = select i1 %gt, <4 x i32> splat (i32 1), <4 x i32> splat (i32 -1)
ADD: %gt = icmp sgt i32 %x, %y
IC: Visiting: %gt = icmp sgt i32 %x, %y
IC: Visiting: %s1 = select i1 %gt, <4 x i32> splat (i32 1), <4 x i32> splat (i32 -1)
IC: Visiting: %eq = icmp eq i32 %x, %y
IC: Visiting: %r = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
ADD DEFERRED: %1 = call <4 x i32> @llvm.scmp.v4i32.i32(i32 %x, i32 %y)
IC: Replacing %r = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
with %1 = call <4 x i32> @llvm.scmp.v4i32.i32(i32 %x, i32 %y)
IC: Mod = %r = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
New = %1 = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
IC: ERASE %1 = select i1 %eq, <4 x i32> zeroinitializer, <4 x i32> %s1
ADD DEFERRED: %eq = icmp eq i32 %x, %y
ADD DEFERRED: %s1 = select i1 %gt, <4 x i32> splat (i32 1), <4 x i32> splat (i32 -1)
IC: ERASE %s1 = select i1 %gt, <4 x i32> splat (i32 1), <4 x i32> splat (i32 -1)
ADD DEFERRED: %gt = icmp sgt i32 %x, %y
IC: ERASE %gt = icmp sgt i32 %x, %y
IC: ERASE %eq = icmp eq i32 %x, %y
ADD: %r = call <4 x i32> @llvm.scmp.v4i32.i32(i32 %x, i32 %y)
IC: Visiting: %r = call <4 x i32> @llvm.scmp.v4i32.i32(i32 %x, i32 %y)
opt: /root/llvm-project/llvm/include/llvm/Support/Casting.h:572: decltype(auto) llvm::cast(From*) [with To = llvm::FixedVectorType; From = llvm::Type]: Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/opt -o /app/output.s -S -passes=instcombine -debug-only=instcombine <source>
1. Running pass "function(instcombine<max-iterations=1;verify-fixpoint>)" on module "<source>"
2. Running pass "instcombine<max-iterations=1;verify-fixpoint>" on function "scmp_scalar_cond_vector_vals"
#0 0x00000000008bf3a8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8bf3a8)
#1 0x00000000008bc194 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8bc194)
#2 0x00000000008bc30e SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0x0000771079c45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#4 0x0000771079c9ec0c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9ec0c)
#5 0x0000771079c4527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#6 0x0000771079c288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#7 0x0000771079c2881b (/lib/x86_64-linux-gnu/libc.so.6+0x2881b)
#8 0x0000771079c3b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#9 0x0000000004e82919 llvm::InstCombinerImpl::SimplifyDemandedVectorElts(llvm::Value*, llvm::APInt, llvm::APInt&, unsigned int, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4e82919)
#10 0x0000000004e83371 llvm::InstCombinerImpl::SimplifyDemandedVectorElts(llvm::Value*, llvm::APInt, llvm::APInt&, unsigned int, bool)::'lambda'(llvm::Instruction*, unsigned int, llvm::APInt, llvm::APInt&)::operator()(llvm::Instruction*, unsigned int, llvm::APInt, llvm::APInt&) const InstCombineSimplifyDemanded.cpp:0:0
#11 0x0000000004e82743 llvm::InstCombinerImpl::SimplifyDemandedVectorElts(llvm::Value*, llvm::APInt, llvm::APInt&, unsigned int, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4e82743)
#12 0x0000000004db3f82 llvm::InstCombinerImpl::visitCallInst(llvm::CallInst&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4db3f82)
#13 0x0000000004d52374 llvm::InstCombinerImpl::run() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4d52374)
#14 0x0000000004d533fc combineInstructionsOverFunction(llvm::Function&, llvm::InstructionWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::BranchProbabilityInfo*, llvm::ProfileSummaryInfo*, llvm::InstCombineOptions const&) (.isra.0) InstructionCombining.cpp:0:0
#15 0x0000000004d546dd llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4d546dd)
#16 0x0000000002f403ae llvm::detail::PassModel<llvm::Function, llvm::InstCombinePass, llvm::AnalysisManager<llvm::Function>>::runImpl(llvm::detail::PassConcept<llvm::Function, llvm::AnalysisManager<llvm::Function>>&, llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2f403ae)
#17 0x0000000005bd66b1 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5bd66b1)
#18 0x0000000000fbe1ce llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::runImpl(llvm::detail::PassConcept<llvm::Function, llvm::AnalysisManager<llvm::Function>>&, llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xfbe1ce)
#19 0x0000000005bd4c3c llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5bd4c3c)
#20 0x0000000000984afe llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::runImpl(llvm::detail::PassConcept<llvm::Module, llvm::AnalysisManager<llvm::Module>>&, llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x984afe)
#21 0x0000000005bd442e llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5bd442e)
#22 0x000000000098e567 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPluginLibraryInfo>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x98e567)
#23 0x0000000000983ca5 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x983ca5)
#24 0x000000000083e490 main (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x83e490)
#25 0x0000771079c2a1ca (/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
#26 0x0000771079c2a28b __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
#27 0x000000000089e0e5 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x89e0e5)
Program terminated with signal SIGABRT (6)
Compiler returned: 134
Metadata
Metadata
Assignees
Labels
confirmedVerified by a second partyVerified by a second partycrash-on-validllvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passesCovers the InstCombine, InstSimplify and AggressiveInstCombine passesregression:24Regression in 24 releaseRegression in 24 release
Type
Projects
- StatusShow more project fieldsNo status
Activity
llvmorg-github-actions commentedon Nov 12, 2026
Undef values are deprecated. Unless this miscompilation is observable in real-world programs, we don't want to fix it.
yrouban commentedon Nov 12, 2026
The following code in the beginning of InstCombinerImpl::foldSelectToCmp(SelectInst &SI) fixes the issue: