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

            Bug ID: 127422
           Summary: [AArch64] -fcompare-debug failure in combine when a
                    DEBUG_INSN retains a volatile MEM -
           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 65601
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65601&action=edit
Standalone AArch64 C testcase

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

Tested revision:

2c3724c84c139c70c034816cc37f5dfb7f256815

Command:

aarch64-linux-gnu-gcc -std=gnu11 -w -O2 -mno-track-speculation \
  -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.

The ordinary RTL is identical between the two profiles through ext_dce and
first differs in combine. The relevant sequence contains two volatile loads.
After Combine folds the second load into its consumer and deletes the ordinary
load, the no-debug profile can retry and combine the first load.

With variable tracking enabled, propagate_for_debug retains the deleted second
load's volatile MEM in a DEBUG_INSN. can_combine_p then scans the open interval
using raw INSN_P membership:

  for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
    if (INSN_P (p) && p != succ && p != succ2
        && is_volatile_p (PATTERN (p)))
      return false;

Because INSN_P includes DEBUG_INSN, the non-executing debug value is treated
as another volatile access and blocks the retry. At that point the debug
instruction is the only volatile reference in the interval; there is no
ordinary volatile instruction there.

As a causal check, changing only this membership test from INSN_P to
NONDEBUG_INSN_P has the following results:

- the debug retry changes from rejected to allowed;
- -fcompare-debug changes from failure to success;
- the no-debug output is unchanged; and
- the debug output becomes identical to that no-debug output.

Expected result: debug-only instructions must not act as operational volatile
accesses or change the generated ordinary code.

Reply via email to