llvm / llvm/llvm-project

Runtime loop unrolling hits a MemorySSA assertion

Open
#222,852 1 comment 0 reactions 0 assignees View on GitHub
confirmed crash-on-valid julialang loopoptim regression:19
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.