On Mon, Sep 5, 2022 at 8:24 AM Aldy Hernandez via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Intersecting two ranges where one is a NAN is keeping the sign bit of
> the NAN range.  This is not correct as the sign bits may not match.
>
> I think the only time we're absolutely sure about the intersection of
> a NAN and something else, is when both are a NAN with exactly the same
> properties (sign bit).  If we're intersecting two NANs of differing
> sign, we can decide later whether that's undefined or just a NAN with
> no known sign.  For now I've done the latter.
>
> I'm still mentally working on intersections involving NANs, especially
> if we want to keep track of signbits.  For now, let's be extra careful
> and only do things we're absolutely sure about.
>
> Later we may want to fold the intersect of [NAN,NAN] and say [3,5]
> with the posibility of NAN, to a NAN, but I'm not 100% sure.

The intersection of [NAN, NAN] and [3, 5] is empty.  The intersection
of [NAN, NAN] and VARYING is [NAN, NAN].

Not sure why you think NAN is somehow special?  I suppose that
[NAN, NAN] is actually implemented as ][ U NAN (empty range
plus aside NaN bit)

Richard.

>  As I've
> said before, setting varying is always a safe choice, because it means
> we know nothing and ranger won't attempt to optimize anything.
>
> gcc/ChangeLog:
>
>         * value-range.cc (early_nan_resolve): Remove.
>         (frange::intersect): Handle NANs.
> ---
>  gcc/value-range.cc | 35 ++++++++++++++++-------------------
>  1 file changed, 16 insertions(+), 19 deletions(-)
>
> diff --git a/gcc/value-range.cc b/gcc/value-range.cc
> index c9f42fe272c..9c561415971 100644
> --- a/gcc/value-range.cc
> +++ b/gcc/value-range.cc
> @@ -444,24 +444,6 @@ frange::normalize_kind ()
>    return false;
>  }
>
> -// If both operands are definitely NAN, do nothing as they combine
> -// perfectly.  If OTOH, only one is a NAN, set R to VARYING as they
> -// can't be neither unioned nor intersected.  Return TRUE if we
> -// changed anything.
> -
> -static inline bool
> -early_nan_resolve (frange &r, const frange &other)
> -{
> -  gcc_checking_assert (r.get_nan ().yes_p () || other.get_nan ().yes_p ());
> -
> -  // There's nothing to do for both NANs.
> -  if (r.get_nan ().yes_p () == other.get_nan ().yes_p ())
> -    return false;
> -  // ?? Perhaps the intersection of a NAN and anything is a NAN ??.
> -  r.set_varying (r.type ());
> -  return true;
> -}
> -
>  bool
>  frange::union_ (const vrange &v)
>  {
> @@ -532,8 +514,23 @@ frange::intersect (const vrange &v)
>        *this = r;
>        return true;
>      }
> +
> +  // If two NANs are not exactly the same, drop to an unknown NAN,
> +  // otherwise there's nothing to do.
> +  if (get_nan ().yes_p () && r.get_nan ().yes_p ())
> +    {
> +      if (m_props == r.m_props)
> +       return false;
> +
> +      *this = frange_nan (m_type);
> +      return true;
> +    }
> +  // ?? Perhaps the intersection of a NAN and anything is a NAN ??.
>    if (get_nan ().yes_p () || r.get_nan ().yes_p ())
> -    return early_nan_resolve (*this, r);
> +    {
> +      set_varying (m_type);
> +      return true;
> +    }
>
>    bool changed = m_props.intersect (r.m_props);
>
> --
> 2.37.1
>

Reply via email to