llvm / llvm/llvm-project

[AArch64] Ignore debug instructions when placing the A53 workaround NOP

Open
#224,661 1 comment 0 reactions 0 assignees View on GitHub
backend:AArch64
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

[issue-reproducer.sh](https://github.com/user-attachments/files/32385895/issue-reproducer.sh)

A leading `DBG_LABEL` changes where the Cortex-A53 erratum 835769 workaround
places a NOP around a block boundary. The ordinary instruction sequence remains
`ldr; nop; madd`, but the debug build moves a block-address target across the
NOP. The target's object relocation addend changes from `.text+0x8` to
`.text+0x4`.

This reproduces with an assertions-enabled LLVM 24.0.0git build at revision
`54a71b0d38b63fc6df48fde0dc5ffd84b9f12a50` on x86-64 Linux. All `llc` runs
target AArch64 Cortex-A53 and use `-verify-machineinstrs`.

## Reproducer

https://godbolt.org/z/9WTba8joq

Attach `a53-debug-front.ll` and `issue-reproducer.sh`, then run:

[a53-debug-front.ll.txt](https://github.com/user-attachments/files/32385980/a53-debug-front.ll.txt)

[issue-reproducer.sh](https://github.com/user-attachments/files/32385984/issue-reproducer.sh)

```console
$ bash issue-reproducer.sh
```

The script compiles the input as written and after `opt --strip-debug`, prints
the relevant assembly, and prints the block-address relocations.

## Actual behavior

With the debug label present, the block-address relocations target
`.text+0x4`. After stripping debug information, they target `.text+0x8`.
An equivalent input without the debug label also targets `.text+0x8`.

Immediately before `AArch64A53Fix835769`, the variants have equal ordinary
Machine IR. The debug variant contributes one leading `DBG_LABEL` to the
block-address-taken block. Disabling the A53 workaround also makes the layouts
reconverge.

This report concerns debug-dependent machine-code layout in an erratum
workaround. It does not claim a runtime mismatch, re-triggering of the erratum,
or exploitability.

## Cause

The pass ignores pseudo instructions while detecting the load-to-`MADD`
sequence. Its insertion helper then compares the `MADD` with raw `MBB.front()`
to decide whether to put the NOP in the fallthrough predecessor or in the
current block. A leading `DBG_LABEL` changes that decision.

I have a candidate patch that compares against the first non-debug instruction
instead. Passing `SkipPseudoOp=false` preserves the existing placement behavior
for pseudo probes.

## Expected behavior

Debug-only instructions should not change which side of an ordinary block
target receives the workaround NOP.

Contributor guide

Open the contributing guide

Research direction

Start by running issue-reproducer.sh with aAArch64 Cortex-A53 target and compare the debug and stripped outputs, including block-address relocations. Read the AArch64A53Fix835769 pass and its insertion helper, focusing on DBG_LABEL handling and the MBB.front() comparison. Done means debug-only instructions no longer change which side receives the workaround NOP and the relocation output agrees across variants.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, shell
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.