diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-19 20:48:25 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-07-19 20:48:25 +0000 |
commit | 3079004085dceb00adb2bf677cf93dd865ef71a6 (patch) | |
tree | 0b64e6d9e88dfbc57439877cbb5bccdfdbdd43ed /gcc/function.c | |
parent | 835deb0f8c407b309bf1bec137dcee88dba50b04 (diff) | |
download | gcc-3079004085dceb00adb2bf677cf93dd865ef71a6.tar.gz |
PR rtl-optimization/53942
* function.c (assign_parm_setup_reg): Avoid zero/sign extension
directly from likely spilled non-fixed hard registers, move them
to pseudo first.
* gcc.dg/pr53942.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189681 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/gcc/function.c b/gcc/function.c index c56758870bc..f1e0b2d3eba 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2987,11 +2987,26 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, && insn_operand_matches (icode, 1, op1)) { enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND; - rtx insn, insns; + rtx insn, insns, t = op1; HARD_REG_SET hardregs; start_sequence (); - insn = gen_extend_insn (op0, op1, promoted_nominal_mode, + /* If op1 is a hard register that is likely spilled, first + force it into a pseudo, otherwise combiner might extend + its lifetime too much. */ + if (GET_CODE (t) == SUBREG) + t = SUBREG_REG (t); + if (REG_P (t) + && HARD_REGISTER_P (t) + && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (t)) + && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (t)))) + { + t = gen_reg_rtx (GET_MODE (op1)); + emit_move_insn (t, op1); + } + else + t = op1; + insn = gen_extend_insn (op0, t, promoted_nominal_mode, data->passed_mode, unsignedp); emit_insn (insn); insns = get_insns (); |