http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47725
--- Comment #6 from H.J. Lu <hjl.tools at gmail dot com> 2011-02-14 14:13:32 UTC --- This seems to work: diff --git a/gcc/function.c b/gcc/function.c index 3f721fb..4c78407 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3000,11 +3000,15 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, && insn_data[icode].operand[1].predicate (op1, data->passed_mode)) { enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND; - rtx insn, insns; + rtx insn, insns, copy; HARD_REG_SET hardregs; start_sequence (); - insn = gen_extend_insn (op0, op1, promoted_nominal_mode, + /* We must copy the hard register first before extending it. + Otherwise, combine won't see the hard register. */ + copy = gen_reg_rtx (data->passed_mode); + emit_move_insn (copy, op1); + insn = gen_extend_insn (op0, copy, promoted_nominal_mode, data->passed_mode, unsignedp); emit_insn (insn); insns = get_insns ();