https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127688
Bug ID: 127688
Summary: -fcompare-debug failure when DEBUG_INSN changes
selective-scheduling issue-group markers
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: ---
Created attachment 65734
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65734&action=edit
input 1
GCC fails its `-fcompare-debug` check for two existing GCC tests when the
second scheduling pass uses selective scheduling. Both failures have the
same cause: a `DEBUG_INSN` changes which ordinary instructions receive the
`TImode` marker for the beginning of an issue group.
Tested revision:
```text
fc79df73ccd91f677c5990a3dadd83e2620404f9
gcc version 17.0.0 20260826 (experimental) (GCC)
```
The build was configured with:
```text
--target=x86_64-pc-linux-gnu --disable-bootstrap --enable-languages=c
--disable-multilib --disable-nls --disable-werror --enable-checking=yes
```
The smaller reproducer is the attached `gcc.dg/pr85423.c`:
```sh
xgcc -B/path/to/gcc -O2 -fselective-scheduling2 \
-fvar-tracking-assignments -fno-guess-branch-probability \
-fno-peephole2 -fno-ssa-phiopt -fno-tree-pre \
--param=max-jump-thread-duplication-stmts=8 -march=nano -w \
-fcompare-debug -c pr85423.c -o pr85423.o
```
Actual result:
```text
xgcc: error: pr85423.c: '-fcompare-debug' failure (length)
```
The attached `gcc.dg/pr80463.c` independently triggers the same failure and
root cause with its original options:
```sh
xgcc -B/path/to/gcc -g -O2 -fvar-tracking-assignments \
-fselective-scheduling2 -ftree-loop-vectorize \
-fnon-call-exceptions -fno-tree-vrp -fno-gcse-lm \
-fno-tree-loop-im -fno-reorder-blocks-and-partition \
-fno-reorder-blocks -fno-move-loop-invariants -w \
-fcompare-debug -c pr80463.c -o pr80463.o
```
For `pr85423.c`, the x86-64 `.text` section is byte-identical between `-g0`
and `-g`. The final RTL is not identical: three ordinary instructions lose
their `:TI` mode in the debug compilation. One representative difference is:
```diff
-(insn/f:TI ...
+(insn/f ...
```
The complete final-insns difference is attached. GCC documents in
`gcc/doc/rtl.texi` that the second Haifa scheduling pass sets an instruction
to `TImode` when it begins an issue group, and that later passes, especially
machine-dependent reorg, may rely on that marker.
The apparent cause is `put_TImodes()` in `gcc/sel-sched.cc`. Its loop skips
non-insn RTL but does not skip debug instructions:
```c++
if (!INSN_P (insn))
continue;
clock = INSN_SCHED_CYCLE (insn);
cost = (last_clock == -1) ? 1 : clock - last_clock;
...
last_clock = clock;
```
`DEBUG_INSN` satisfies `INSN_P`. A debug instruction can therefore update
`last_clock` for a new scheduling cycle. The following ordinary instruction
then has zero computed cost and does not receive the `TImode` marker that it
receives without debug information.
As a causal check, changing the membership test to
```c++
if (!INSN_P (insn) || DEBUG_INSN_P (insn))
continue;
```
makes both reproducers pass `-fcompare-debug`. For each reproducer, the
patched `-g0` `.text` is byte-identical to the unmodified `-g0` `.text`, and
the patched `-g` and `-g0` `.text` sections are byte-identical.
The diagnostic change is attached to document the causal check; it is not
intended to prescribe the final patch or its regression test.
The same `put_TImodes()` loop is still present in GCC master revision
`2e70e94cef1d76dbb3202d64184a7a8329c92f4e` by source inspection. The
execution results above are from the tested revision `fc79df73ccd9`.
Expected result: non-executable debug instructions should not consume an
issue-cycle transition or change issue-group markers on ordinary
instructions.