Commit e15a8cbe by Alan Modra Committed by Alan Modra

re PR target/44075 (__builtin_eh_return miscompiled)

	PR target/44075
	* config/rs6000/rs6000.c (struct machine_function): Reorder
	fields for better packing.  Add lr_save_state.
	(rs6000_ra_ever_killed): Return lr_save_state if set.
	(rs6000_emit_eh_reg_restore): Set lr_save_state.

From-SVN: r159382
parent 3d8d607e
2010-05-14 Alan Modra <amodra@gmail.com>
PR target/44075
* config/rs6000/rs6000.c (struct machine_function): Reorder
fields for better packing. Add lr_save_state.
(rs6000_ra_ever_killed): Return lr_save_state if set.
(rs6000_emit_eh_reg_restore): Set lr_save_state.
2010-05-13 Jan Hubicka <jh@suse.cz> 2010-05-13 Jan Hubicka <jh@suse.cz>
* varpool.c (decide_is_variable_needed): Drop code checking * varpool.c (decide_is_variable_needed): Drop code checking
......
...@@ -115,14 +115,16 @@ typedef struct rs6000_stack { ...@@ -115,14 +115,16 @@ typedef struct rs6000_stack {
This is added to the cfun structure. */ This is added to the cfun structure. */
typedef struct GTY(()) machine_function typedef struct GTY(()) machine_function
{ {
/* Flags if __builtin_return_address (n) with n >= 1 was used. */
int ra_needs_full_frame;
/* Some local-dynamic symbol. */ /* Some local-dynamic symbol. */
const char *some_ld_name; const char *some_ld_name;
/* Whether the instruction chain has been scanned already. */ /* Whether the instruction chain has been scanned already. */
int insn_chain_scanned_p; int insn_chain_scanned_p;
/* Flags if __builtin_return_address (n) with n >= 1 was used. */
int ra_needs_full_frame;
/* Flags if __builtin_return_address (0) was used. */ /* Flags if __builtin_return_address (0) was used. */
int ra_need_lr; int ra_need_lr;
/* Cache lr_save_p after expansion of builtin_eh_return. */
int lr_save_state;
/* Offset from virtual_stack_vars_rtx to the start of the ABI_V4 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
varargs save area. */ varargs save area. */
HOST_WIDE_INT varargs_save_offset; HOST_WIDE_INT varargs_save_offset;
...@@ -17729,6 +17731,9 @@ rs6000_ra_ever_killed (void) ...@@ -17729,6 +17731,9 @@ rs6000_ra_ever_killed (void)
if (cfun->is_thunk) if (cfun->is_thunk)
return 0; return 0;
if (cfun->machine->lr_save_state)
return cfun->machine->lr_save_state - 1;
/* regs_ever_live has LR marked as used if any sibcalls are present, /* regs_ever_live has LR marked as used if any sibcalls are present,
but this should not force saving and restoring in the but this should not force saving and restoring in the
pro/epilogue. Likewise, reg_set_between_p thinks a sibcall pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
...@@ -17898,6 +17903,12 @@ rs6000_emit_eh_reg_restore (rtx source, rtx scratch) ...@@ -17898,6 +17903,12 @@ rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
} }
else else
emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]); emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
/* Freeze lr_save_p. We've just emitted rtl that depends on the
state of lr_save_p so any change from here on would be a bug. In
particular, stop rs6000_ra_ever_killed from considering the SET
of lr we may have added just above. */
cfun->machine->lr_save_state = info->lr_save_p + 1;
} }
static GTY(()) alias_set_type set = -1; static GTY(()) alias_set_type set = -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment