re PR middle-end/64242 (Longjmp expansion incorrect)
authorJohn David Anglin <danglin@gcc.gnu.org>
Sun, 16 Jun 2019 21:27:14 +0000 (21:27 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Sun, 16 Jun 2019 21:27:14 +0000 (21:27 +0000)
PR middle-end/64242
* config/pa/pa.md (nonlocal_goto): Restore frame pointer last.  Add
frame clobbers and schedule block.
(builtin_longjmp): Likewise.

From-SVN: r272361

gcc/ChangeLog
gcc/config/pa/pa.md

index 1b7528b..369ca4b 100644 (file)
@@ -1,3 +1,10 @@
+2019-06-16  John David Anglin  <danglin@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.
+
 2019-06-16  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
 
        * config/msp430/msp430.c (msp430_expand_helper): Setup arguments which
index 8308b37..84630ad 100644 (file)
   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
-     of the virtual stack variables and the hard frame pointer.  */
-  if (GET_CODE (fp) != REG)
-    fp = force_reg (Pmode, fp);
-  emit_move_insn (hard_frame_pointer_rtx, plus_constant (Pmode, fp, -8));
+  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.  */
+  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_use (hard_frame_pointer_rtx);
   emit_use (stack_pointer_rtx);
 
@@ -8695,23 +8698,26 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   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);
-  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);
 
+  /* 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));
+
+  emit_use (hard_frame_pointer_rtx);
+  emit_use (stack_pointer_rtx);
+
   /* 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 ());