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