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

            Bug ID: 128611
           Summary: __builtin_dwarf_cfa returns wrong address in a
                    DRAP-realigned frame
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ishevlyakov at gcc dot gnu.org
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu, i686-pc-linux-gnu

In a function whose frame is realigned through a DRAP (dynamic realign
argument pointer), __builtin_dwarf_cfa () does not return the CFA.

Testcase:

extern void abort (void);

__attribute__ ((noipa)) void
sink (volatile char *p)
{
  p[0] = 0;
}

__attribute__ ((noipa)) void *
plain (void)
{
  return __builtin_dwarf_cfa ();
}

__attribute__ ((noipa)) void *
realigned (void)
{
  volatile char buf[64] __attribute__ ((aligned (64)));
  sink (buf);
  return __builtin_dwarf_cfa ();
}

int
main (void)
{
  if (plain () != realigned ())
    abort ();
  return 0;
}

Both functions are called from the same frame in main, so they must see
the same CFA.

$ gcc -O2 -mforce-drap t.c && ./a.out      # x86_64: aborts
$ gcc -m32 -O2 t.c && ./a.out              # i686: aborts, no extra flag
                                           # needed (DRAP is used anyway)
$ gcc -O2 t.c && ./a.out                   # x86_64 without DRAP: passes

Fails at -O0 through -O3 and -Os; -mstackrealign does not matter.
Printing the two values (x86_64, -O2 -mforce-drap):

  plain=0x7ffe43872680 realigned=0x7ffe43872640

x86_64 -O2 -mforce-drap code for realigned():

        leaq    8(%rsp), %r10        # r10 = CFA (DRAP)
        andq    $-64, %rsp
        pushq   -8(%r10)             # copy of return address
        pushq   %rbp
        movq    %rsp, %rbp
        pushq   %r10
        ...
        leaq    16(%rbp), %rax       # "CFA" = argp eliminated via hard fp
        leave

The CFA should be %r10 (the DRAP).  What is returned instead is %rbp+16,
the address just above the copy of the return address pushed after
realignment, i.e. an address inside the realigned frame.
  • [Bug middle-end/128611] New: _... ishevlyakov at gcc dot gnu.org via Gcc-bugs

Reply via email to