PING: PATCH [4/n]: Prepare x32: Permute the conversion and addition if one operand is a constant

H.J. Lu hjl.tools@gmail.com
Thu May 29 17:09:00 GMT 2014


On Thu, May 29, 2014 at 9:23 AM,  <pinskia@gmail.com> wrote:
>
>
>> On May 29, 2014, at 9:13 AM, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>
>>> On Wed, May 28, 2014 at 9:52 PM, Andrew Pinski <pinskia@gmail.com> wrote:
>>>> On Wed, Jul 13, 2011 at 9:39 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>> On Wed, Jul 13, 2011 at 9:13 AM, Paolo Bonzini <bonzini@gnu.org> wrote:
>>>>>> On 07/11/2011 05:54 PM, H.J. Lu wrote:
>>>>>>
>>>>>> The key is the
>>>>>>>
>>>>>>>    XEXP (x, 1) == convert_memory_address_addr_space
>>>>>>>                   (to_mode, XEXP (x, 1), as)
>>>>>>>
>>>>>>> test.  It ensures basically that the constant has 31-bit precision,
>>>>>>> because
>>>>>>> otherwise the constant would change from e.g. (const_int -0x7ffffffc)
>>>>>>> to
>>>>>>> (const_int 0x80000004) when zero-extending it from SImode to DImode.
>>>>>>>
>>>>>>> But I'm not sure it's safe.  You have,
>>>>>>>
>>>>>>>   (zero_extend:DI (plus:SI FOO:SI) (const_int Y))
>>>>>>>
>>>>>>> and you want to convert it to
>>>>>>>
>>>>>>>   (plus:DI FOO:DI (zero_extend:DI (const_int Y)))
>>>>>>>
>>>>>>> (where the zero_extend is folded).  Ignore that FOO is a SYMBOL_REF
>>>>>>> (this
>>>>>>> piece of code does not assume anything about its shape); if FOO ==
>>>>>>> 0xfffffffc and Y = 8, the result will be respectively 0x4 (valid) and
>>>>>>> 0x100000004 (invalid).
>>>>>>
>>>>>> This example contradicts what you said above "It ensures basically that
>>>>>> the
>>>>>> constant has 31-bit precision".
>>>>>
>>>>> Why?  Certainly Y = 8 has 31-bit (or less) precision.  So it has the same
>>>>> representation in SImode and DImode, and the test above on XEXP (x, 1)
>>>>> succeeds.
>>>>
>>>> And then we permute conversion and addition, which leads to the issue you
>>>> raised above.  In another word, the current code permutes conversion
>>>> and addition.
>>>> It leads to different values in case of symbol (0xfffffffc) + 8.
>>>> Basically the current
>>>> test for 31-bit (or less) precision is bogus.  The real question is
>>>> for a address
>>>> computation, A + B, if address wrap-around is supported in
>>>> convert_memory_address_addr_space.
>>>
>>> Unless the code has already reassociated the additions already.
>>> Like in the AARCH64 ILP32 case:
>>>
>>> (plus:SI (plus:SI (mult:SI (reg/v:SI 80 [ b ])
>>>            (const_int -4 [0xfffffffffffffffc]))
>>>        (subreg/s/u:SI (reg/v/f:DI 79 [ a ]) 0))
>>>    (const_int -1073742592 [0xffffffffbffffd00]))
>>>
>>> The Tree level is correct in that it did not reassociate the addition
>>> but the RTL level ignores that.
>>>
>>> So this patch is invalid and incorrect unless you know the non
>>> constant part of the addition is a pointer (which is not the case
>>> here).
>>
>> There is an address overflow.  Is the address overflow behavior
>> defined here?
>
> There was no address overflow in the original code and there was no address overflow in the tree level. The rtl level does introduce an address overflow but the semantics of plus is defined to be wrapping so there is no overflow.   This is blocking me from testing ilp32 under gnu/Linux as ld.so gets miscompiled and stack addresses have the "sign" bit set.
>

What is your Pmode?


-- 
H.J.



More information about the Gcc-patches mailing list