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).

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.

Thanks,

Paolo

Reply via email to