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.