https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127687
Bug ID: 127687
Summary: -fcompare-debug failure when GIMPLE_DEBUG splits
forwprop VEC_PERM sequence blending
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: yqtian668 at gmail dot com
Target Milestone: ---
Created attachment 65731
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65731&action=edit
input
GCC fails its `-fcompare-debug` check for the attached existing GCC testcase
`gcc.dg/pr123672.c` at `-O2`. Adding debug information also changes the final
x86-64 instruction sequence.
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
```
Command:
```sh
xgcc -B/path/to/gcc -O2 -fcompare-debug -c pr123672.c -o pr123672.o
```
Actual result:
```text
xgcc: error: pr123672.c: '-fcompare-debug' failure (length)
```
Compiling the source separately with `-g0` and `-g` produces different
`.text` sections. The full ordinary-instruction diff is attached as
`instructions-g0-vs-g.diff`. In particular, the `-g0` compilation blends the
two vector-permute sequences and uses two `shufps` instructions, whereas the
`-g` compilation keeps the sequences separate and uses four `pshufd`
instructions.
The first ordinary compiler-state difference occurs in forwprop. The
statement loop in `pass_forwprop::execute` accumulates simplifiable VEC_PERM
sequences and processes them as a list so that compatible pairs can be
blended. It currently processes that list at every non-assignment statement:
```c++
if (!is_gimple_assign (stmt))
{
process_vec_perm_simplify_seq_list (&vec_perm_simplify_seq_list);
gsi_next (&gsi);
continue;
}
```
A `GIMPLE_DEBUG` bind is not an assignment. With `-g`, a debug bind between
the two compatible sequences therefore processes the first sequence before
the second one is available, preventing the pair from being blended.
As a causal check, I made a diagnostic change that skips `GIMPLE_DEBUG`
statements before the non-assignment check. With only that change:
- `-fcompare-debug` passes;
- the patched `-g` and `-g0` `.text` sections are byte-identical; and
- the patched `-g0` `.text` is byte-identical to the unmodified `-g0` output.
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 non-assignment flush is still present in GCC master revision
`2e70e94cef1d76dbb3202d64184a7a8329c92f4e` by source inspection. The
execution results above are from the tested revision `fc79df73ccd9`.
This is distinct from PR tree-optimization/123672. That issue is the
wrong-code problem for which this testcase was originally added; the problem
reported here is the debug-dependent boundary in the later sequence-blending
logic.
Expected result: a non-executable debug bind should not end a pending
VEC_PERM sequence or change the generated ordinary code.