On 2/12/25 8:44 AM, Jakub Jelinek wrote:
On Wed, Feb 12, 2025 at 08:29:37AM -0700, Jeff Law wrote:
On 2/12/25 8:18 AM, 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.
So if the types are allowed to vary within a statement (I guess as an IFN
they can unlike most gimple operations).

The overflow builtins started from clang's
__builtin_{s,u}{add,sub,mul}{,l,ll}_overflow
builtins (those were added for compatibility), all of those have the 3 types
identical; but the __builtin_{add,sub,mul}_overflow{,_p} builtins allow 3
arbitrary types, whether something overflows or not is determined by
performing the operation in virtually infinite precision and then seeing if
it is representable in the target type.

I'm fine if your patch is for GCC 15 limited to the easy cases with all 3
types compatible (that is the common case).  Still, I think it would be nice
not to restrict to TYPE_UNSIGNED, just say check either that for a >= b or a > b
b is not negative (using vr1min).

And let's file a PR for GCC 16 to do it properly.
The pause button was to give me time to get coffee in and brain turned on to walk through the cases.

Note there's code later in that function which actually does computations based on known ranges to try and prove/disprove overflow state. There may be cases there we can improve range based analysis as well and there may be cases where the combination of range information and relationships couple be helpful. Those all felt out of scope to me in terms of addressing the regression. Happy to open a distinct issue on possibilities there.

The regression can be resolved entirely by looking at the relationship between and the types of the inputs. Hence it's a distinct block of code in that routine and avoids most of the complexity in that routine.

I agree that the most common cases should be all the arguments the same type. I was working under the assumption that the args would be compatible types already, forgetting that IFNs are different in that regard than other gimple ops. I wouldn't want to go any further than all three operands the same with the easy to reason about relation checks.


For gcc-16 I think we can extend that block fairly easily to handle certain mismatched size cases and we look to see if there's cases where the combination of a relationship between the arguments and some range information would allow us to capture further cases.

It may even make a good relatively early task for one of the interns I've got that's starting soon. Narrow in scope, easily understood, doesn't require a ton of internals knowledge to reason about the cases,
easy to evaluate if the transformations are triggering, etc etc.


Jeff





Reply via email to