llvm / llvm/llvm-project

[AMDGPU] [Miscompilation/Crash] opt -O3 crash in GenericUniformityAnalysisImpl::isTemporalDivergent during ReassociatePass

Open
#223,844 6 comments 0 reactions 0 assignees View on GitHub
confirmed crash-on-valid regression:23
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

## Summary

`opt -O3` segfaults inside `ReassociatePass` while querying `GenericUniformityAnalysisImpl::isTemporalDivergent` for an AMDGPU target. Reproduces on `-mcpu=gfx90a`, `-mcpu=gfx1100`, and `-mcpu=gfx1250`.

## opt version

```bash
# /opt/rocm/llvm/bin/opt --version
AMD LLVM version 24.0.0git
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: znver5
```

## Command to reproduce

```bash
/opt/rocm/llvm/bin/opt -O3 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a crash.ll -o /dev/null
/opt/rocm/llvm/bin/opt -O3 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 crash.ll -o /dev/null
```

Both crash identically. `crash.ll` is a `llvm-reduce`-minimized reproducer (43 lines) derived from a much larger module that failed to compile in the same way.

## Reproducer

```llvm
target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
target triple = "amdgpu9.0a-amd-amdhsa"

; Function Attrs: convergent nocallback nocreateundeforpoison nofree nounwind willreturn memory(none)
declare i64 @llvm.amdgcn.ballot.i64(i1) #0

define amdgpu_kernel void @test_typed_put_signal(ptr %0) {
tail call void @rocshmem_int_put_signal(ptr %0, ptr null, i64 0, ptr null, i64 0, i32 0, i32 0)
ret void
}

define void @rocshmem_int_put_signal(ptr %0, ptr %1, i64 %2, ptr %3, i64 %4, i32 %5, i32 %6) {
br label %.preheader.i.i17.i.i.i.i.i.i

.preheader.i.i17.i.i.i.i.i.i: ; preds = %.preheader.i.i17.i.i.i.i.i.i.backedge, %7
%.06.i.i.i.i.i.i.i.i.i = phi i64 [ 0, %7 ], [ %10, %.preheader.i.i17.i.i.i.i.i.i.backedge ]
%8 = phi i1 [ true, %7 ], [ false, %.preheader.i.i17.i.i.i.i.i.i.backedge ]
%9 = tail call i64 @llvm.amdgcn.ballot.i64(i1 %8)
%.not12.i.i.i.i.i.i.i.i.i = icmp eq i64 %9, 0
br i1 %.not12.i.i.i.i.i.i.i.i.i, label %_ZN8rocshmem12ActiveWFInfoC2EiNS_11ThreadScopeE.exit.i.i.i.i.i.i, label %.preheader.i.i17.i.i.i.i.i.i.backedge

.preheader.i.i17.i.i.i.i.i.i.backedge: ; preds = %.preheader.i.i17.i.i.i.i.i.i
%10 = tail call i64 @llvm.amdgcn.ballot.i64(i1 true)
br label %.preheader.i.i17.i.i.i.i.i.i

_ZN8rocshmem12ActiveWFInfoC2EiNS_11ThreadScopeE.exit.i.i.i.i.i.i: ; preds = %.preheader.i.i17.i.i.i.i.i.i
%11 = tail call i64 @llvm.amdgcn.ballot.i64(i1 true)
%12 = and i64 %.06.i.i.i.i.i.i.i.i.i, %11
%.not.i.i.i.i.i.i.i.i = icmp eq i64 %12, 0
call void @llvm.assume(i1 %.not.i.i.i.i.i.i.i.i)
%13 = load i64, ptr %0, align 8
%14 = ptrtoint ptr %0 to i64
%15 = or i64 %13, %14
%16 = or i64 %15, 1
store i64 %16, ptr addrspace(5) null, align 8
ret void
}

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write)
declare void @llvm.assume(i1 noundef) #1

attributes #0 = { convergent nocallback nocreateundeforpoison nofree nounwind willreturn memory(none) }
attributes #1 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
```

**Backtrace**:

```bash
# /opt/rocm/llvm/bin/opt -O3 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 /tmp/trimmed_gfx90a.reduced.ll -o /dev/null
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/rocm/llvm/bin/opt -O3 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 /tmp/trimmed_gfx90a.reduced.ll -o /dev/null
1. Running pass "require,function(invalidate),require,cgscc(devirt<4>(inline,inline,function-attrs,argpromotion,openmp-opt-cgscc,function(amdgpu-promote-kernel-arguments,infer-address-spaces,amdgpu-lower-kernel-attributes,amdgpu-promote-alloca-to-vector),function(sroa,early-cse,speculative-execution,jump-threading,correlated-propagation,jump-table-to-switch,simplifycfg,instcombine,aggressive-instcombine,libcalls-shrinkwrap,amdgpu-usenative,amdgpu-simplifylib,amdgpu-uniform-intrinsic-combine,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,amdgpu-usenative,amdgpu-simplifylib,amdgpu-uniform-intrinsic-combine,dfa-jump-threading,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm),coro-elide,infer-address-spaces,simplifycfg,instcombine,amdgpu-usenative,amdgpu-simplifylib,amdgpu-uniform-intrinsic-combine),function-attrs,function(require),coro-split,coro-annotation-elide)),function(invalidate),cgscc(devirt<4>())" on module "/tmp/trimmed_gfx90a.reduced.ll"
2. Running pass "cgscc(devirt<4>(inline,inline,function-attrs,argpromotion,openmp-opt-cgscc,function(amdgpu-promote-kernel-arguments,infer-address-spaces,amdgpu-lower-kernel-attributes,amdgpu-promote-alloca-to-vector),function(sroa,early-cse,speculative-execution,jump-threading,correlated-propagation,jump-table-to-switch,simplifycfg,instcombine,aggressive-instcombine,libcalls-shrinkwrap,amdgpu-usenative,amdgpu-simplifylib,amdgpu-uniform-intrinsic-combine,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,amdgpu-usenative,amdgpu-simplifylib,amdgpu-uniform-intrinsic-combine,dfa-jump-threading,jump-threading,correlated-propagation,adce,memcpyopt,dse,move-auto-init,loop-mssa(licm),coro-elide,infer-address-spaces,simplifycfg,instcombine,amdgpu-usenative,amdgpu-simplifylib,amdgpu-uniform-intrinsic-combine),function-attrs,function(require),coro-split,coro-annotation-elide))" on module "/tmp/trimmed_gfx90a.reduced.ll"
3. Running pass "reassociate" on function "test_typed_put_signal"
#0 0x000078444ce30161 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x719161)
#1 0x000078444ce2cd01 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#2 0x000078444c2b4330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#3 0x000078444f096404 llvm::GenericUniformityAnalysisImpl>::isTemporalDivergent(llvm::BasicBlock const&, llvm::Instruction const&) const (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x297f404)
#4 0x000078444e684a64 llvm::ReassociatePass::ReassociateExpression(llvm::BinaryOperator*) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x1f6da64)
#5 0x000078444e688733 llvm::ReassociatePass::runImpl(llvm::Function&, llvm::GenericUniformityInfo>&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x1f71733)
#6 0x000078444e689336 llvm::ReassociatePass::run(llvm::Function&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x1f72336)
#7 0x0000784450a12245 llvm::detail::PassModel>::runImpl(llvm::detail::PassConcept>&, llvm::Function&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x42fb245)
#8 0x000078444d06dfe6 llvm::PassManager>::run(llvm::Function&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x956fe6)
#9 0x000078444fe5cf95 llvm::detail::PassModel>, llvm::AnalysisManager>::runImpl(llvm::detail::PassConcept>&, llvm::Function&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x3745f95)
#10 0x000078444edf0b6f llvm::CGSCCToFunctionPassAdaptor::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x26d9b6f)
#11 0x000078444fe5cfe5 llvm::detail::PassModel, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::runImpl(llvm::detail::PassConcept, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>&, llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x3745fe5)
#12 0x000078444edea357 llvm::PassManager, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x26d3357)
#13 0x000078444e853e35 llvm::detail::PassModel, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>, llvm::AnalysisManager, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::runImpl(llvm::detail::PassConcept, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>&, llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x213ce35)
#14 0x000078444edee058 llvm::DevirtSCCRepeatedPass::run(llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x26d7058)
#15 0x000078444e853e85 llvm::detail::PassModel, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>::runImpl(llvm::detail::PassConcept, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&>&, llvm::LazyCallGraph::SCC&, llvm::AnalysisManager&, llvm::LazyCallGraph&, llvm::CGSCCUpdateResult&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x213ce85)
#16 0x000078444edec0c8 llvm::ModuleToPostOrderCGSCCPassAdaptor::run(llvm::Module&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x26d50c8)
#17 0x000078444e853ed5 llvm::detail::PassModel>::runImpl(llvm::detail::PassConcept>&, llvm::Module&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x213ced5)
#18 0x000078444d06c32b llvm::PassManager>::run(llvm::Module&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x95532b)
#19 0x000078444e856fc0 llvm::ModuleInlinerWrapperPass::run(llvm::Module&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x213ffc0)
#20 0x0000784450a0fa65 llvm::detail::PassModel>::runImpl(llvm::detail::PassConcept>&, llvm::Module&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x42f8a65)
#21 0x000078444d06c32b llvm::PassManager>::run(llvm::Module&, llvm::AnalysisManager&) (/opt/rocm/lib/llvm/bin/../lib/libLLVM.so.24.0git+0x95532b)
#22 0x000061dc756483d4 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/rocm/llvm/bin/opt+0x2a3d4)
#23 0x000061dc7563aed8 optMain (/opt/rocm/llvm/bin/opt+0x1ced8)
#24 0x000078444c2991ca (/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
#25 0x000078444c29928b __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
#26 0x000061dc75631365 _start (/opt/rocm/llvm/bin/opt+0x13365)
Segmentation fault (core dumped)
```

## Notes

- Discovered while building [rocSHMEM#11464](https://github.com/ROCm/rocm-systems/pull/11646)'s merged device-bitcode module (test_typed_put_signal), then reduced with `llvm-reduce` to the module above (43 lines).
- [AI:] The crash probably triggers specifically inside `reassociate`'s call into the new-pass-manager uniformity analysis (`isTemporalDivergent`) when reassociating an integer expression (`or/ptrtoint` chain) inside a kernel whose CFG has a convergent-ballot-guarded loop preheader (the `.preheader...backedge` self-loop above). Reassociate appears to query temporal divergence for a value/block combination that the analysis doesn't expect in this shape, and null-derefs rather than returning a defined answer.
- Reproduces identically on `gfx90a`, `gfx1100`, and `gfx1250`, so this looks target-independent (triggered by the AMDGPU divergence/uniformity analysis specifically, not a per-subtarget codegen issue).

Contributor guide

Open the contributing guide

Research direction

Reproduce the crash with the 43-line crash.ll LLVM IR and the provided opt -O3 commands for gfx90a and gfx1100. Start at ReassociatePass and GenericUniformityAnalysisImpl::isTemporalDivergent, using the backtrace as the entry point. Done means the reproducer no longer crashes and a regression test covers the failure.

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
Clearly specified
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.