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

Reply via email to