[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