On Fri, May 05, 2023 at 01:38:48PM +0200, Mikael Morin wrote: > I think there is something wrong with the handling of NAN and lower bounds > in op1_range. If the lhs has positive lower bound and can be nan, op1 > should have -inf lower bound regardless of lhs's lower bound value.
Oops, you're right, will retest with --- gcc/gimple-range-op.cc 2023-05-04 19:58:44.842606865 +0200 +++ gcc/gimple-range-op.cc 2023-05-05 13:53:58.742406160 +0200 @@ -508,6 +508,7 @@ ub = dconstinf; frange r2; r2.set (type, lb, ub); + r2.flush_denormals_to_zero (); r.intersect (r2); return true; } @@ -563,7 +564,7 @@ return true; REAL_VALUE_TYPE lb = lhs.lower_bound (); REAL_VALUE_TYPE ub = lhs.upper_bound (); - if (real_less (&dconst0, &lb)) + if (!lhs.maybe_isnan () && real_less (&dconst0, &lb)) { for (unsigned i = 0; i < ulps; ++i) frange_nextafter (TYPE_MODE (type), lb, dconstninf); incremental change (the first hunk because fold_range is forward operation and that could in some configurations flush denormals to zero). Thanks for catching that. > Maybe it would be less error prone to combine the ordered range part (r2) > and the unordered one (r) with union instead of intersection? The reason for the intersection rather than tweaking the bounds immediately is for 2 reasons, ulps might be larger than bulps (the boundary ones) but the boundary ulps should take priority on the boundaries, so if say bulps is 2ulps and ulps 10ulps and sqrt (lb) is 0.0 + 4ulps, then the range should be [-0.0 - 2ulps, ...] rather than [-0.0 - 6ulps, ...], and to help readers determine this is the range from the intrinsic boundaries, this is the range from specific values, one can put breakpoints around the intersection and print both ranges and the result etc. > The rest looks good. There is the case of slightly negative lhs bounds > coming (through ulps) from slightly positive op1 that could get better than > infinite bounds for op1 range, but at least it is conservatively correct, > and I'm not sure it's that important anyway. Currently bulps for sqrt in glibc is always 0, haven't discovered any case of sqrt actually returning < -0.0 value, so the sqrt bulps other than ~0U (don't know, currently all non-glibc targets) is always 0. That is just in case some other implementation returns such values. For sin/cos unfortunately even glibc sometimes returns > 1.0 or < -1.0 values in non-default rounding modes. Jakub