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,