https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107591
Bug ID: 107591
Summary: range-op{,-float}.cc for x * x
Product: gcc
Version: 13.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
int
foo (int x)
{
if (x < -13 || x > 26)
return -1;
return x * x;
}
results in
x_4(D) : [irange] int [-13, 26]
_5 : [irange] int [-338, 676]
That is unnecessarily pessimized, because it only computes [-13, 26] * [-13,
26]
range without taking into account that both operands are the same.
For the powi (x, 2) case the range is actually [0, 26 * 26], i.e. we shouldn't
do a cross product for it, just compute the -13 * -13, 0 * 0 (if 0 is in the
range) and 26 * 26 products and form from that the range (I admit I haven't
thought about unsigned or wrapping stuff).
On the PR107569 testcase it is on frange:
_3 = u_2(D)->x;
_6 = _3 * _3;
_7 = u_2(D)->y;
_8 = _7 * _7;
_9 = _6 + _8;
if (_9 u>= 0.0)
If we don't know anything further about u_2(D)->x and u_2(D)->y, VARYING *
VARYING is [0, +Inf] +-NAN, added twice is the same (note, unless
-fno-signed-zeros, it should be really [+0, +Inf] +-NAN, not [-0, +Inf] +-NAN,
but it doesn't matter for the u>= 0.0 comparison).
And then we can fold u>= 0.0 to true.