[Xtensa] Segfault in LiveVariables::HandleVirtRegUse at -O1 with invoke and landingpad cleanup
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
This was reduced by Claude. Note that the original IR didn't invoke null. llvm-reduce truncated the actual function and reduced it to null. This just looks like an unremarkable function call...
I'd ask if exceptions are just TODO (an error message would be better than a crash), but it builds with -O0, so it seems the support is there.
## Summary
`llc` crashes with a segmentation fault on the Xtensa target at `-O1` when processing a function containing an `invoke` of a null function pointer with a `landingpad cleanup` unwind destination. The crash occurs in `LiveVariables::HandleVirtRegUse` during the "Live Variable Analysis" pass. The same IR compiles successfully at `-O0` and on other targets (x86_64, aarch64) at `-O1`.
## Reproducer
```llvm
; crash.ll
target datalayout = "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32"
target triple = "xtensa-unknown-none-elf"
define { ptr, i32 } @test() personality ptr null {
else:
invoke void null({ i32, ptr } zeroinitializer, i32 0)
to label %postinvoke unwind label %landingPad
postinvoke:
unreachable
landingPad:
%0 = landingpad { ptr, i32 }
cleanup
ret { ptr, i32 } %0
}
```
**Crash command:**
```
$ llc -O1 crash.ll -o /dev/null
```
**No crash:**
```
$ llc -O0 crash.ll -o /dev/null # succeeds
$ llc -O1 -mtriple=x86_64 crash.ll -o /dev/null # succeeds
```
## Stack trace
```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: llc-21 -O1 crash.ll -o /dev/null
1. Running pass 'Function Pass Manager' on module 'crash.ll'.
2. Running pass 'Live Variable Analysis' on function '@test'
#0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
#1 llvm::sys::RunSignalHandlers()
#4 llvm::LiveVariables::HandleVirtRegUse(llvm::Register, llvm::MachineBasicBlock*, llvm::MachineInstr&)
#5 llvm::LiveVariables::runOnInstr(llvm::MachineInstr&, llvm::SmallVectorImpl&, unsigned int)
#6 llvm::LiveVariables::runOnBlock(llvm::MachineBasicBlock*, unsigned int)
#7 llvm::LiveVariables::analyze(llvm::MachineFunction&)
#9 llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
#10 llvm::FPPassManager::runOnFunction(llvm::Function&)
#11 llvm::FPPassManager::runOnModule(llvm::Module&)
#12 llvm::legacy::PassManagerImpl::run(llvm::Module&)
```
## Environment
- LLVM version: 21.1.8
- Target: xtensa-unknown-none-elf
- Host: x86_64-pc-linux-gnu
- Found via LDC (the LLVM-based D compiler) 1.42.0 cross-compiling to ESP32-S3
## Analysis
The Xtensa backend's instruction selection for `invoke null` with a landing pad appears to produce machine IR with a virtual register use that has no corresponding definition. When the `LiveVariables` pass encounters this undefined virtual register at `-O1`, it dereferences a null entry in its VirtRegInfo map, causing the segfault.
At `-O0` the crash does not occur, likely because the code path through instruction selection differs (no optimisation-dependent lowering of the invoke/landingpad pair), or because the LiveVariables pass is not run.
This was reduced from a real-world codebase (an IoT router written in D) using `llvm-reduce`. The original function (`Variant.insert`) generates this IR pattern through D's `assert` mechanism, which uses `invoke` for cleanup-guarded calls.
Contributor guide
Assessment
This issue has not been assessed yet.