> On May 29, 2014, at 10:09 AM, "H.J. Lu" <hjl.to...@gmail.com> wrote:
> 
>> 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?

Pmode is dimode while ptr_mode is simode.  Pointers are zero extended when 
converting between si and di modes. 

Thanks,
Andrew


> 
> 
> -- 
> H.J.

Reply via email to