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