Ian Lance Taylor <[email protected]> wrote:
> I don't see what this has to do with pure functions.
>
> It seems to me that instead you want to put something here:
>
> else if (target
> && GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp))
> && GET_MODE (target) == GET_MODE (valreg))
> {
> /* TARGET and VALREG cannot be equal at this point because the
> latter would not have REG_FUNCTION_VALUE_P true, while the
> former would if it were referring to the same register.
>
> If they refer to the same register, this move will be a no-op,
> except when function inlining is being done. */
> emit_move_insn (target, valreg);
>
> i.e.
>
> if (REG_P (valreg)
> && HARD_REGISTER_P (valreg)
> && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (valreg))))
> valreg = copy_to_reg (valreg);
> emit_move_insn (target, valreg);
Like this?
@@ -2861,6 +2861,12 @@ expand_call (tree exp, rtx target, int i
If they refer to the same register, this move will be a no-op,
except when function inlining is being done. */
+ /* We have to copy a return value in a CLASS_LIKELY_SPILLED hard
+ reg to a plain register. */
+ if (REG_P (valreg)
+ && HARD_REGISTER_P (valreg)
+ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (valreg))))
+ valreg = copy_to_reg (valreg);
emit_move_insn (target, valreg);
/* If we are setting a MEM, this code must be executed. Since it is
Regards,
kaz