https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127796
Bug ID: 127796
Summary: [SPARC] DEBUG_INSN between consecutive labels makes -g
redirect jumps differently
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: yqtian668 at gmail dot com
Target Milestone: ---
Host: x86_64-pc-linux-gnu
Target: sparc-unknown-elf
Build: x86_64-pc-linux-gnu
GCC's existing `gcc.c-torture/compile/pr110705-1.c` test produces different
post-delay-slot-scheduling output with `-g` and `-g0` on SPARC when variable
tracking is disabled. This reproduces on GCC trunk at revision
`54e232d0d4752b419ed775bdad50d83798fa899d` with GCC 17.0.0 20261009. The
affected `skip_consecutive_labels` implementation remains unchanged on master
revision `59e5dcee5375614cf1cc58e97dcc04f63bc9b519`.
## Reproducer
Using a `sparc-elf` compiler built from that revision:
```
$ sparc-elf-gcc -O1 -w -fno-var-tracking -fcompare-debug -S \
gcc/testsuite/gcc.c-torture/compile/pr110705-1.c
cc1: error: ...: '-fcompare-debug' failure (length)
```
The same source also reproduces when copied unchanged out of the testsuite.
## Actual behavior
The `-g` and `-g0` assemblies have different branch targets and label counts.
After label names are erased, their executable instructions are identical, so
this report is about debug information changing delay-slot reorganization, not
about a known runtime miscompilation.
The first differing pass is `dbr`. Before that pass, the relevant instruction
streams differ only by a debug marker between two labels. With `-g0`,
`relax_delay_slots` redirects the jump to the last label in the group and the
first label is deleted. With `-g`, the debug marker hides the later label, so
the jump keeps the first label.
## Cause
`skip_consecutive_labels` in `gcc/reorg.cc` stops at every `INSN_P`:
```c
for (insn = label;
insn != 0 && !INSN_P (insn) && !BARRIER_P (insn);
insn = NEXT_INSN (insn))
```
`INSN_P` is true for a `DEBUG_INSN`, even though a debug instruction should not
be an executable boundary when choosing among consecutive labels.
The reproducer is SPARC because that target exercises this path, but
`skip_consecutive_labels` is part of GCC's generic delay-slot reorganization
code rather than the SPARC backend.
This is related to PR rtl-optimization/127725, but that report covers different
sites in `optimize_skip`, `get_label_before`, and `fill_slots_from_thread`. It
does not cover `skip_consecutive_labels`. A Bugzilla duplicate search was
refreshed on 2026-10-10 and found no report for this site.
## Proposed fix
Changing the condition to `!NONDEBUG_INSN_P (insn)` makes both builds choose
the same label. A patch and a focused `gcc.target/sparc` `-fcompare-debug` test
are prepared. The test fails before the change and passes after it.
The patch passes `contrib/check_GNU_style.sh` and `git diff --check`. A native
x86_64 build containing this fix and three sibling delay-slot fixes completed
bootstrap and the full testsuite. After normalizing the build-directory path
embedded in one module test name, all 541,492 baseline and combined-patch
test-result records were identical.