Runtime loop unrolling hits a MemorySSA assertion
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
While doing some Julia/Enzyme work, I came across the following crash:
https://godbolt.org/z/q5KxjqP7a
Running: `opt -passes=loop-unroll -unroll-runtime -unroll-count=4` with an assertion build
```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-linux-gnu"
define void @f(ptr %p, ptr %q, i64 %n) {
entry:
; a dominating store with !invariant.group, OUTSIDE the loop
store i64 0, ptr %p, align 8, !invariant.group !0
br label %loop
loop:
%i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
%v = load i64, ptr %p, align 8, !invariant.group !0
%qi = getelementptr inbounds i64, ptr %q, i64 %i
store i64 %v, ptr %qi, align 8 ; bumps loadCSE's generation
%i.next = add nuw nsw i64 %i, 1
%c = icmp slt i64 %i.next, %n
br i1 %c, label %loop, label %exit
exit:
ret void
}
!0 = distinct !{}
```
leads to"
```
opt: /root/llvm-project/llvm/lib/Analysis/MemorySSA.cpp:2544: llvm::MemoryAccess* llvm::MemorySSA::ClobberWalkerBase::getClobberingMemoryAccessBase(llvm::MemoryAccess*, llvm::BatchAAResults&, unsigned int&, bool, bool): Assertion `ClobberMA' 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=loop-unroll -unroll-runtime -unroll-count=4
1. Running pass "function(loop-unroll)" on module ""
2. Running pass "loop-unroll" on function "f"
#0 0x0000000005c8f2d8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5c8f2d8)
#1 0x0000000005c8c534 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5c8c534)
#2 0x0000000005c8c6ae SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0x00007e0113845330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#4 0x00007e011389ec0c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9ec0c)
#5 0x00007e011384527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#6 0x00007e01138288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#7 0x00007e011382881b (/lib/x86_64-linux-gnu/libc.so.6+0x2881b)
#8 0x00007e011383b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)-passes=loop-unroll -unroll-runtime -unroll-count=4
#9 0x00000000051a1f16 llvm::MemorySSA::ClobberWalkerBase::getClobberingMemoryAccessBase(llvm::MemoryAccess*, llvm::BatchAAResults&, unsigned int&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x51a1f16)
#10 0x00000000051a3ac5 llvm::MemorySSA::CachingWalker::getClobberingMemoryAccess(llvm::MemoryAccess*, llvm::BatchAAResults&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x51a3ac5)
#11 0x0000000004e22cec getMatchingValue(LoadValue, llvm::LoadInst*, unsigned int, llvm::BatchAAResults&, llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4e22cec)
#12 0x0000000004e26b9b loadCSE(llvm::Loop*, llvm::DominatorTree&, llvm::ScalarEvolution&, llvm::LoopInfo&, llvm::BatchAAResults&, llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4e26b9b)
#13 0x0000000004e27fe7 llvm::simplifyLoopAfterUnroll(llvm::Loop*, bool, llvm::LoopInfo*, llvm::ScalarEvolution*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::TargetTransformInfo const*, llvm::ArrayRef, llvm::AAResults*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4e27fe7)
#14 0x0000000004e2d55e llvm::UnrollLoop(llvm::Loop*, llvm::UnrollLoopOptions, llvm::LoopInfo*, llvm::ScalarEvolution*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::TargetTransformInfo const*, llvm::OptimizationRemarkEmitter*, bool, llvm::Loop**, llvm::AAResults*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4e2d55e)
#15 0x00000000049e9821 tryToUnrollLoop(llvm::Loop*, llvm::DominatorTree&, llvm::LoopInfo*, llvm::ScalarEvolution&, llvm::TargetTransformInfo const&, llvm::AssumptionCache&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::ProfileSummaryInfo*, bool, int, bool, bool, bool, bool, std::optional, std::optional, std::optional, std::optional, std::optional, std::optional, std::optional, llvm::GenericUniformityInfo>*, llvm::AAResults*) LoopUnrollPass.cpp:0:0
#16 0x00000000049eca47 llvm::LoopUnrollPass::run(llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x49eca47)
#17 0x00000000030efa9e llvm::detail::PassModel>::runImpl(llvm::detail::PassConcept>&, llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x30efa9e)
#18 0x0000000005a0cdb1 llvm::PassManager>::run(llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5a0cdb1)
#19 0x0000000000ef34be llvm::detail::PassModel>, llvm::AnalysisManager>::runImpl(llvm::detail::PassConcept>&, llvm::Function&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xef34be)
#20 0x0000000005a0b9cc llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5a0b9cc)
#21 0x00000000008e82de llvm::detail::PassModel>::runImpl(llvm::detail::PassConcept>&, llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8e82de)
#22 0x0000000005a0b1be llvm::PassManager>::run(llvm::Module&, llvm::AnalysisManager&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5a0b1be)
#23 0x00000000008f1fbd 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+0x8f1fbd)
#24 0x00000000008e6335 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8e6335)
#25 0x00007e011382a1ca (/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
#26 0x00007e011382a28b __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
#27 0x00000000008dc365 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8dc365)
```
Contributor guide
Research direction
Reproduce the crash with the supplied LLVM IR and opt command, then inspect MemorySSA.cpp at getClobberingMemoryAccessBase and the loop-unroll/loadCSE stack entries. Determine why runtime unrolling reaches the failed assertion, and verify that the reproducer completes without an assertion, with regression coverage for the case.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 48/100