https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127421

            Bug ID: 127421
           Summary: [SPARC] -fcompare-debug failure because DEBUG_INSNs
                    consume redundant_insn search budget -
           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: ---
            Target: sparc-elf

Created attachment 65600
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65600&action=edit
Standalone SPARC C testcase

GCC trunk fails its -fcompare-debug check for the attached standalone C
testcase when targeting SPARC V8.

Tested revision:

2c3724c84c139c70c034816cc37f5dfb7f256815

Command:

sparc-elf-gcc -std=gnu11 -O2 -mcpu=v8 \
  -fno-var-tracking -fno-var-tracking-assignments \
  -fno-asynchronous-unwind-tables \
  --param=max-delay-slot-insn-search=8 -fcompare-debug -S repro.c

Actual result:

xgcc: error: repro.c: '-fcompare-debug' failure (length)

The testcase is header-free and does not require Csmith or a target sysroot.

In both bounded backwards walks in reorg.cc::redundant_insn, the search
budget is decremented for every INSN_P before DEBUG_INSN is rejected. The
relevant ordering is equivalent to:

  if (!INSN_P (trial))
    continue;
  --insns_to_search;

  /* Other checks. */

  if (GET_CODE (trial) == DEBUG_INSN)
    continue;

The debug instructions therefore consume
param_max_delay_slot_insn_search, even though they cannot execute. With a
budget of eight, the debug walk fails to reach a repeated ordinary
instruction that the no-debug walk reaches. This changes the delay-slot
decision and the final ordinary assembly.

A same-debug instrumentation check gives identical normalized RTL immediately
before delayed-branch scheduling when debug instructions are projected out.
Changing only the search walk to avoid charging DEBUG_INSN changes the
redundant_insn result and makes the post-pass ordinary RTL agree. Fourteen
independently generated variants reproduce the same causal chain; outside-loop
and no-guard controls do not.

Source history points to r193829, commit
90251a6208237554814599ed36126cd63bfe9dc6 (2012-11-26). That change was
titled "reorg.c (redundant_insn): Do not handle DEBUG_INSNs" and changed both
walks from NONDEBUG_INSN_P to INSN_P. Because the decrement occurs before the
later debug-instruction check, the change made debug instructions consume the
finite search budget.

I confirmed the failure on the tested trunk revision above. I have not
compiled every historical release, so I am not claiming an exact affected
release range.

Expected result: debug-only instructions should be skipped without consuming
the ordinary-instruction search budget, and -fcompare-debug should succeed.

Historical commit:
https://github.com/gcc-mirror/gcc/commit/90251a6208237554814599ed36126cd63bfe9dc6

Reply via email to