re PR middle-end/64242 (Longjmp expansion incorrect)

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
This commit is contained in:
John David Anglin 2019-06-16 21:27:14 +00:00
parent 0fcc78f79e
commit c669ebe7c3
2 changed files with 34 additions and 21 deletions

View 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

View File

@ -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
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 ());