opt crash in ScalarEvolution::getBackedgeTakenInfo
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
The following valid IR (reduced from compiling dav1d with UBSan) crashes at trunk with `opt -O3` (https://godbolt.org/z/qo3hnjdK5):
```llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-grtev4-linux-gnu"
@qm_tbl_8x4 = external global [15 x [2 x [32 x i8]]]
; Function Attrs: optsize
define i32 @dav1d_init_qm_tables(i1 %0, ptr %qm_tbl_32x32) #0 {
br label %2
2: ; preds = %5, %1
%.11 = phi i64 [ 0, %1 ], [ 1, %5 ]
br i1 %0, label %4, label %3
3: ; preds = %2
ret i32 0
split: ; preds = %4
call void @llvm.ubsantrap(i8 0)
unreachable
4: ; preds = %2
%.not = icmp ult i64 %.11, ptrtoint (ptr @qm_tbl_8x4 to i64)
br i1 %.not, label %split, label %5
5: ; preds = %4
call void @untriangle(ptr %qm_tbl_32x32, i32 32)
br label %2
}
; Function Attrs: cold noreturn nounwind memory(inaccessiblemem: write)
declare void @llvm.ubsantrap(i8 immarg) #1
define void @untriangle(ptr %0, i32 %1) {
br label %3
3: ; preds = %21, %2
%.016 = phi ptr [ null, %2 ], [ %22, %21 ]
%.015 = phi i32 [ 0, %2 ], [ %17, %21 ]
%.014 = phi ptr [ %0, %2 ], [ null, %21 ]
%4 = icmp slt i32 %.015, %1
br i1 %4, label %7, label %5
5: ; preds = %3
ret void
6: ; preds = %16, %9
call void @llvm.ubsantrap(i8 0)
unreachable
7: ; preds = %12, %3
%.0.in = phi i32 [ %.0, %12 ], [ %.015, %3 ]
%8 = icmp slt i32 %.0.in, %1
br i1 %8, label %12, label %9
9: ; preds = %7
%10 = ptrtoint ptr %.014 to i64
%11 = sext i32 %1 to i64
%.not = icmp ult i64 %10, %11
br i1 %.not, label %6, label %16
12: ; preds = %7
%.0 = add i32 %.0.in, 1
%13 = load i8, ptr %0, align 1
%14 = sext i32 %.0.in to i64
%15 = getelementptr i8, ptr %.014, i64 %14
store i8 %13, ptr %15, align 1
br label %7
16: ; preds = %9
%17 = add i32 %.015, 1
%18 = ptrtoint ptr %.016 to i64
%19 = xor i64 %18, -1
%20 = sext i32 %17 to i64
%.not1 = icmp ult i64 %19, %20
br i1 %.not1, label %6, label %21
21: ; preds = %16
%22 = getelementptr nusw i8, ptr %.016, i64 %20
br label %3
}
attributes #0 = { optsize }
attributes #1 = { cold noreturn nounwind memory(inaccessiblemem: write) }
```
Output:
```
opt: /root/llvm-project/llvm/include/llvm/ADT/DenseMap.h:1223: llvm::DenseMapIterator::value_type& llvm::DenseMapIterator::operator*() const [with KeyT = const llvm::Loop*; ValueT = llvm::ScalarEvolution::BackedgeTakenInfo; KeyInfoT = llvm::DenseMapInfo; Bucket = llvm::detail::DenseMapPair; bool IsConst = false; llvm::DenseMapIterator::reference = llvm::detail::DenseMapPair&; llvm::DenseMapIterator::value_type = llvm::detail::DenseMapPair]: Assertion `Ptr != End && "dereferencing end() iterator"' 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 -S -O3
1. Running pass "require,function(invalidate),require,cgscc(devirt<4>(inline,function-attrs,argpromotion,openmp-opt-cgscc,function(sroa,early-cse,speculative-execution,jump-threading,correlated-propagation,simplifycfg,instcombine,aggressive-instcombine,libcalls-shrinkwrap,tailcallelim,simplifycfg,reassociate,constraint-elimination,loop-mssa(loop-instsimplify,loop-simplifycfg,licm,loop-rotate,licm,simple-loop-unswitch),simplifycfg,instcombine,loop(loop-idiom,indvars,extra-simple-loop-unswitch-passes,loop-deletion,loop-unroll-full),sroa,vector-combine,mldst-motion,gvn<>,sccp,bdce,instcombine,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm),coro-elide,simplifycfg,instcombine),function-attrs,function(require),coro-split,coro-annotation-elide)),function(invalidate),cgscc(devirt<4>())" on module ""
2. Running pass "cgscc(devirt<4>(inline,function-attrs,argpromotion,openmp-opt-cgscc,function(sroa,early-cse,speculative-execution,jump-threading,correlated-propagation,simplifycfg,instcombine,aggressive-instcombine,libcalls-shrinkwrap,tailcallelim,simplifycfg,reassociate,constraint-elimination,loop-mssa(loop-instsimplify,loop-simplifycfg,licm,loop-rotate,licm,simple-loop-unswitch),simplifycfg,instcombine,loop(loop-idiom,indvars,extra-simple-loop-unswitch-passes,loop-deletion,loop-unroll-full),sroa,vector-combine,mldst-motion,gvn<>,sccp,bdce,instcombine,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm),coro-elide,simplifycfg,instcombine),function-attrs,function(require),coro-split,coro-annotation-elide))" on module ""
3. Running pass "loop(loop-idiom,indvars,extra-simple-loop-unswitch-passes,loop-deletion,loop-unroll-full)" on function "dav1d_init_qm_tables"
#0 0x0000000005ce2c38 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5ce2c38)
#1 0x0000000005cdfa64 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5cdfa64)
#2 0x0000000005cdfbda SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0x00007bd44de42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
#4 0x00007bd44de969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
#5 0x00007bd44de42476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
#6 0x00007bd44de287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
#7 0x00007bd44de2871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
#8 0x00007bd44de39e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#9 0x00000000052c76e2 llvm::ScalarEvolution::getBackedgeTakenInfo(llvm::Loop const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c76e2)
#10 0x00000000052e8bd2 llvm::ScalarEvolution::getBackedgeTakenCount(llvm::Loop const*, llvm::ScalarEvolution::ExitCountKind) (.constprop.0) ScalarEvolution.cpp:0:0
#11 0x00000000052f0e3e llvm::ScalarEvolution::computeSCEVAtScope(llvm::SCEV const*, llvm::Loop const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52f0e3e)
#12 0x00000000052f1294 llvm::ScalarEvolution::getSCEVAtScope(llvm::SCEV const*, llvm::Loop const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52f1294)
#13 0x00000000052c4663 llvm::ScalarEvolution::computeExitLimitFromICmp(llvm::Loop const*, llvm::CmpPredicate, llvm::SCEVUseT, llvm::SCEVUseT, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c4663)
#14 0x00000000052e2b21 llvm::ScalarEvolution::computeExitLimitFromICmp(llvm::Loop const*, llvm::ICmpInst*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52e2b21)
#15 0x00000000052c57c2 llvm::ScalarEvolution::computeExitLimitFromCondImpl(llvm::ScalarEvolution::ExitLimitCache&, llvm::Loop const*, llvm::Value*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c57c2)
#16 0x00000000052c5b93 llvm::ScalarEvolution::computeExitLimitFromCondCached(llvm::ScalarEvolution::ExitLimitCache&, llvm::Loop const*, llvm::Value*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c5b93)
#17 0x00000000053065e2 llvm::ScalarEvolution::computeExitLimitFromCondFromBinOp(llvm::ScalarEvolution::ExitLimitCache&, llvm::Loop const*, llvm::Value*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x53065e2)
#18 0x00000000052c53ea llvm::ScalarEvolution::computeExitLimitFromCondImpl(llvm::ScalarEvolution::ExitLimitCache&, llvm::Loop const*, llvm::Value*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c53ea)
#19 0x00000000052c5b93 llvm::ScalarEvolution::computeExitLimitFromCondCached(llvm::ScalarEvolution::ExitLimitCache&, llvm::Loop const*, llvm::Value*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c5b93)
#20 0x00000000052c5ccf llvm::ScalarEvolution::computeExitLimitFromCond(llvm::Loop const*, llvm::Value*, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c5ccf)
#21 0x00000000052c5f08 llvm::ScalarEvolution::computeExitLimit(llvm::Loop const*, llvm::BasicBlock*, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c5f08)
#22 0x00000000052c628a llvm::ScalarEvolution::computeBackedgeTakenCount(llvm::Loop const*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c628a)
#23 0x00000000052c738d llvm::ScalarEvolution::getBackedgeTakenInfo(llvm::Loop const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52c738d)
#24 0x00000000052e8405 llvm::ScalarEvolution::getBackedgeTakenCount(llvm::Loop const*, llvm::ScalarEvolution::ExitCountKind) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52e8405)
#25 0x000000000493705e (anonymous namespace)::IndVarSimplify::predicateLoopExits(llvm::Loop*, llvm::SCEVExpander&) IndVarSimplify.cpp:0:0
#26 0x000000000493d2e6 (anonymous namespace)::IndVarSimplify::run(llvm::Loop*) IndVarSimplify.cpp:0:0
#27 0x000000000493f600 llvm::IndVarSimplifyPass::run(llvm::Loop&, llvm::AnalysisManager&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x493f600)
#28 0x0000000002edae2e llvm::detail::PassModel, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2edae2e)
#29 0x00000000049e54d6 std::optional llvm::PassManager, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runSinglePass, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>>>>(llvm::Loop&, std::unique_ptr, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>>>&, llvm::AnalysisManager&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&, llvm::PassInstrumentation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x49e54d6)
#30 0x00000000049e567f llvm::PassManager, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runWithoutLoopNestPasses(llvm::Loop&, llvm::AnalysisManager&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x49e567f)
#31 0x00000000049e6cd4 llvm::PassManager, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x49e6cd4)
#32 0x00000000049e7d0f llvm::FunctionToLoopPassAdaptor::run(llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x49e7d0f)
#33 0x0000000000f34b7e llvm::detail::PassModel>::run(llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xf34b7e)
#34 0x0000000005a42916 llvm::PassManager>::run(llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5a42916)
#35 0x0000000000f3599e llvm::detail::PassModel>, llvm::AnalysisManager>::run(llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xf3599e)
#36 0x0000000005042a33 llvm::CGSCCToFunctionPassAdaptor::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5042a33)
#37 0x0000000000f346fe llvm::detail::PassModel, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xf346fe)
#38 0x000000000503b43e llvm::PassManager, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x503b43e)
#39 0x0000000003229ebe llvm::detail::PassModel, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>, llvm::AnalysisManager, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3229ebe)
#40 0x000000000503f906 llvm::DevirtSCCRepeatedPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x503f906)
#41 0x0000000003229ede llvm::detail::PassModel, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3229ede)
#42 0x000000000503ca39 llvm::ModuleToPostOrderCGSCCPassAdaptor::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x503ca39)
#43 0x0000000000f346de llvm::detail::PassModel>::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xf346de)
#44 0x0000000005a44476 llvm::PassManager>::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5a44476)
#45 0x00000000034df643 llvm::ModuleInlinerWrapperPass::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x34df643)
#46 0x0000000002edae5e llvm::detail::PassModel>::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2edae5e)
#47 0x0000000005a44476 llvm::PassManager>::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5a44476)
#48 0x00000000009756da llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef, llvm::ArrayRef>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x9756da)
#49 0x000000000096977f optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x96977f)
#50 0x00007bd44de29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#51 0x00007bd44de29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#52 0x000000000095ec65 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x95ec65)
```
It crashes at least as far back as LLVM 19.1.0 (https://godbolt.org/z/z9KGzcM7T). The test case is not compatible with 18.1.0 because 'getelementptr nusw' is unsupported; if I remove the 'nusw' qualifier, the test case passes both at 18.1.0 and trunk.
I tried to reduce the test case to use a specific pass instead of -O3, but skill issue.
Contributor guide
Research direction
Reproduce the crash with opt -O3 using the reduced LLVM IR from the issue. Start in llvm/lib/Analysis/ScalarEvolution.cpp at ScalarEvolution::getBackedgeTakenInfo and inspect the DenseMap assertion in llvm/include/llvm/ADT/DenseMap.h; done means opt completes successfully on this reproducer without dereferencing an end iterator.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100