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