https://gcc.gnu.org/g:3cf0e6ab2aa9e7cb9a406079ff19856a6461d9f0

commit r15-6833-g3cf0e6ab2aa9e7cb9a406079ff19856a6461d9f0
Author: Maciej W. Rozycki <ma...@orcam.me.uk>
Date:   Sun Jan 12 16:48:53 2025 +0000

    Alpha: Restore frame pointer last in `builtin_longjmp' [PR64242]
    
    Add similar arrangements to `builtin_longjmp' for Alpha as with commit
    71b144289c1c ("re PR middle-end/64242 (Longjmp expansion incorrect)")
    and commit 511ed59d0b04 ("Fix PR64242 - Longjmp expansion incorrect"),
    so as to restore the frame pointer last, so that accesses to a local
    buffer supplied can still be fulfilled with memory accesses via the
    original frame pointer, fixing:
    
    FAIL: gcc.c-torture/execute/pr64242.c   -O0  execution test
    FAIL: gcc.c-torture/execute/pr64242.c   -O1  execution test
    FAIL: gcc.c-torture/execute/pr64242.c   -O2  execution test
    FAIL: gcc.c-torture/execute/pr64242.c   -O3 -g  execution test
    FAIL: gcc.c-torture/execute/pr64242.c   -Os  execution test
    FAIL: gcc.c-torture/execute/pr64242.c   -O2 -flto -fno-use-linker-plugin 
-flto-partition=none  execution test
    FAIL: gcc.c-torture/execute/pr64242.c   -O2 -flto -fuse-linker-plugin 
-fno-fat-lto-objects  execution test
    
    and adding no regressions in `alpha-linux-gnu' testing.
    
            gcc/
            PR middle-end/64242
            * config/alpha/alpha.md (`builtin_longjmp'): Restore frame
            pointer last.  Add frame clobber and schedule blockage.

Diff:
---
 gcc/config/alpha/alpha.md | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 35c8030422f5..178ce992206d 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -5005,14 +5005,28 @@
   rtx pv = gen_rtx_REG (Pmode, 27);
 
   /* This bit is the same as expand_builtin_longjmp.  */
+
   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
-  emit_move_insn (hard_frame_pointer_rtx, fp);
+
   emit_move_insn (pv, lab);
+
+  /* Restore the frame pointer and stack pointer.  We must use a
+     temporary since the setjmp buffer may be a local.  */
+  fp = copy_to_reg (fp);
   emit_stack_restore (SAVE_NONLOCAL, stack);
+
+  /* Ensure the frame pointer move is not optimized.  */
+  emit_insn (gen_blockage ());
+  emit_clobber (hard_frame_pointer_rtx);
+  emit_clobber (frame_pointer_rtx);
+  emit_move_insn (hard_frame_pointer_rtx, fp);
+
   emit_use (hard_frame_pointer_rtx);
   emit_use (stack_pointer_rtx);
 
+  /* End of the bit corresponding to expand_builtin_longjmp.  */
+
   /* Load the label we are jumping through into $27 so that we know
      where to look for it when we get back to setjmp's function for
      restoring the gp.  */

Reply via email to