for *a function with frame size >= 512 and there is outgoing area*,
aarch64 gcc is generate wrong .cfi_def_cfa_offset for the last
stack adjustment instruction in epiloue.

given a simple testcase

test.c
===
int
main (int argc, char **argv)
{
  char a[600];
  int b = 0x10;
  printf ("%d, %d, %d, %d, %d, %d, %d, %d\n", argc + 0, argc + 1, argc + 2,
          argc + 3, argc + 4, argc + 5, argc + 6, argc + 7);
  return 0;
}


gcc -O0 -g test.c

gdb ./a.out
(gdb) b main
(gdb) r
(gdb) b *0x0000000000400744
(break point at the end of the "main"
   0x000000000040073c <+204>:     ldp     x29, x30, [sp],#16
   0x0000000000400740 <+208>:     add     sp, sp, #0x280
   0x0000000000400744 <+212>:     ret  <--- *set a break point here*
)

(gdb) c
Breakpoint 2, 0x0000000000400744 in main (argc=-1693278018, argv=0x0) at 
hello.c:9
(gdb) p/x b
* $1 = 0 while $1 should be 0x10 *
(gdb)

all local variable access are wrong, because gcc generated wrong cfa adjustment

        add     sp, sp, 640      <--- A
        .cfi_def_cfa_offset 624  <--- B
        ret

after A, the cfa offset should be zero, so B should be

       .cfi_def_cfa_offset 0


no regression on aarch64-none-elf bare-metal full test.

ok for trunk?

thanks.

gcc/
  * config/aarch64/aarch64.c (aarch64_expand_epilogue): Remove redundant cfa 
offset update.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 2ea55e8..53d3fa1 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2551,11 +2551,6 @@ aarch64_expand_epilogue (bool for_sibcall)
 	      RTX_FRAME_RELATED_P (insn) = 1;
 	    }
 	}
-
-      aarch64_set_frame_expr (gen_rtx_SET (Pmode, stack_pointer_rtx,
-					   plus_constant (Pmode,
-							  stack_pointer_rtx,
-							  offset)));
     }

   emit_use (gen_rtx_REG (DImode, LR_REGNUM));

Reply via email to