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

--- Comment #27 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #21)
> 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,

Could we abstract this into an inline function until this could be properly
implemented in real.cc?

Reply via email to