On Thu, May 29, 2014 at 9:23 AM,  <pins...@gmail.com> wrote:
>
>
>> On May 29, 2014, at 9:13 AM, "H.J. Lu" <hjl.to...@gmail.com> wrote:
>>
>>> On Wed, May 28, 2014 at 9:52 PM, Andrew Pinski <pins...@gmail.com> wrote:
>>>> On Wed, Jul 13, 2011 at 9:39 AM, H.J. Lu <hjl.to...@gmail.com> wrote:
>>>>> On Wed, Jul 13, 2011 at 9:13 AM, Paolo Bonzini <bonz...@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.

Reply via email to