llvm / llvm/llvm-project

[M68k] copyPhysReg passes DBG_LABEL to LiveRegUnits::stepBackward

Open
#221,632 1 comment 0 reactions 0 assignees View on GitHub
backend:m68k
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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.