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

            Bug ID: 128020
           Summary: [DebugInfo] AArch64: loop unrolling gives a stale
                    constant DWARF location for a loop counter
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: MrEven132 at outlook dot com
  Target Milestone: ---

With GCC 17.0.0 20261003 (experimental) and GDB 17.2 on AArch64, enabling loop
unrolling makes GDB print `i = 0` after the first loop iteration, although `i`
is 1 and the register holding its value is 1.  Disabling loop unrolling makes
GDB print `i = 1` at the same source line.

Test case (case.c):

    /* Reduced from gcc/testsuite/gcc.dg/guality/loop-1.c.  */
    void __attribute__((noipa, noinline))
    foo (int n)
    {
      if (n == 0)
        return;

      int i = 0;
      do
        {
          ++i;
        }
      while (i < n);

      /* Keep the final value live at a stable source-level inspection point. 
*/
      __asm__ volatile ("nop" : : "g" (i) : "memory");
    }

    int
    main (void)
    {
      foo (1);
      return 0;
    }

Build on AArch64:

    gcc -O3 -g -fno-tree-scev-cprop -fno-tree-vectorize -funroll-loops case.c
-o unrolled
    gcc -O3 -g -fno-tree-scev-cprop -fno-tree-vectorize -funroll-loops
-fno-unroll-loops case.c -o no-unroll

In separate GDB sessions, load each executable, break at case.c:16 (the
`__asm__ volatile ("nop" : : "g" (i) : "memory");` line), run, and print `i`. 
The call is `foo(1)`, so the loop has incremented `i` once before this line. 
With unrolling enabled, GDB prints `i = 0` while register `x5` is 1.  With
unrolling disabled, GDB prints `i = 1` while register `x1` is 1.

At case.c:16 in the unrolled executable, the DWARF location for `i` incorrectly
describes the variable as the constant zero:

    DW_OP_lit0, DW_OP_stack_value

At case.c:16 in the no-unroll executable, the DWARF location for `i` is
`DW_OP_reg1 W1`.  The unrolled location list appears to retain `i`'s initial
value beyond the increment, causing the stale GDB value.

Reply via email to