https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608

--- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Aldy Hernandez from comment #16)
> Created attachment 54224 [details]
> untested patch
> 
> Perhaps this would work.  It solves the testcase, though I think we should
> probably audit the operators that don't use the generic
> range_operator_float::fold_range to make sure they're not doing anything
> silly.

Even as a workaround this seems to be quite a big hammer.
If we want to preserve overflow traps, all we need to arrange is that if
non-inf operands result in singleton inf we don't treat that result as
singleton.
Now, what result one gets in different rounding modes depends on the rounding
mode,
in round to nearest it should be +-inf, in round to zero +-max, in round to
+inf +inf or -max and in round to -inf -inf or +max.  But right now GCC doesn't
handle the separate rounding modes, it just differentiates between
-fno-rounding-math where we assume round to nearest and -frounding-math where
we should consider any rounding mode.
I think for -frounding-math we already don't treat such results as singletons,
as we
end up with ranges like [+max, +inf] or [-inf, -max].
So, one possible way for -fno-rounding-math -ftrapping-math could be instead of
making
the result VARYING just extend the range by one ulp towards 0, i.e. instead of
singleton
[+inf, +inf] use [+max, +inf] etc.
Another would be to add some bool flag to frange which would say this is never
a singleton and just take that flag into account, though perhaps it is too
risky right now.

As for invalid exceptions, that implies result maybe or known NAN, but we don't
treat
maybe or known NAN as singletons, do we?  After all, there isn't just a single
NAN and we don't know which one the result is.  That doesn't mean we handle all
cases right, say
if a result of something is only used in __builtin_isnan or similar, we can
still happily optimized it away.

As for underflow exceptions, I've tried to construct a testcase but seems we
didn't care already in older GCC versions.
Say for float foo (void) { float x = __FLT_MIN__; return x * x; } without
-frounding-math we already optimized it in ccp1 in GCC 12 and older, with
-frounding-math again we should be fine because the result isn't singleton.
Again with the problem that if the result is in the end used in some comparison
or test that will not care about details, like if (__builtin_fabsf (foo ()) <
1.0f) then again we optimize away the trapping operation and we didn't
previously.

And inexact exceptions I think is something we just basically didn't care at
all before, those can happen pretty much all the time.

Reply via email to