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

--- Comment #21 from Richard Biener <rguenth at gcc dot gnu.org> ---
So without messing with real.cc to try exposing 0.5ulp adjustments for GCC 13
I'd simply do something like the following:

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index ff42b95de4f..1ae68503664 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -2214,7 +2214,26 @@ public:
     range_op_handler minus (MINUS_EXPR, type);
     if (!minus)
       return false;
-    return float_binary_op_range_finish (minus.fold_range (r, type, lhs, op2),
+    /* The forward operation is
+        lhs = r + op2
+       where the result is +-0.5ulp of lhs before rounding.  For the
+       reverse operation we need the lhs range before rounding, so
+       conservatively use nextafter on it.
+       ???  REAL_VALUE_TYPE could handle this more precisely if we
+       make sure to not round the inputs for the format before the
+       real_operation is carried out and when we can properly round
+       towards +-Inf for the lower/upper bounds.  */
+    frange wlhs (lhs);
+    if (!lhs.known_isnan ())
+      {
+       REAL_VALUE_TYPE lhsl = lhs.lower_bound ();
+       frange_nextafter (TYPE_MODE (type), lhsl, dconstninf);
+       REAL_VALUE_TYPE lhsu = lhs.upper_bound ();
+       frange_nextafter (TYPE_MODE (type), lhsu, dconstinf);
+       wlhs.set (type, lhsl, lhsu);
+       wlhs.union_ (lhs);  /* Copy NaN state.  */
+      }
+    return float_binary_op_range_finish (minus.fold_range (r, type, wlhs,
op2),
                                         r, type, lhs);
   }
   virtual bool op2_range (frange &r, tree type,

Reply via email to