diff options
author | Alan Modra <amodra@gmail.com> | 2010-05-14 10:05:16 +0930 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2010-05-14 10:05:16 +0930 |
commit | e15a8cbe1a7d51072a1b998ccfa6f1977b8688fc (patch) | |
tree | e8d0fffdb199a23a50c4c488287e90a6886c7998 | |
parent | 3d8d607efced01c0af693f06e559bd8c32438451 (diff) | |
download | gcc-e15a8cbe1a7d51072a1b998ccfa6f1977b8688fc.zip gcc-e15a8cbe1a7d51072a1b998ccfa6f1977b8688fc.tar.gz gcc-e15a8cbe1a7d51072a1b998ccfa6f1977b8688fc.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 15 |
2 files changed, 21 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 007ce28..86e0efd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +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> * varpool.c (decide_is_variable_needed): Drop code checking diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 9479548..cd1e3ba 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -115,14 +115,16 @@ typedef struct rs6000_stack { This is added to the cfun structure. */ 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. */ const char *some_ld_name; /* Whether the instruction chain has been scanned already. */ 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. */ 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 varargs save area. */ HOST_WIDE_INT varargs_save_offset; @@ -17729,6 +17731,9 @@ rs6000_ra_ever_killed (void) if (cfun->is_thunk) 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, but this should not force saving and restoring in the pro/epilogue. Likewise, reg_set_between_p thinks a sibcall @@ -17898,6 +17903,12 @@ rs6000_emit_eh_reg_restore (rtx source, rtx scratch) } else 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; |