The attached change fixes PR middle-end/64242 on hppa.  The nonlocal_goto and
builtin_longjmp expanders are reworked to restore the frame pointer last.  
Clobbers
and a blockage are added to ensure the restored frame pointer is not used to 
restore
the stack pointer and the branch address.

Tested on hppa-unknown-linux-gnu and hppa2.0w-hp-hpux11.11.  Committed to trunk.

Dave
-- 
John David Anglin  dave.ang...@bell.net

2019-06-16  John David Anglin  <dang...@gcc.gnu.org>

        PR middle-end/64242
        * config/pa/pa.md (nonlocal_goto): Restore frame pointer last.  Add
        frame clobbers and schedule block.
        (builtin_longjmp): Likewise.

Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md     (revision 272327)
+++ config/pa/pa.md     (working copy)
@@ -6904,21 +6904,24 @@
   rtx stack = operands[2];
   rtx fp = operands[3];

-  lab = copy_to_reg (lab);
-
   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));

-  /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
-     instead of the hard_frame_pointer_rtx in the save area.  As a
-     result, an extra instruction is needed to adjust for the offset
+  lab = copy_to_reg (lab);
+
+  /* Restore the stack and frame pointers.  The virtual_stack_vars_rtx
+     is saved instead of the hard_frame_pointer_rtx in the save area.
+     As a result, an extra instruction is needed to adjust for the offset
      of the virtual stack variables and the hard frame pointer.  */
-  if (GET_CODE (fp) != REG)
-    fp = force_reg (Pmode, fp);
+  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, plus_constant (Pmode, fp, -8));

-  emit_stack_restore (SAVE_NONLOCAL, stack);
-
   emit_use (hard_frame_pointer_rtx);
   emit_use (stack_pointer_rtx);

@@ -8695,23 +8698,26 @@
   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));

-  /* Restore the frame pointer.  The virtual_stack_vars_rtx is saved
-     instead of the hard_frame_pointer_rtx in the save area.  We need
-     to adjust for the offset between these two values.  */
-  if (GET_CODE (fp) != REG)
-    fp = force_reg (Pmode, fp);
+  /* Load the label we are jumping through into r1 so that we know
+     where to look for it when we get back to setjmp's function for
+     restoring the gp.  */
+  emit_move_insn (pv, lab);
+
+  /* Restore the stack and frame pointers.  The virtual_stack_vars_rtx
+     is saved instead of the hard_frame_pointer_rtx in the save area.
+     We need to adjust for the offset between these two values.  */
+  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, plus_constant (Pmode, fp, -8));

-  /* This bit is the same as expand_builtin_longjmp.  */
-  emit_stack_restore (SAVE_NONLOCAL, stack);
   emit_use (hard_frame_pointer_rtx);
   emit_use (stack_pointer_rtx);

-  /* Load the label we are jumping through into r1 so that we know
-     where to look for it when we get back to setjmp's function for
-     restoring the gp.  */
-  emit_move_insn (pv, lab);
-
   /* Prevent the insns above from being scheduled into the delay slot
      of the interspace jump because the space register could change.  */
   emit_insn (gen_blockage ());

Reply via email to