POINTERS_EXTEND_UNSIGNED fix (found on IA64 HP-UX)
Richard Henderson
rth@redhat.com
Tue Jul 16 17:02:00 GMT 2002
On Tue, Jul 16, 2002 at 02:35:38PM -0700, Steve Ellcey wrote:
> The comments under 'case PLUS' and 'case MULT' in convert_memory_address
> say the optimization for PLUS is safe for small constants but the test
> is:
>
> INTVAL (XEXP (x, 1)) + 20000 < 40000
This is completely bogus. Either any constant is valid or no
constant is valid.
> And we do the optimization and wind up generating bad code.
How, exactly, do things go wrong?
Is it that -2000000000L is signed, but unsigned or ptr-extending
pointers frob the high bits in a bad way? If so, the proper
solution is to remove that range check, and
(1) if sign- or zero-extending pointers, verify that the constant
is the same after conversion.
(2) if ptr-extending, don't ever re-associate the operations.
This shouldn't hurt ia64, since we don't have much in the
way of special address arithmetic that this reassociation
is hoping to cater to.
Incidentally, the CONST_INT/CONST_DOUBLE case looks wrong. We
should be adjusting the constant according to POINTERS_EXTEND_UNSIGNED
from from_mode to to_mode. Really that means
case CONST_INT:
case CONST_DOUBLE:
if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode))
code = TRUNCATE;
else if (POINTERS_EXTEND_UNSIGNED)
code = ZERO_EXTEND;
else
code = SIGN_EXTEND;
return simplify_unary_operation (code, to_mode, x, from_mode);
r~
More information about the Gcc-patches
mailing list