On 2/12/25 10:18, Jakub Jelinek wrote:
On Tue, Feb 11, 2025 at 05:20:49PM -0700, Jeff Law wrote:
So this is a fairly old regression, but with all the ranger work that's been
done, it's become easy to resolve.

The basic idea here is to use known relationships between two operands of a
SUB_OVERFLOW IFN to statically compute the overflow state and ultimately
allow turning the IFN into simple arithmetic (or for the tests in this BZ
elide the arithmetic entirely).

The regression example is when the two inputs are known equal.  In that case
the subtraction will never overflow.    But there's a few other cases we can
handle as well.

a == b -> never overflows
a > b  -> never overflows when A and B are unsigned
a >= b -> never overflows when A and B are unsigned
a < b  -> always overflows when A and B are unsigned
Is that really the case?
I mean, .SUB_OVERFLOW etc. can have 3 arbitrary types, the type into which
we are trying to write the result and the 2 types of arguments.
Consider:

int
foo (unsigned x, unsigned y)
{
   return __builtin_sub_overflow_p (x, y, (signed char) 0);
}

int
bar (unsigned int x, unsigned long long y)
{
   return __builtin_sub_overflow_p (x, y, (_BitInt(33)) 0);
}

int
main ()
{
   __builtin_printf ("%d\n", foo (16, 16));
   __builtin_printf ("%d\n", foo (65536, 65536));
   __builtin_printf ("%d\n", foo (65536, 16));
   __builtin_printf ("%d\n", bar (0, ~0U));
   __builtin_printf ("%d\n", bar (0, ~0ULL));
}

The a == b case is probably ok, although unsure if the relation query
won't be upset if op0 and op1 have different types (say signed long long vs.

Relation queries are purely ssa-name based, and never look at the type.   The only way a relation can exist between 2 different typed SSA_NAMES with different size/signs is if a call is made to record such a relation. Its not disallowed, but its unlikely to happen from within ranger currently (other than partial equivalences), but presumably even if it did, it should only come from a circumstance where the operation generating the relation knows it to be true.  Typically relations are generated as known side effects of a stmt executing.. like if (a < b), and all the instances I am aware of involve range-ops between operands of the same size..

Its easy enough to be safe an check if it matters tho I suppose.

FWIW, ==  should only come up when both the sign and # bits are the same.  Otherwise it is represented with a partial equivalence which indicates only that a certain number of bits are equal.

Andrew

Reply via email to