On Mon, Jul 11, 2011 at 4:03 AM, Paolo Bonzini <bonz...@gnu.org> wrote:
> On 07/11/2011 02:04 AM, H.J. Lu wrote:
>>
>> With my original change,  I got
>>
>> (const:DI (plus:DI (symbol_ref:DI ("iplane.1577") [flags 0x2]
>> <var_decl 0x7ffff0857960 iplane>)
>>         (const_int -4 [0xfffffffffffffffc])))
>>
>> I think it is safe to permute the conversion and addition operation
>> if one operand is a constant and we are zero-extending.  This is
>> how zero-extending works.
>
> Ok, I think I understand what you mean.  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".  For zero-extend, the issue is address-wrap.
As I understand, to support address-wrap, you need to use ptr_mode.

> If pointers extend as signed you also have a similar case.   If FOO ==
> 0x7ffffffc and Y = 8, the result of
>
>  (sign_extend:DI (plus:SI FOO:SI) (const_int Y))
>
> and
>
>  (plus:DI FOO:DI (sign_extend:DI (const_int Y)))
>
> will be respectively 0xffffffff80000004 (valid) and 0x80000004 (invalid).
>
>
> What happens if you just return NULL instead of the assertion (good idea
> adding it!)?
>
> Of course then you need to:
>
> 1) check the return values of convert_memory_address_addr_space_1, and
> propagate NULL up to simplify_unary_operation;
>
> 2) check in simplify-rtx.c whether the return value of
> convert_memory_address_1 is NULL, and only return if the return value is not
> NULL.  This is not yet necessary (convert_memory_address is the last
> transformation for both SIGN_EXTEND and ZERO_EXTEND) but it is better to
> keep code clean.

I will give it a try.

Thanks.


-- 
H.J.

Reply via email to