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

            Bug ID: 127854
           Summary: PRU repeat-loop transformation treats debug
                    instructions as executable neighbours
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: yqtian668 at gmail dot com
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu
            Target: pru-unknown-elf
             Build: x86_64-pc-linux-gnu

Created attachment 65807
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65807&action=edit
patch

Four neighbour queries in gcc/config/pru/pru.cc use prev_real_insn or
next_real_insn while making PRU repeat-loop decisions. These helpers return
DEBUG_INSNs. A debug marker at each queried boundary can independently change
the generated code.

This reproduces with GCC master
9759f4fa7d01775298d8db581a36eef0baafb752 configured for pru-elf, using
-O2 -mloop -g2 -fno-var-tracking.

The four sites are:

  pru_repeat_loop_p: prev_real_insn (loop->end->label)
  pru_repeat_loop_p: next_real_insn (JUMP_LABEL_AS_INSN (end->fallthrough))
  pru_reorg_loop:    next_real_insn (insn)
  pru_reorg_loop:    next_real_insn (loop->end->insn)

Reproducer

The prepared multi-end-source.c is GCC's existing gcc.dg/pr121519.c test. The
four small .spec files place one DEBUG_INSN immediately before the mach pass.
They use the RTL mutation/projection method in repro.sh: the raw arm contains
the marker and the projected arm removes debug instructions while retaining
the same debug mode. trigger-2904.spec additionally needs the small
probe-afterbegin.patch on the Stutter GCC plugin so that its marker can be
placed immediately after the selected loop-end instruction.

Each site was isolated cumulatively:

  trigger-2768.spec: unpatched differs; changing 2768 alone makes it equal
  trigger-2839.spec: still differs after 2768; adding 2839 makes it equal
  trigger-2784.spec: still differs after 2768+2839; adding 2784 makes it equal
  trigger-2904.spec: still differs after the first three; adding 2904 makes it
equal

The original 2768 campaign carrier and reduced reproducer are also prepared as
source.c and trigger.spec.

Actual behavior

The first three markers can prevent conversion to a hardware LOOP, leaving a
software decrement and branch instead.

The 2904 marker has a potentially correctness-relevant effect. A marker
immediately after doloop_end makes next_real_insn stop before a used label, so
the pass omits the loop-guard NOP. The source comment says this NOP prevents a
loop break from naming the loop-end address and accidentally continuing the
hardware cycle. final-rtl-2904.diff shows the isolated missing NOP. I have not
runtime-tested this case on PRU hardware.

Expected behavior

Debug-only instructions should not affect repeat-loop eligibility, fallthrough
matching, or the used-label scan.

Root cause and candidate fix

The four queries use helpers that include debug instructions even though only
executing instructions matter. Replacing them with prev_real_nondebug_insn and
next_real_nondebug_insn makes all four raw/projected pairs equal. The prepared
fix.patch contains these four substitutions.

git diff --check and contrib/check_GNU_style.sh are clean. A serial
gcc.target/pru/pru.exp run has identical results before and after the patch
(131 PASS, 74 FAIL, 51 UNRESOLVED); the failures are baseline limitations of
this cross environment. A separate -O2 -mloop -g0 comparison over 3,714 C
torture files found no status or assembly differences.

Test coverage limitation

Current source lowering has not been observed to place a marker at these exact
late RTL boundaries, so the causal reproducers inject one immediately before
mach. I also tried to turn the pre-pass state into an embedded __RTL test, but
the PRU loop-end pattern stores the UNSPECV_LOOP_END value in a non-volatile
unspec. GCC's compact RTL reader resolves that operand through unspec_strings,
so it cannot round-trip this PRU loop-end form. I would appreciate guidance on
the preferred upstream regression-test form.

This is related to PR target/127460, which fixed a different debug-instruction
query in pru_insert_loop_label_last.

Reply via email to