[x32] PATCH: PR middle-end/47725: [x32] error: unable to find a register to spill in class DIREG
Eric Botcazou
ebotcazou@adacore.com
Thu Mar 24 15:56:00 GMT 2011
> Pointer is promoted to Pmode from ptr_mode.
Indeed. However the problem is the 2 in assign_parm_setup_reg:
/* Store the parm in a pseudoregister during the function, but we may
need to do it in a wider mode. Using 2 here makes the result
consistent with promote_decl_mode and thus expand_expr_real_1. */
promoted_nominal_mode
= promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp,
TREE_TYPE (current_function_decl), 2);
which is supposed to match the 2 in promote_decl_mode:
if (TREE_CODE (decl) == RESULT_DECL
|| TREE_CODE (decl) == PARM_DECL)
pmode = promote_function_mode (type, mode, &unsignedp,
TREE_TYPE (current_function_decl), 2);
else
pmode = promote_mode (type, mode, &unsignedp);
but doesn't match the 0 in assign_parm_find_data_types:
promoted_mode = promote_function_mode (passed_type, passed_mode, &unsignedp,
TREE_TYPE (current_function_decl), 0);
so you get the redundant extension in the callee. The solution is to define
the promote_function_mode hook for x86 to something like:
static enum machine_mode
ix86_promote_function_mode (const_tree type,
enum machine_mode mode,
int *punsignedp,
const_tree fntype ATTRIBUTE_UNUSED,
int for_return ATTRIBUTE_UNUSED)
{
if (POINTER_TYPE_P (type))
{
*punsignedp = POINTERS_EXTEND_UNSIGNED;
return Pmode;
}
return mode;
}
--
Eric Botcazou
More information about the Gcc-patches
mailing list