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.