[M68k] copyPhysReg passes DBG_LABEL to LiveRegUnits::stepBackward
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
An assertions-enabled LLVM build aborts when the M68k backend compiles a
verifier-valid module containing one `#dbg_label` after a call that requires a
physical-register copy. The crash occurs in the Post-RA pseudo instruction
expansion pass:
```text
LiveRegUnits::stepBackward: Assertion `!MI.isDebugInstr() &&
"Debug instructions must not affect liveness calculation"' failed.
```
Removing only the `#dbg_label` makes the same module compile successfully.
The crash does not require `-verify-machineinstrs`.
The executable reproduction was performed with LLVM 24.0.0git at revision
`50d4fbcc610e478190408685f02fe5818779c154` on x86-64 Linux and revalidated at
`502e51aa4df687807fbe51fa0b419baf65e9615f`. The relevant
`M68kInstrInfo::copyPhysReg` loop remains unchanged on `main` at
`91d3532e2261e168e85ebcf5c5112419b47ef530`.
## Reproducer
The following files are attached individually. The LLVM IR file has a final
`.txt` suffix only because GitHub does not accept `.ll` uploads:
[crash.txt](https://github.com/user-attachments/files/31897116/crash.txt)
[reduced.ll.txt](https://github.com/user-attachments/files/31897117/reduced.ll.txt)
[reproduce.sh](https://github.com/user-attachments/files/31897115/reproduce.sh)
[reproducer.c](https://github.com/user-attachments/files/31897114/reproducer.c)
Run with an assertions-enabled build:
```bash
bash reproduce.sh
```
The script first checks the input with `llvm-as` and
`opt -passes=verify`. It also compiles a control produced by removing only the
`#dbg_label`.
Observed output:
```text
without #dbg_label status: 0
with #dbg_label status: 134
llc: ... LiveRegUnits::stepBackward ... Assertion `!MI.isDebugInstr() &&
"Debug instructions must not affect liveness calculation"' failed.
2. Running pass 'Post-RA pseudo instruction expansion pass' on function '@f'
```
The attached C file is a natural source carrier for the relevant
`call`/debug-label/`ret` shape. It was independently checked with:
```bash
clang -target m68k-unknown-linux-gnu -g -O1 -S -emit-llvm \
reproducer.c -o from-c.ll
llc -mtriple=m68k -O0 from-c.ll -o /dev/null
```
The direct and deterministic reproducer is `reduced.ll.txt`.
## Crash path
Immediately before Post-RA pseudo expansion, the relevant verifier-valid
Machine IR has this ordering:
```text
$a0 = COPY $sp
...
CALLb @consume
DBG_LABEL
$sp = frame-destroy ADD32ai $sp, 68
RET 0
```
The symbolized stack contains:
```text
llvm::LiveRegUnits::stepBackward(...)
llvm::M68kInstrInfo::copyPhysReg(...)
llvm::TargetInstrInfo::lowerCopy(...)
(anonymous namespace)::ExpandPostRA::run(...)
```
## Cause
`M68kInstrInfo::copyPhysReg` reconstructs liveness by walking backward from
the raw end of the `MachineBasicBlock` to the `COPY`:
```cpp
auto InstUpToI = MBB.end();
while (InstUpToI != MI) {
UsedRegs.stepBackward(*--InstUpToI);
}
```
This walk crosses the `DBG_LABEL` shown above and passes it to
`LiveRegUnits::stepBackward`, whose API explicitly rejects debug instructions.
This is the M68k analogue of the Thumb1 `copyPhysReg` crash fixed by
[#209478](https://github.com/llvm/llvm-project/pull/209478) for
[#209475](https://github.com/llvm/llvm-project/issues/209475). I did not find
an existing M68k issue or PR for this call site.
## Possible fix
Skipping debug instructions during the backward walk avoids the assertion:
```cpp
while (InstUpToI != MI) {
--InstUpToI;
if (InstUpToI->isDebugInstr())
continue;
UsedRegs.stepBackward(*InstUpToI);
}
```
I tested this change at `91d3532e2261e168e85ebcf5c5112419b47ef530`.
With the change, the reduced input passes `-verify-machineinstrs`; the original
baseline, `DBG_VALUE`, and `DBG_LABEL` variants also compile to identical
ordinary object-instruction projections. A corresponding M68k regression test
fails with the assertion on the unmodified build and passes with the change.
## Expected behavior and scope
Debug-only instructions should not be passed to the physical-register
liveness update. The module should compile successfully with or without the
debug label.
The confirmed impact is an assertions-enabled compiler crash. No
non-asserting-build miscompile or runtime impact is claimed.
## Current trunk validation
The attached `reproduce.sh` was rerun successfully in an isolated assertions-enabled build of LLVM `main` at revision `502e51aa4df687807fbe51fa0b419baf65e9615f`:
```text
without #dbg_label status: 0
with #dbg_label status: 134
llc: /path/to/llvm-project/llvm/lib/CodeGen/LiveRegUnits.cpp:45: void llvm::LiveRegUnits::stepBackward(const llvm::MachineInstr&): Assertion `!MI.isDebugInstr() && "Debug instructions must not affect liveness calculation"' failed.
2. Running pass 'Post-RA pseudo instruction expansion pass' on function '@f'
Contributor guide
Research direction
Start with M68kInstrInfo::copyPhysReg and run the attached reproduce.sh using reduced.ll.txt in an assertions-enabled build. Compare the DBG_LABEL and control cases, then add the corresponding M68k regression test; done means both compile successfully without the LiveRegUnits assertion and the existing checks pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100