diff mbox

PATCH [3/n] X32: Promote pointers to Pmode

Message ID CAMe9rOqJrnd1mCN17GD8k72PvLH8gSFqpuDgoJa8mF_bBgrfOw@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu July 10, 2011, 7:43 p.m. UTC
On Sun, Jul 10, 2011 at 7:32 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Sat, Jul 9, 2011 at 11:28 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>
>> X32 psABI requires promoting pointers to Pmode when passing/returning
>> in registers.  OK for trunk?
>>
>> Thanks.
>>
>> H.J.
>> --
>> 2011-07-09  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>        * config/i386/i386.c (ix86_promote_function_mode): New.
>>        (TARGET_PROMOTE_FUNCTION_MODE): Likewise.
>>
>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>> index 04cb07d..c852719 100644
>> --- a/gcc/config/i386/i386.c
>> +++ b/gcc/config/i386/i386.c
>> @@ -7052,6 +7061,23 @@ ix86_function_value (const_tree valtype, const_tree fntype_or_decl,
>>   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
>>  }
>>
>> +/* Pointer function arguments and return values are promoted to
>> +   Pmode.  */
>> +
>> +static enum machine_mode
>> +ix86_promote_function_mode (const_tree type, enum machine_mode mode,
>> +                           int *punsignedp, const_tree fntype,
>> +                           int for_return)
>> +{
>> +  if (for_return != 1 && type != NULL_TREE && POINTER_TYPE_P (type))
>> +    {
>> +      *punsignedp = POINTERS_EXTEND_UNSIGNED;
>> +      return Pmode;
>> +    }
>> +  return default_promote_function_mode (type, mode, punsignedp, fntype,
>> +                                       for_return);
>> +}
>
> Please rewrite the condition to:
>
> if (for_return == 1)
>  /* Do not promote function return values.  */
>  ;
> else if (type != NULL_TREE && ...)
>
> Also, please add some comments.
>
> Your comment also says that pointer return arguments are promoted to
> Pmode. The documentation says that:
>
>     FOR_RETURN allows to distinguish the promotion of arguments and
>     return values.  If it is `1', a return value is being promoted and
>     `TARGET_FUNCTION_VALUE' must perform the same promotions done here.
>     If it is `2', the returned mode should be that of the register in
>     which an incoming parameter is copied, or the outgoing result is
>     computed; then the hook should return the same mode as
>     `promote_mode', though the signedness may be different.
>
> You bypass promotions when FOR_RETURN is 1.
>
> Uros.
>

Here is the updated patch. OK for trunk?

Thanks.

Comments

Richard Henderson July 10, 2011, 9:44 p.m. UTC | #1
On 07/10/2011 12:43 PM, H.J. Lu wrote:
> +/* Pointer function arguments and return values are promoted to Pmode.
> +   If FOR_RETURN is 1, this function must behave in the same way with
> +   regard to function returns as TARGET_FUNCTION_VALUE.  */
> +
> +static enum machine_mode
> +ix86_promote_function_mode (const_tree type, enum machine_mode mode,
> +			    int *punsignedp, const_tree fntype,
> +			    int for_return)
> +{
> +  if (for_return == 1)
> +    /* Do not promote function return values.  */
> +    ;
> +  else if (type != NULL_TREE && POINTER_TYPE_P (type))

These two comments still conflict.  And why wouldn't you want to 
promote return values?


r~
H.J. Lu July 10, 2011, 10:01 p.m. UTC | #2
On Sun, Jul 10, 2011 at 2:44 PM, Richard Henderson <rth@redhat.com> wrote:
> On 07/10/2011 12:43 PM, H.J. Lu wrote:
>> +/* Pointer function arguments and return values are promoted to Pmode.
>> +   If FOR_RETURN is 1, this function must behave in the same way with
>> +   regard to function returns as TARGET_FUNCTION_VALUE.  */
>> +
>> +static enum machine_mode
>> +ix86_promote_function_mode (const_tree type, enum machine_mode mode,
>> +                         int *punsignedp, const_tree fntype,
>> +                         int for_return)
>> +{
>> +  if (for_return == 1)
>> +    /* Do not promote function return values.  */
>> +    ;
>> +  else if (type != NULL_TREE && POINTER_TYPE_P (type))
>
> These two comments still conflict.  And why wouldn't you want to
> promote return values?

We only want to promote function parameters passed/returned in register.
But  I can't tell if a value will be passed in register or memory inside of
TARGET_FUNCTION_VALUE.  So when FOR_RETURN is 1, we don't
promote. Even if we don't promote it explicitly, hardware still zero-extends
it for us. So it isn't a real issue.
Richard Henderson July 11, 2011, 12:48 a.m. UTC | #3
On 07/10/2011 03:01 PM, H.J. Lu wrote:
> We only want to promote function parameters passed/returned in register.
> But  I can't tell if a value will be passed in register or memory inside of
> TARGET_FUNCTION_VALUE.  So when FOR_RETURN is 1, we don't
> promote. Even if we don't promote it explicitly, hardware still zero-extends
> it for us. So it isn't a real issue.

The hardware *usually* zero-extends.  It all depends on where the data is
coming from.  Without certainty, i.e. actually representing it properly,
you're designing a broken ABI.

What you wrote above re T_F_V not being able to tell register or 
memory doesn't make sense.  Did you really mean inside TARGET_PROMOTE_FUNCTION_MODE?
And why exactly wouldn't you be able to tell there?  Can you not find out
via a call to ix86_return_in_memory?


r~
H.J. Lu July 11, 2011, 1:14 a.m. UTC | #4
On Sun, Jul 10, 2011 at 5:48 PM, Richard Henderson <rth@redhat.com> wrote:
> On 07/10/2011 03:01 PM, H.J. Lu wrote:
>> We only want to promote function parameters passed/returned in register.
>> But  I can't tell if a value will be passed in register or memory inside of
>> TARGET_FUNCTION_VALUE.  So when FOR_RETURN is 1, we don't
>> promote. Even if we don't promote it explicitly, hardware still zero-extends
>> it for us. So it isn't a real issue.
>
> The hardware *usually* zero-extends.  It all depends on where the data is
> coming from.  Without certainty, i.e. actually representing it properly,
> you're designing a broken ABI.
>
> What you wrote above re T_F_V not being able to tell register or
> memory doesn't make sense.  Did you really mean inside TARGET_PROMOTE_FUNCTION_MODE?
> And why exactly wouldn't you be able to tell there?  Can you not find out
> via a call to ix86_return_in_memory?
>

TARGET_PROMOTE_FUNCTION_MODE is for passing/returning
value in a register and the documentation says that:

    FOR_RETURN allows to distinguish the promotion of arguments and
    return values.  If it is `1', a return value is being promoted and
    `TARGET_FUNCTION_VALUE' must perform the same promotions done here.
    If it is `2', the returned mode should be that of the register in
    which an incoming parameter is copied, or the outgoing result is
    computed; then the hook should return the same mode as
    `promote_mode', though the signedness may be different.


But for TARGET_FUNCTION_VALUE, there is no difference for
register and memory.  That is why I don't promote when
FOR_RETURN is 1.  mmix/mmix.c and rx/rx.c have similar
treatment.
H.J. Lu July 13, 2011, 1:17 p.m. UTC | #5
PING.

On Sun, Jul 10, 2011 at 12:43 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sun, Jul 10, 2011 at 7:32 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Sat, Jul 9, 2011 at 11:28 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>>
>>> X32 psABI requires promoting pointers to Pmode when passing/returning
>>> in registers.  OK for trunk?
>>>
>>> Thanks.
>>>
>>> H.J.
>>> --
>>> 2011-07-09  H.J. Lu  <hongjiu.lu@intel.com>
>>>
>>>        * config/i386/i386.c (ix86_promote_function_mode): New.
>>>        (TARGET_PROMOTE_FUNCTION_MODE): Likewise.
>>>
>>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>>> index 04cb07d..c852719 100644
>>> --- a/gcc/config/i386/i386.c
>>> +++ b/gcc/config/i386/i386.c
>>> @@ -7052,6 +7061,23 @@ ix86_function_value (const_tree valtype, const_tree fntype_or_decl,
>>>   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
>>>  }
>>>
>>> +/* Pointer function arguments and return values are promoted to
>>> +   Pmode.  */
>>> +
>>> +static enum machine_mode
>>> +ix86_promote_function_mode (const_tree type, enum machine_mode mode,
>>> +                           int *punsignedp, const_tree fntype,
>>> +                           int for_return)
>>> +{
>>> +  if (for_return != 1 && type != NULL_TREE && POINTER_TYPE_P (type))
>>> +    {
>>> +      *punsignedp = POINTERS_EXTEND_UNSIGNED;
>>> +      return Pmode;
>>> +    }
>>> +  return default_promote_function_mode (type, mode, punsignedp, fntype,
>>> +                                       for_return);
>>> +}
>>
>> Please rewrite the condition to:
>>
>> if (for_return == 1)
>>  /* Do not promote function return values.  */
>>  ;
>> else if (type != NULL_TREE && ...)
>>
>> Also, please add some comments.
>>
>> Your comment also says that pointer return arguments are promoted to
>> Pmode. The documentation says that:
>>
>>     FOR_RETURN allows to distinguish the promotion of arguments and
>>     return values.  If it is `1', a return value is being promoted and
>>     `TARGET_FUNCTION_VALUE' must perform the same promotions done here.
>>     If it is `2', the returned mode should be that of the register in
>>     which an incoming parameter is copied, or the outgoing result is
>>     computed; then the hook should return the same mode as
>>     `promote_mode', though the signedness may be different.
>>
>> You bypass promotions when FOR_RETURN is 1.
>>
>> Uros.
>>
>
> Here is the updated patch. OK for trunk?
>
> Thanks.
>
> --
> H.J.
> --
> 2011-07-10  H.J. Lu  <hongjiu.lu@intel.com>
>
>        * config/i386/i386.c (ix86_promote_function_mode): New.
>        (TARGET_PROMOTE_FUNCTION_MODE): Likewise.
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 04cb07d..1b02312 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -7052,6 +7061,27 @@ ix86_function_value (const_tree valtype,
> const_tree fntype_or_decl,
>   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
>  }
>
> +/* Pointer function arguments and return values are promoted to Pmode.
> +   If FOR_RETURN is 1, this function must behave in the same way with
> +   regard to function returns as TARGET_FUNCTION_VALUE.  */
> +
> +static enum machine_mode
> +ix86_promote_function_mode (const_tree type, enum machine_mode mode,
> +                           int *punsignedp, const_tree fntype,
> +                           int for_return)
> +{
> +  if (for_return == 1)
> +    /* Do not promote function return values.  */
> +    ;
> +  else if (type != NULL_TREE && POINTER_TYPE_P (type))
> +    {
> +      *punsignedp = POINTERS_EXTEND_UNSIGNED;
> +      return Pmode;
> +    }
> +  return default_promote_function_mode (type, mode, punsignedp, fntype,
> +                                       for_return);
> +}
> +
>  rtx
>  ix86_libcall_value (enum machine_mode mode)
>  {
> @@ -34810,6 +35157,9 @@ ix86_autovectorize_vector_sizes (void)
>  #undef TARGET_FUNCTION_VALUE_REGNO_P
>  #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
>
> +#undef TARGET_PROMOTE_FUNCTION_MODE
> +#define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
> +
>  #undef TARGET_SECONDARY_RELOAD
>  #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
>
Uros Bizjak July 13, 2011, 1:25 p.m. UTC | #6
On Wed, Jul 13, 2011 at 3:17 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> PING.

>> 2011-07-10  H.J. Lu  <hongjiu.lu@intel.com>
>>
>>        * config/i386/i386.c (ix86_promote_function_mode): New.
>>        (TARGET_PROMOTE_FUNCTION_MODE): Likewise.

You have discussed this with rth, the final approval should be from him.

Uros.
H.J. Lu July 13, 2011, 2:02 p.m. UTC | #7
Hi Richard,

Is my patch OK?

Thanks.


H.J.
----
On Sun, Jul 10, 2011 at 6:14 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sun, Jul 10, 2011 at 5:48 PM, Richard Henderson <rth@redhat.com> wrote:
>> On 07/10/2011 03:01 PM, H.J. Lu wrote:
>>> We only want to promote function parameters passed/returned in register.
>>> But  I can't tell if a value will be passed in register or memory inside of
>>> TARGET_FUNCTION_VALUE.  So when FOR_RETURN is 1, we don't
>>> promote. Even if we don't promote it explicitly, hardware still zero-extends
>>> it for us. So it isn't a real issue.
>>
>> The hardware *usually* zero-extends.  It all depends on where the data is
>> coming from.  Without certainty, i.e. actually representing it properly,
>> you're designing a broken ABI.
>>
>> What you wrote above re T_F_V not being able to tell register or
>> memory doesn't make sense.  Did you really mean inside TARGET_PROMOTE_FUNCTION_MODE?
>> And why exactly wouldn't you be able to tell there?  Can you not find out
>> via a call to ix86_return_in_memory?
>>
>
> TARGET_PROMOTE_FUNCTION_MODE is for passing/returning
> value in a register and the documentation says that:
>
>    FOR_RETURN allows to distinguish the promotion of arguments and
>    return values.  If it is `1', a return value is being promoted and
>    `TARGET_FUNCTION_VALUE' must perform the same promotions done here.
>    If it is `2', the returned mode should be that of the register in
>    which an incoming parameter is copied, or the outgoing result is
>    computed; then the hook should return the same mode as
>    `promote_mode', though the signedness may be different.
>
>
> But for TARGET_FUNCTION_VALUE, there is no difference for
> register and memory.  That is why I don't promote when
> FOR_RETURN is 1.  mmix/mmix.c and rx/rx.c have similar
> treatment.
>
Richard Henderson July 13, 2011, 3:27 p.m. UTC | #8
On 07/13/2011 07:02 AM, H.J. Lu wrote:
> Hi Richard,
> 
> Is my patch OK?

No, I don't think it is.


r~
H.J. Lu July 13, 2011, 3:35 p.m. UTC | #9
On Wed, Jul 13, 2011 at 8:27 AM, Richard Henderson <rth@redhat.com> wrote:
> On 07/13/2011 07:02 AM, H.J. Lu wrote:
>> Hi Richard,
>>
>> Is my patch OK?
>
> No, I don't think it is.
>

What is your suggestion?
Richard Henderson July 13, 2011, 3:37 p.m. UTC | #10
On 07/13/2011 08:35 AM, H.J. Lu wrote:
> On Wed, Jul 13, 2011 at 8:27 AM, Richard Henderson <rth@redhat.com> wrote:
>> On 07/13/2011 07:02 AM, H.J. Lu wrote:
>>> Hi Richard,
>>>
>>> Is my patch OK?
>>
>> No, I don't think it is.
>>
> 
> What is your suggestion?

Promote the return value.  If that means it doesn't match function_value,
then I suggest that function_value is wrong.


r~
H.J. Lu July 14, 2011, 4:47 a.m. UTC | #11
On Wed, Jul 13, 2011 at 8:37 AM, Richard Henderson <rth@redhat.com> wrote:
> On 07/13/2011 08:35 AM, H.J. Lu wrote:
>> On Wed, Jul 13, 2011 at 8:27 AM, Richard Henderson <rth@redhat.com> wrote:
>>> On 07/13/2011 07:02 AM, H.J. Lu wrote:
>>>> Hi Richard,
>>>>
>>>> Is my patch OK?
>>>
>>> No, I don't think it is.
>>>
>>
>> What is your suggestion?
>
> Promote the return value.  If that means it doesn't match function_value,
> then I suggest that function_value is wrong.
>
>

static enum machine_mode
ix86_promote_function_mode (const_tree type, enum machine_mode mode,
                            int *punsignedp, const_tree fntype,
                            int for_return)
{
  if (type != NULL_TREE && POINTER_TYPE_P (type))
    {
      *punsignedp = POINTERS_EXTEND_UNSIGNED;
      return Pmode;
    }
  return default_promote_function_mode (type, mode, punsignedp, fntype,
                                        for_return);
}

doesn't work.  I got

In file included from
/export/gnu/import/git/gcc-x32/libgcc/config/libbid/bid_div_macros.h:27:0,
                 from
/export/gnu/import/git/gcc-x32/libgcc/config/libbid/bid128_div.c:25:
/export/gnu/import/git/gcc-x32/libgcc/config/libbid/bid_internal.h: In
function \u2018handle_UF_128.constprop.7\u2019:
/export/gnu/import/git/gcc-x32/libgcc/config/libbid/bid_internal.h:1626:1:
internal compiler error: in emit_move_insn, at expr.c:3349
Please submit a full bug report,
with preprocessed source if appropriate.

TARGET_FUNCTION_VALUE shouldn't promote pointers to Pmode
since it will also promote pointers passed in memory, which aren't
needed nor desired.

Since x86-64 processors ALWAYS zero-extend 32bit to 64bit
when writing 32bit registers, it is OK not to promote pointers
in TARGET_FUNCTION_VALUE.  We only need to promote
pointers to

static enum machine_mode
ix86_promote_function_mode (const_tree type, enum machine_mode mode,
                            int *punsignedp, const_tree fntype,
                            int for_return)
{
  if (for_return == 1)
    /* Do not promote function return values.  */
    ;
  else if (type != NULL_TREE && POINTER_TYPE_P (type))
    {
      *punsignedp = POINTERS_EXTEND_UNSIGNED;
      return Pmode;
    }
  return default_promote_function_mode (type, mode, punsignedp, fntype,
                                        for_return);
}

Richard, can you tell me what the real problem with my approach is?

Thanks.
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 04cb07d..1b02312 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2973,6 +2973,9 @@  ix86_option_override_internal (bool main_args_p)
   SUBSUBTARGET_OVERRIDE_OPTIONS;
 #endif

+  if (TARGET_X32)
+    ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+
   /* -fPIC is the default for x86_64.  */
   if (TARGET_MACHO && TARGET_64BIT)
@@ -7052,6 +7061,27 @@  ix86_function_value (const_tree valtype,