“-foo” overflows when “foo” is INT_MIN, whereas the original expression
didn't overflow in that case.
As discussed in the PR trail, we could simply ignore the fact that
int overflow is undefined and treat it as a wrapping type, but that
is likely to pessimise quite a few cases.
This patch instead reworks split_constant_offset so that:
- it treats integer operations as having an implicit cast to sizetype
- for integer operations, the returned VAR has type sizetype
In other words, the problem becomes to express:
(sizetype) (OP0 CODE OP1)
as:
VAR:sizetype + (sizetype) OFF:ssizetype
The top-level integer split_constant_offset will (usually) be a sizetype
POINTER_PLUS operand, so the extra cast to sizetype disappears. But adding
the cast allows the conversion handling to defer a lot of the difficult
cases to the recursive split_constant_offset call, which can detect
overflow on individual operations.
gcc/
PR tree-optimization/98069
* tree-data-ref.c (compute_distributive_range): New function.
(nop_conversion_for_offset_p): Likewise.
(split_constant_offset): In the internal overload, treat integer
expressions as having an implicit cast to sizetype and express
them accordingly. Pass back the range of the original (uncast)
expression in a new range parameter.
(split_constant_offset_1): Likewise. Rework the handling of
conversions to account for the implicit sizetype casts.