/* Floating point range operators.
   Copyright (C) 2022-2026 Free Software Foundation, Inc.
   Contributed by Aldy Hernandez <aldyh@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "insn-codes.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "optabs-tree.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "flags.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "calls.h"
#include "cfganal.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimple-walk.h"
#include "tree-cfg.h"
#include "wide-int.h"
#include "value-relation.h"
#include "range-op.h"
#include "range-op-mixed.h"

// Default definitions for floating point operators.

bool
range_operator::fold_range (frange &r, tree type,
			    const frange &op1, const frange &op2,
			    relation_trio trio) const
{
  if (empty_range_varying (r, type, op1, op2))
    return true;
  if (op1.known_isnan () || op2.known_isnan ())
    {
      r.set_nan (type);
      return true;
    }

  rv_fold (r, type,
	   op1.lower_bound (), op1.upper_bound (),
	   op2.lower_bound (), op2.upper_bound (), trio.op1_op2 ());

  if (r.known_isnan ())
    return true;
  if (op1.maybe_isnan () || op2.maybe_isnan ())
    r.update_nan ();

  // If the result has overflowed and flag_trapping_math, folding this
  // operation could elide an overflow or division by zero exception.
  // Avoid returning a singleton +-INF, to keep the propagators (DOM
  // and substitute_and_fold_engine) from folding.  See PR107608.
  if (flag_trapping_math
      && MODE_HAS_INFINITIES (TYPE_MODE (type))
      && r.known_isinf () && !op1.known_isinf () && !op2.known_isinf ())
    {
      REAL_VALUE_TYPE inf = r.lower_bound ();
      if (real_isneg (&inf))
	{
	  REAL_VALUE_TYPE min = real_min_representable (type);
	  r.set (type, inf, min);
	}
      else
	{
	  REAL_VALUE_TYPE max = real_max_representable (type);
	  r.set (type, max, inf);
	}
    }

  r.flush_denormals_to_zero ();

  return true;
}

// For a given operation, fold two sets of ranges into [lb, ub].
// MAYBE_NAN is set to TRUE if, in addition to any result in LB or
// UB, the final range has the possibility of a NAN.
void
range_operator::rv_fold (frange &r, tree type,
			 const REAL_VALUE_TYPE &,
			 const REAL_VALUE_TYPE &,
			 const REAL_VALUE_TYPE &,
			 const REAL_VALUE_TYPE &, relation_kind) const
{
  r.set (type, dconstninf, dconstinf, nan_state (true));
}

bool
range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
			    tree type ATTRIBUTE_UNUSED,
			    const frange &lh ATTRIBUTE_UNUSED,
			    const irange &rh ATTRIBUTE_UNUSED,
			    relation_trio) const
{
  return false;
}

bool
range_operator::fold_range (irange &r ATTRIBUTE_UNUSED,
			    tree type ATTRIBUTE_UNUSED,
			    const frange &lh ATTRIBUTE_UNUSED,
			    const frange &rh ATTRIBUTE_UNUSED,
			    relation_trio) const
{
  return false;
}

bool
range_operator::fold_range (frange &r ATTRIBUTE_UNUSED,
			    tree type ATTRIBUTE_UNUSED,
			    const irange &lh ATTRIBUTE_UNUSED,
			    const irange &rh ATTRIBUTE_UNUSED,
			    relation_trio) const
{
  return false;
}

bool
range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
			   tree type ATTRIBUTE_UNUSED,
			   const frange &lhs ATTRIBUTE_UNUSED,
			   const frange &op2 ATTRIBUTE_UNUSED,
			   relation_trio) const
{
  return false;
}

bool
range_operator::op1_range (frange &r ATTRIBUTE_UNUSED,
				 tree type ATTRIBUTE_UNUSED,
				 const irange &lhs ATTRIBUTE_UNUSED,
				 const frange &op2 ATTRIBUTE_UNUSED,
				 relation_trio) const
{
  return false;
}

bool
range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
			   tree type ATTRIBUTE_UNUSED,
			   const frange &lhs ATTRIBUTE_UNUSED,
			   const frange &op1 ATTRIBUTE_UNUSED,
			   relation_trio) const
{
  return false;
}

bool
range_operator::op2_range (frange &r ATTRIBUTE_UNUSED,
			   tree type ATTRIBUTE_UNUSED,
			   const irange &lhs ATTRIBUTE_UNUSED,
			   const frange &op1 ATTRIBUTE_UNUSED,
			   relation_trio) const
{
  return false;
}

relation_kind
range_operator::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED,
				  const frange &op1 ATTRIBUTE_UNUSED,
				  const frange &op2 ATTRIBUTE_UNUSED,
				  relation_kind) const
{
  return VREL_VARYING;
}

relation_kind
range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
				  const frange &op1 ATTRIBUTE_UNUSED,
				  const frange &op2 ATTRIBUTE_UNUSED,
				  relation_kind) const
{
  return VREL_VARYING;
}

relation_kind
range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
				  const frange &op1 ATTRIBUTE_UNUSED,
				  const frange &op2 ATTRIBUTE_UNUSED,
				  relation_kind) const
{
  return VREL_VARYING;
}

relation_kind
range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
				  const frange &op1 ATTRIBUTE_UNUSED,
				  const frange &op2 ATTRIBUTE_UNUSED,
				  relation_kind) const
{
  return VREL_VARYING;
}

relation_kind
range_operator::op1_op2_relation (const irange &,
				  const frange &,
				  const frange &) const
{
  return VREL_VARYING;
}


relation_kind
range_operator::op1_op2_relation (const frange &,
				  const frange &,
				  const frange &) const
{
  return VREL_VARYING;
}

// Return TRUE if OP1 and OP2 may be a NAN.

static inline bool
maybe_isnan (const frange &op1, const frange &op2)
{
  return op1.maybe_isnan () || op2.maybe_isnan ();
}

// Floating point version of relop_early_resolve that takes NANs into
// account.
//
// For relation opcodes, first try to see if the supplied relation
// forces a true or false result, and return that.
// Then check for undefined operands.  If none of this applies,
// return false.
//
// TRIO are the relations between operands as they appear in the IL.
// MY_REL is the relation that corresponds to the operator being
// folded.  For example, when attempting to fold x_3 == y_5, MY_REL is
// VREL_EQ, and if the statement is dominated by x_3 > y_5, then
// TRIO.op1_op2() is VREL_GT.

static inline bool
frelop_early_resolve (irange &r, tree type,
		      const frange &op1, const frange &op2,
		      relation_trio trio, relation_kind my_rel)
{
  relation_kind rel = trio.op1_op2 ();

  // If known relation is a complete subset of this relation, always
  // return true.  However, avoid doing this when NAN is a possibility
  // as we'll incorrectly fold conditions:
  //
  //   if (x_3 >= y_5)
  //     ;
  //   else
  //     ;; With NANs the relation here is basically VREL_UNLT, so we
  //     ;; can't fold the following:
  //     if (x_3 < y_5)
  if (!maybe_isnan (op1, op2) && relation_union (rel, my_rel) == my_rel)
    {
      r = range_true (type);
      return true;
    }

  // If known relation has no subset of this relation, always false.
  if (relation_intersect (rel, my_rel) == VREL_UNDEFINED)
    {
      r = range_false (type);
      return true;
    }

  // If either operand is undefined, return VARYING.
  if (empty_range_varying (r, type, op1, op2))
    return true;

  return false;
}

// Set VALUE to its next real value, or INF if the operation overflows.

void
frange_nextafter (enum machine_mode mode,
		  REAL_VALUE_TYPE &value,
		  const REAL_VALUE_TYPE &inf)
{
  if (MODE_COMPOSITE_P (mode)
      && (real_isdenormal (&value, mode) || real_iszero (&value)))
    {
      // IBM extended denormals only have DFmode precision.
      REAL_VALUE_TYPE tmp, tmp2;
      real_convert (&tmp2, DFmode, &value);
      real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
      real_convert (&value, mode, &tmp);
    }
  else
    {
      REAL_VALUE_TYPE tmp;
      real_nextafter (&tmp, REAL_MODE_FORMAT (mode), &value, &inf);
      value = tmp;
    }
}

// Like real_arithmetic, but round the result to INF if the operation
// produced inexact results.
//
// ?? There is still one problematic case, i387.  With
// -fexcess-precision=standard we perform most SF/DFmode arithmetic in
// XFmode (long_double_type_node), so that case is OK.  But without
// -mfpmath=sse, all the SF/DFmode computations are in XFmode
// precision (64-bit mantissa) and only occasionally rounded to
// SF/DFmode (when storing into memory from the 387 stack).  Maybe
// this is ok as well though it is just occasionally more precise. ??

void
frange_arithmetic (enum tree_code code, tree type,
		   REAL_VALUE_TYPE &result,
		   const REAL_VALUE_TYPE &op1,
		   const REAL_VALUE_TYPE &op2,
		   const REAL_VALUE_TYPE &inf)
{
  REAL_VALUE_TYPE value;
  enum machine_mode mode = TYPE_MODE (type);
  bool mode_composite = MODE_COMPOSITE_P (mode);

  bool inexact = real_arithmetic (&value, code, &op1, &op2);
  real_convert (&result, mode, &value);

  /* When rounding towards negative infinity, x + (-x) and
     x - x is -0 rather than +0 real_arithmetic computes.
     So, when we are looking for lower bound (inf is negative),
     use -0 rather than +0.  */
  if (flag_rounding_math
      && (code == PLUS_EXPR || code == MINUS_EXPR)
      && !inexact
      && real_iszero (&result)
      && !real_isneg (&result)
      && real_isneg (&inf))
    {
      REAL_VALUE_TYPE op2a = op2;
      if (code == PLUS_EXPR)
	op2a.sign ^= 1;
      if (real_isneg (&op1) == real_isneg (&op2a) && real_equal (&op1, &op2a))
	result.sign = 1;
    }

  // Be extra careful if there may be discrepancies between the
  // compile and runtime results.
  bool round = false;
  if (mode_composite)
    round = true;
  else
    {
      bool low = real_isneg (&inf);
      round = (low ? !real_less (&result, &value)
		   : !real_less (&value, &result));
      if (real_isinf (&result, !low)
	  && !real_isinf (&value)
	  && !flag_rounding_math)
	{
	  // Use just [+INF, +INF] rather than [MAX, +INF]
	  // even if value is larger than MAX and rounds to
	  // nearest to +INF.  Similarly just [-INF, -INF]
	  // rather than [-INF, +MAX] even if value is smaller
	  // than -MAX and rounds to nearest to -INF.
	  // Unless INEXACT is true, in that case we need some
	  // extra buffer.
	  if (!inexact)
	    round = false;
	  else
	    {
	      REAL_VALUE_TYPE tmp = result, tmp2;
	      frange_nextafter (mode, tmp, inf);
	      // TMP is at this point the maximum representable
	      // number.
	      real_arithmetic (&tmp2, MINUS_EXPR, &value, &tmp);
	      if (real_isneg (&tmp2) != low
		  && (REAL_EXP (&tmp2) - REAL_EXP (&tmp)
		      >= 2 - REAL_MODE_FORMAT (mode)->p))
		round = false;
	    }
	}
    }
  if (round && (inexact || !real_identical (&result, &value)))
    {
      if (mode_composite
	  && (real_isdenormal (&result, mode) || real_iszero (&result)))
	{
	  // IBM extended denormals only have DFmode precision.
	  REAL_VALUE_TYPE tmp, tmp2;
	  real_convert (&tmp2, DFmode, &value);
	  real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2, &inf);
	  real_convert (&result, mode, &tmp);
	}
      else
	frange_nextafter (mode, result, inf);
    }
  if (mode_composite)
    switch (code)
      {
      case PLUS_EXPR:
      case MINUS_EXPR:
	// ibm-ldouble-format documents 1ulp for + and -.
	frange_nextafter (mode, result, inf);
	break;
      case MULT_EXPR:
	// ibm-ldouble-format documents 2ulps for *.
	frange_nextafter (mode, result, inf);
	frange_nextafter (mode, result, inf);
	break;
      case RDIV_EXPR:
	// ibm-ldouble-format documents 3ulps for /.
	frange_nextafter (mode, result, inf);
	frange_nextafter (mode, result, inf);
	frange_nextafter (mode, result, inf);
	break;
      default:
	break;
      }
}

// Crop R to [-INF, MAX] where MAX is the maximum representable number
// for TYPE.

static inline void
frange_drop_inf (frange &r, tree type)
{
  REAL_VALUE_TYPE max = real_max_representable (type);
  frange tmp (type, r.lower_bound (), max);
  r.intersect (tmp);
}

// Crop R to [MIN, +INF] where MIN is the minimum representable number
// for TYPE.

static inline void
frange_drop_ninf (frange &r, tree type)
{
  REAL_VALUE_TYPE min = real_min_representable (type);
  frange tmp (type, min, r.upper_bound ());
  r.intersect (tmp);
}

// Crop R to [MIN, MAX] where MAX is the maximum representable number
// for TYPE and MIN the minimum representable number for TYPE.

static inline void
frange_drop_infs (frange &r, tree type)
{
  REAL_VALUE_TYPE max = real_max_representable (type);
  REAL_VALUE_TYPE min = real_min_representable (type);
  frange tmp (type, min, max);
  r.intersect (tmp);
}

// If zero is in R, make sure both -0.0 and +0.0 are in the range.

static inline void
frange_add_zeros (frange &r, tree type)
{
  if (r.undefined_p () || r.known_isnan ())
    return;

  if (HONOR_SIGNED_ZEROS (type)
      && (real_iszero (&r.lower_bound ()) || real_iszero (&r.upper_bound ())))
    {
      frange zero;
      zero.set_zero (type);
      r.union_ (zero);
    }
}

// Build a range that is <= VAL and store it in R.  Return TRUE if
// further changes may be needed for R, or FALSE if R is in its final
// form.

static bool
build_le (frange &r, tree type, const frange &val)
{
  gcc_checking_assert (!val.known_isnan ());

  REAL_VALUE_TYPE ninf = frange_val_min (type);
  r.set (type, ninf, val.upper_bound ());

  // Add both zeros if there's the possibility of zero equality.
  frange_add_zeros (r, type);

  return true;
}

// Build a range that is < VAL and store it in R.  Return TRUE if
// further changes may be needed for R, or FALSE if R is in its final
// form.

static bool
build_lt (frange &r, tree type, const frange &val)
{
  gcc_checking_assert (!val.known_isnan ());

  // < -INF is outside the range.
  if (real_isinf (&val.upper_bound (), 1))
    {
      if (HONOR_NANS (type))
	r.set_nan (type);
      else
	r.set_undefined ();
      return false;
    }

  REAL_VALUE_TYPE ninf = frange_val_min (type);
  REAL_VALUE_TYPE prev = val.upper_bound ();
  machine_mode mode = TYPE_MODE (type);
  // Default to the conservatively correct closed ranges for
  // MODE_COMPOSITE_P, otherwise use nextafter.  Note that for
  // !HONOR_INFINITIES, nextafter will yield -INF, but frange::set()
  // will crop the range appropriately.
  if (!MODE_COMPOSITE_P (mode))
    frange_nextafter (mode, prev, ninf);
  r.set (type, ninf, prev);
  return true;
}

// Build a range that is >= VAL and store it in R.  Return TRUE if
// further changes may be needed for R, or FALSE if R is in its final
// form.

static bool
build_ge (frange &r, tree type, const frange &val)
{
  gcc_checking_assert (!val.known_isnan ());

  REAL_VALUE_TYPE inf = frange_val_max (type);
  r.set (type, val.lower_bound (), inf);

  // Add both zeros if there's the possibility of zero equality.
  frange_add_zeros (r, type);

  return true;
}

// Build a range that is > VAL and store it in R.  Return TRUE if
// further changes may be needed for R, or FALSE if R is in its final
// form.

static bool
build_gt (frange &r, tree type, const frange &val)
{
  gcc_checking_assert (!val.known_isnan ());

  // > +INF is outside the range.
  if (real_isinf (&val.lower_bound (), 0))
    {
      if (HONOR_NANS (type))
	r.set_nan (type);
      else
	r.set_undefined ();
      return false;
    }

  REAL_VALUE_TYPE inf = frange_val_max (type);
  REAL_VALUE_TYPE next = val.lower_bound ();
  machine_mode mode = TYPE_MODE (type);
  // Default to the conservatively correct closed ranges for
  // MODE_COMPOSITE_P, otherwise use nextafter.  Note that for
  // !HONOR_INFINITIES, nextafter will yield +INF, but frange::set()
  // will crop the range appropriately.
  if (!MODE_COMPOSITE_P (mode))
    frange_nextafter (mode, next, inf);
  r.set (type, next, inf);
  return true;
}


bool
operator_identity::fold_range (frange &r, tree, const frange &op1,
			       const frange &, relation_trio) const
{
  r = op1;
  return true;
}

bool
operator_identity::op1_range (frange &r, tree, const frange &lhs,
			      const frange &, relation_trio) const
{
  r = lhs;
  return true;
}

bool
operator_cst::fold_range (frange &r, tree, const frange &op1,
			  const frange &, relation_trio) const
{
  r = op1;
  return true;
}

bool
operator_equal::op2_range (frange &r, tree type,
			   const irange &lhs, const frange &op1,
			   relation_trio rel) const
{
  return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
}

bool
operator_equal::fold_range (irange &r, tree type,
			    const frange &op1, const frange &op2,
			    relation_trio rel) const
{
  if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
    return true;

  if (op1.known_isnan () || op2.known_isnan ())
    r = range_false (type);
  // We can be sure the values are always equal or not if both ranges
  // consist of a single value, and then compare them.
  else if (op1.singleton_p () && op2.singleton_p ())
    {
      if (op1 == op2)
	r = range_true (type);
      // If one operand is -0.0 and other 0.0, they are still equal.
      else if (real_iszero (&op1.lower_bound ())
	       && real_iszero (&op2.lower_bound ()))
	r = range_true (type);
      else
	r = range_false (type);
    }
  else if (real_iszero (&op1.lower_bound ())
	   && real_iszero (&op1.upper_bound ())
	   && real_iszero (&op2.lower_bound ())
	   && real_iszero (&op2.upper_bound ())
	   && !maybe_isnan (op1, op2))
    // [-0.0, 0.0] == [-0.0, 0.0] or similar.
    r = range_true (type);
  else
    {
      // If ranges do not intersect, we know the range is not equal,
      // otherwise we don't know anything for sure.
      frange tmp = op1;
      tmp.intersect (op2);
      if (tmp.undefined_p ())
	{
	  // If one range is [whatever, -0.0] and another
	  // [0.0, whatever2], we don't know anything either,
	  // because -0.0 == 0.0.
	  if ((real_iszero (&op1.upper_bound ())
	       && real_iszero (&op2.lower_bound ()))
	      || (real_iszero (&op1.lower_bound ())
		  && real_iszero (&op2.upper_bound ())))
	    r = range_true_and_false (type);
	  else
	    r = range_false (type);
	}
      else
	r = range_true_and_false (type);
    }
  return true;
}

bool
operator_equal::op1_range (frange &r, tree type,
			   const irange &lhs,
			   const frange &op2,
			   relation_trio trio) const
{
  relation_kind rel = trio.op1_op2 ();
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of x == NAN is unreachable.
      if (op2.known_isnan ())
	r.set_undefined ();
      else
	{
	  // If it's true, the result is the same as OP2.
	  r = op2;
	  // Add both zeros if there's the possibility of zero equality.
	  frange_add_zeros (r, type);
	  // The TRUE side of op1 == op2 implies op1 is !NAN.
	  r.clear_nan ();
	}
      break;

    case BRS_FALSE:
      // The FALSE side of op1 == op1 implies op1 is a NAN.
      if (rel == VREL_EQ)
	r.set_nan (type);
      // On the FALSE side of x == NAN, we know nothing about x.
      else if (op2.known_isnan ())
	r.set_varying (type);
      // If the result is false, the only time we know anything is
      // if OP2 is a constant.
      else if (op2.singleton_p ()
	       || (!op2.maybe_isnan () && op2.zero_p ()))
	{
	  REAL_VALUE_TYPE tmp = op2.lower_bound ();
	  r.set (type, tmp, tmp, VR_ANTI_RANGE);
	}
      else
	r.set_varying (type);
      break;

    default:
      break;
    }
  return true;
}

// Check if the LHS range indicates a relation between OP1 and OP2.

relation_kind
operator_equal::op1_op2_relation (const irange &lhs, const frange &,
				  const frange &) const
{
  if (lhs.undefined_p ())
    return VREL_UNDEFINED;

  // FALSE = op1 == op2 indicates NE_EXPR.
  if (lhs.zero_p ())
    return VREL_NE;

  // TRUE = op1 == op2 indicates EQ_EXPR.
  if (!contains_zero_p (lhs))
    return VREL_EQ;
  return VREL_VARYING;
}

bool
operator_not_equal::fold_range (irange &r, tree type,
				const frange &op1, const frange &op2,
				relation_trio trio) const
{
  relation_kind rel = trio.op1_op2 ();

  // VREL_NE & NE_EXPR is always true, even with NANs.
  if (rel == VREL_NE)
    {
      r = range_true (type);
      return true;
    }
  if (rel == VREL_EQ && maybe_isnan (op1, op2))
    {
      // Avoid frelop_early_resolve() below as it could fold to FALSE
      // without regards to NANs.  This would be incorrect if trying
      // to fold x_5 != x_5 without prior knowledge of NANs.
    }
  else if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE))
    return true;

  // x != NAN is always TRUE.
  if (op1.known_isnan () || op2.known_isnan ())
    r = range_true (type);
  // We can be sure the values are always equal or not if both ranges
  // consist of a single value, and then compare them.
  else if (op1.singleton_p () && op2.singleton_p ())
    {
      if (op1 == op2)
	r = range_false (type);
      // If one operand is -0.0 and other 0.0, they are still equal.
      else if (real_iszero (&op1.lower_bound ())
	       && real_iszero (&op2.lower_bound ()))
	r = range_false (type);
      else
	r = range_true (type);
    }
  else if (real_iszero (&op1.lower_bound ())
	   && real_iszero (&op1.upper_bound ())
	   && real_iszero (&op2.lower_bound ())
	   && real_iszero (&op2.upper_bound ())
	   && !maybe_isnan (op1, op2))
    // [-0.0, 0.0] != [-0.0, 0.0] or similar.
    r = range_false (type);
  else
    {
      // If ranges do not intersect, we know the range is not equal,
      // otherwise we don't know anything for sure.
      frange tmp = op1;
      tmp.intersect (op2);
      if (tmp.undefined_p ())
	{
	  // If one range is [whatever, -0.0] and another
	  // [0.0, whatever2], we don't know anything either,
	  // because -0.0 == 0.0.
	  if ((real_iszero (&op1.upper_bound ())
	       && real_iszero (&op2.lower_bound ()))
	      || (real_iszero (&op1.lower_bound ())
		  && real_iszero (&op2.upper_bound ())))
	    r = range_true_and_false (type);
	  else
	    r = range_true (type);
	}
      else
	r = range_true_and_false (type);
    }
  return true;
}

bool
operator_not_equal::op1_range (frange &r, tree type,
			       const irange &lhs,
			       const frange &op2,
			       relation_trio trio) const
{
  relation_kind rel = trio.op1_op2 ();
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // If the result is true, the only time we know anything is if
      // OP2 is a constant.
      if (op2.singleton_p ())
	{
	  // This is correct even if op1 is NAN, because the following
	  // range would be ~[tmp, tmp] with the NAN property set to
	  // maybe (VARYING).
	  REAL_VALUE_TYPE tmp = op2.lower_bound ();
	  r.set (type, tmp, tmp, VR_ANTI_RANGE);
	}
      // The TRUE side of op1 != op1 implies op1 is NAN.
      else if (rel == VREL_EQ)
	r.set_nan (type);
      else
	r.set_varying (type);
      break;

    case BRS_FALSE:
      // The FALSE side of x != NAN is impossible.
      if (op2.known_isnan ())
	r.set_undefined ();
      else
	{
	  // If it's false, the result is the same as OP2.
	  r = op2;
	  // Add both zeros if there's the possibility of zero equality.
	  frange_add_zeros (r, type);
	  // The FALSE side of op1 != op2 implies op1 is !NAN.
	  r.clear_nan ();
	}
      break;

    default:
      break;
    }
  return true;
}

bool
operator_not_equal::op2_range (frange &r, tree type,
			       const irange &lhs,
			       const frange &op1,
			       relation_trio trio) const
{
  return op1_range (r, type, lhs, op1, trio);
}

// Check if the LHS range indicates a relation between OP1 and OP2.

relation_kind
operator_not_equal::op1_op2_relation (const irange &lhs, const frange &,
				      const frange &) const
{
  if (lhs.undefined_p ())
    return VREL_UNDEFINED;

  // FALSE = op1 != op2  indicates EQ_EXPR.
  if (lhs.zero_p ())
    return VREL_EQ;

  // TRUE = op1 != op2  indicates NE_EXPR.
  if (!contains_zero_p (lhs))
    return VREL_NE;
  return VREL_VARYING;
}

bool
operator_lt::fold_range (irange &r, tree type,
			 const frange &op1, const frange &op2,
			 relation_trio trio) const
{
  if (frelop_early_resolve (r, type, op1, op2, trio, VREL_LT))
    return true;

  if (op1.known_isnan ()
      || op2.known_isnan ()
      || !real_less (&op1.lower_bound (), &op2.upper_bound ()))
    r = range_false (type);
  else if (!maybe_isnan (op1, op2)
	   && real_less (&op1.upper_bound (), &op2.lower_bound ()))
    r = range_true (type);
  else
    r = range_true_and_false (type);
  return true;
}

bool
operator_lt::op1_range (frange &r,
			tree type,
			const irange &lhs,
			const frange &op2,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of x < NAN is unreachable.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (op2.undefined_p ())
	return false;
      else if (build_lt (r, type, op2))
	{
	  r.clear_nan ();
	  // x < y implies x is not +INF.
	  frange_drop_inf (r, type);
	}
      break;

    case BRS_FALSE:
      // On the FALSE side of x < NAN, we know nothing about x.
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else
	build_ge (r, type, op2);
      break;

    default:
      break;
    }
  return true;
}

bool
operator_lt::op2_range (frange &r,
			tree type,
			const irange &lhs,
			const frange &op1,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of NAN < x is unreachable.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_gt (r, type, op1))
	{
	  r.clear_nan ();
	  // x < y implies y is not -INF.
	  frange_drop_ninf (r, type);
	}
      break;

    case BRS_FALSE:
      // On the FALSE side of NAN < x, we know nothing about x.
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else
	build_le (r, type, op1);
      break;

    default:
      break;
    }
  return true;
}


// Check if the LHS range indicates a relation between OP1 and OP2.

relation_kind
operator_lt::op1_op2_relation (const irange &lhs, const frange &,
			       const frange &) const
{
  if (lhs.undefined_p ())
    return VREL_UNDEFINED;

  // FALSE = op1 < op2 indicates GE_EXPR.
  if (lhs.zero_p ())
    return VREL_GE;

  // TRUE = op1 < op2 indicates LT_EXPR.
  if (!contains_zero_p (lhs))
    return VREL_LT;
  return VREL_VARYING;
}

bool
operator_le::fold_range (irange &r, tree type,
			 const frange &op1, const frange &op2,
			 relation_trio rel) const
{
  if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
    return true;

  if (op1.known_isnan ()
      || op2.known_isnan ()
      || !real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
    r = range_false (type);
  else if (!maybe_isnan (op1, op2)
	   && real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
    r = range_true (type);
  else
    r = range_true_and_false (type);
  return true;
}

bool
operator_le::op1_range (frange &r,
			tree type,
			const irange &lhs,
			const frange &op2,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of x <= NAN is unreachable.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (op2.undefined_p ())
	return false;
      else if (build_le (r, type, op2))
	r.clear_nan ();
      break;

    case BRS_FALSE:
      // On the FALSE side of x <= NAN, we know nothing about x.
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else
	build_gt (r, type, op2);
      break;

    default:
      break;
    }
  return true;
}

bool
operator_le::op2_range (frange &r,
			tree type,
			const irange &lhs,
			const frange &op1,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of NAN <= x is unreachable.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_ge (r, type, op1))
	r.clear_nan ();
      break;

    case BRS_FALSE:
      // On the FALSE side of NAN <= x, we know nothing about x.
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else if (op1.undefined_p ())
	return false;
      else
	build_lt (r, type, op1);
      break;

    default:
      break;
    }
  return true;
}

// Check if the LHS range indicates a relation between OP1 and OP2.

relation_kind
operator_le::op1_op2_relation (const irange &lhs, const frange &,
			       const frange &) const
{
  if (lhs.undefined_p ())
    return VREL_UNDEFINED;

  // FALSE = op1 <= op2 indicates GT_EXPR.
  if (lhs.zero_p ())
    return VREL_GT;

  // TRUE = op1 <= op2 indicates LE_EXPR.
  if (!contains_zero_p (lhs))
    return VREL_LE;
  return VREL_VARYING;
}

bool
operator_gt::fold_range (irange &r, tree type,
			 const frange &op1, const frange &op2,
			 relation_trio trio) const
{
  if (frelop_early_resolve (r, type, op1, op2, trio, VREL_GT))
    return true;

  if (op1.known_isnan ()
      || op2.known_isnan ()
      || !real_compare (GT_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
    r = range_false (type);
  else if (!maybe_isnan (op1, op2)
	   && real_compare (GT_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
    r = range_true (type);
  else
    r = range_true_and_false (type);
  return true;
}

bool
operator_gt::op1_range (frange &r,
			tree type,
			const irange &lhs,
			const frange &op2,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of x > NAN is unreachable.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (op2.undefined_p ())
	return false;
      else if (build_gt (r, type, op2))
	{
	  r.clear_nan ();
	  // x > y implies x is not -INF.
	  frange_drop_ninf (r, type);
	}
      break;

    case BRS_FALSE:
      // On the FALSE side of x > NAN, we know nothing about x.
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else if (op2.undefined_p ())
	return false;
      else
	build_le (r, type, op2);
      break;

    default:
      break;
    }
  return true;
}

bool
operator_gt::op2_range (frange &r,
			tree type,
			const irange &lhs,
			const frange &op1,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of NAN > x is unreachable.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_lt (r, type, op1))
	{
	  r.clear_nan ();
	  // x > y implies y is not +INF.
	  frange_drop_inf (r, type);
	}
      break;

    case BRS_FALSE:
      // On The FALSE side of NAN > x, we know nothing about x.
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else if (op1.undefined_p ())
	return false;
      else
	build_ge (r, type, op1);
      break;

    default:
      break;
    }
  return true;
}

// Check if the LHS range indicates a relation between OP1 and OP2.

relation_kind
operator_gt::op1_op2_relation (const irange &lhs, const frange &,
			       const frange &) const
{
  if (lhs.undefined_p ())
    return VREL_UNDEFINED;

  // FALSE = op1 > op2 indicates LE_EXPR.
  if (lhs.zero_p ())
    return VREL_LE;

  // TRUE = op1 > op2 indicates GT_EXPR.
  if (!contains_zero_p (lhs))
    return VREL_GT;
  return VREL_VARYING;
}

bool
operator_ge::fold_range (irange &r, tree type,
			 const frange &op1, const frange &op2,
			 relation_trio rel) const
{
  if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
    return true;

  if (op1.known_isnan ()
      || op2.known_isnan ()
      || !real_compare (GE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
    r = range_false (type);
  else if (!maybe_isnan (op1, op2)
	   && real_compare (GE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
    r = range_true (type);
  else
    r = range_true_and_false (type);
  return true;
}

bool
operator_ge::op1_range (frange &r,
			tree type,
			const irange &lhs,
			const frange &op2,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of x >= NAN is unreachable.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (op2.undefined_p ())
	return false;
      else if (build_ge (r, type, op2))
	r.clear_nan ();
      break;

    case BRS_FALSE:
      // On the FALSE side of x >= NAN, we know nothing about x.
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else if (op2.undefined_p ())
	return false;
      else
	build_lt (r, type, op2);
      break;

    default:
      break;
    }
  return true;
}

bool
operator_ge::op2_range (frange &r, tree type,
			const irange &lhs,
			const frange &op1,
			relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of NAN >= x is unreachable.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_le (r, type, op1))
	r.clear_nan ();
      break;

    case BRS_FALSE:
      // On the FALSE side of NAN >= x, we know nothing about x.
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else if (op1.undefined_p ())
	return false;
      else
	build_gt (r, type, op1);
      break;

    default:
      break;
    }
  return true;
}

// Check if the LHS range indicates a relation between OP1 and OP2.

relation_kind
operator_ge::op1_op2_relation (const irange &lhs, const frange &,
			       const frange &) const
{
  if (lhs.undefined_p ())
    return VREL_UNDEFINED;

  // FALSE = op1 >= op2 indicates LT_EXPR.
  if (lhs.zero_p ())
    return VREL_LT;

  // TRUE = op1 >= op2 indicates GE_EXPR.
  if (!contains_zero_p (lhs))
    return VREL_GE;
  return VREL_VARYING;
}

// UNORDERED_EXPR comparison.

class foperator_unordered : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio = TRIO_VARYING) const final override;
  bool op1_range (frange &r, tree type,
		  const irange &lhs, const frange &op2,
		  relation_trio = TRIO_VARYING) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs, const frange &op1,
		  relation_trio rel = TRIO_VARYING) const final override
  {
    return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
  }
} fop_unordered;

bool
foperator_unordered::fold_range (irange &r, tree type,
				 const frange &op1, const frange &op2,
				 relation_trio) const
{
  // UNORDERED is TRUE if either operand is a NAN.
  if (op1.known_isnan () || op2.known_isnan ())
    r = range_true (type);
  // UNORDERED is FALSE if neither operand is a NAN.
  else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
    r = range_false (type);
  else
    r = range_true_and_false (type);
  return true;
}

bool
foperator_unordered::op1_range (frange &r, tree type,
				const irange &lhs,
				const frange &op2,
				relation_trio trio) const
{
  relation_kind rel = trio.op1_op2 ();
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // Since at least one operand must be NAN, if one of them is
      // not, the other must be.
      if (rel == VREL_EQ || !op2.maybe_isnan ())
	r.set_nan (type);
      else
	r.set_varying (type);
      break;

    case BRS_FALSE:
      // A false UNORDERED means both operands are !NAN, so it's
      // impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else
	{
	  r.set_varying (type);
	  r.clear_nan ();
	}
      break;

    default:
      break;
    }
  return true;
}

// ORDERED_EXPR comparison.

class foperator_ordered : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio = TRIO_VARYING) const final override;
  bool op1_range (frange &r, tree type,
		  const irange &lhs, const frange &op2,
		  relation_trio = TRIO_VARYING) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs, const frange &op1,
		  relation_trio rel = TRIO_VARYING) const final override
  {
    return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
  }
} fop_ordered;

bool
foperator_ordered::fold_range (irange &r, tree type,
			       const frange &op1, const frange &op2,
			       relation_trio) const
{
  if (op1.known_isnan () || op2.known_isnan ())
    r = range_false (type);
  else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
    r = range_true (type);
  else
    r = range_true_and_false (type);
  return true;
}

bool
foperator_ordered::op1_range (frange &r, tree type,
			      const irange &lhs,
			      const frange &op2,
			      relation_trio trio) const
{
  relation_kind rel = trio.op1_op2 ();
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // The TRUE side of ORDERED means both operands are !NAN, so
      // it's impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else
	{
	  r.set_varying (type);
	  r.clear_nan ();
	}
      break;

    case BRS_FALSE:
      // The FALSE side of op1 ORDERED op1 implies op1 is NAN.
      if (rel == VREL_EQ)
	r.set_nan (type);
      else
	r.set_varying (type);
      break;

    default:
      break;
    }
  return true;
}

bool
operator_negate::fold_range (frange &r, tree type,
			     const frange &op1, const frange &op2,
			     relation_trio) const
{
  if (empty_range_varying (r, type, op1, op2))
    return true;
  if (op1.known_isnan ())
    {
      bool sign;
      if (op1.nan_signbit_p (sign))
	r.set_nan (type, !sign);
      else
	r.set_nan (type);
      return true;
    }

  REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
  REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
  lh_lb = real_value_negate (&lh_lb);
  lh_ub = real_value_negate (&lh_ub);
  r.set (type, lh_ub, lh_lb);
  if (op1.maybe_isnan ())
    {
      bool sign;
      if (op1.nan_signbit_p (sign))
	r.update_nan (!sign);
      else
	r.update_nan ();
    }
  else
    r.clear_nan ();
  return true;
}

bool
operator_negate::op1_range (frange &r, tree type,
			    const frange &lhs, const frange &op2,
			    relation_trio rel) const
{
  return fold_range (r, type, lhs, op2, rel);
}

bool
operator_abs::fold_range (frange &r, tree type,
			  const frange &op1, const frange &op2,
			  relation_trio) const
{
  if (empty_range_varying (r, type, op1, op2))
    return true;
  if (op1.known_isnan ())
    {
      r.set_nan (type, /*sign=*/false);
      return true;
    }

  const REAL_VALUE_TYPE lh_lb = op1.lower_bound ();
  const REAL_VALUE_TYPE lh_ub = op1.upper_bound ();
  // Handle the easy case where everything is positive.
  if (real_compare (GE_EXPR, &lh_lb, &dconst0)
      && !real_iszero (&lh_lb, /*sign=*/true)
      && !op1.maybe_isnan (/*sign=*/true))
    {
      r = op1;
      return true;
    }

  REAL_VALUE_TYPE min = real_value_abs (&lh_lb);
  REAL_VALUE_TYPE max = real_value_abs (&lh_ub);
  // If the range contains zero then we know that the minimum value in the
  // range will be zero.
  if (real_compare (LE_EXPR, &lh_lb, &dconst0)
      && real_compare (GE_EXPR, &lh_ub, &dconst0))
    {
      if (real_compare (GT_EXPR, &min, &max))
	max = min;
      min = dconst0;
    }
  else
    {
      // If the range was reversed, swap MIN and MAX.
      if (real_compare (GT_EXPR, &min, &max))
	std::swap (min, max);
    }

  r.set (type, min, max);
  if (op1.maybe_isnan ())
    r.update_nan (/*sign=*/false);
  else
    r.clear_nan ();
  return true;
}

bool
operator_abs::op1_range (frange &r, tree type,
			 const frange &lhs, const frange &op2,
			 relation_trio) const
{
  if (empty_range_varying (r, type, lhs, op2))
    return true;
  if (lhs.known_isnan ())
    {
      r.set_nan (type);
      return true;
    }

  // Start with the positives because negatives are an impossible result.
  frange positives (type, dconst0, frange_val_max (type));
  positives.update_nan (/*sign=*/false);
  positives.intersect (lhs);
  r = positives;
  // Add -NAN if relevant.
  if (r.maybe_isnan ())
    {
      frange neg_nan;
      neg_nan.set_nan (type, true);
      r.union_ (neg_nan);
    }
  if (r.known_isnan () || r.undefined_p ())
    return true;
  // Then add the negative of each pair:
  // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
  frange negatives (type, real_value_negate (&positives.upper_bound ()),
		    real_value_negate (&positives.lower_bound ()));
  negatives.clear_nan ();
  r.union_ (negatives);
  return true;
}

class foperator_unordered_lt : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio trio = TRIO_VARYING) const final override
  {
    if (op1.known_isnan () || op2.known_isnan ())
      {
	r = range_true (type);
	return true;
      }
    frange op1_no_nan = op1;
    frange op2_no_nan = op2;
    if (op1.maybe_isnan ())
      op1_no_nan.clear_nan ();
    if (op2.maybe_isnan ())
      op2_no_nan.clear_nan ();
    if (!range_op_handler (LT_EXPR).fold_range (r, type, op1_no_nan,
						op2_no_nan, trio))
      return false;
    // The result is the same as the ordered version when the
    // comparison is true or when the operands cannot be NANs.
    if (!maybe_isnan (op1, op2) || r == range_true (type))
      return true;
    else
      {
	r = range_true_and_false (type);
	return true;
      }
  }
  bool op1_range (frange &r, tree type,
		  const irange &lhs,
		  const frange &op2,
		  relation_trio trio) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs,
		  const frange &op1,
		  relation_trio trio) const final override;
} fop_unordered_lt;

bool
foperator_unordered_lt::op1_range (frange &r, tree type,
				   const irange &lhs,
				   const frange &op2,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else if (op2.undefined_p ())
	return false;
      else
	build_lt (r, type, op2);
      break;

    case BRS_FALSE:
      // A false UNORDERED_LT means both operands are !NAN, so it's
      // impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (op2.undefined_p ())
	return false;
      else if (build_ge (r, type, op2))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

bool
foperator_unordered_lt::op2_range (frange &r, tree type,
				   const irange &lhs,
				   const frange &op1,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else if (op1.undefined_p ())
	return false;
      else
	build_gt (r, type, op1);
      break;

    case BRS_FALSE:
      // A false UNORDERED_LT means both operands are !NAN, so it's
      // impossible for op1 to be a NAN.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_le (r, type, op1))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

class foperator_unordered_le : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio trio = TRIO_VARYING) const final override
  {
    if (op1.known_isnan () || op2.known_isnan ())
      {
	r = range_true (type);
	return true;
      }
    frange op1_no_nan = op1;
    frange op2_no_nan = op2;
    if (op1.maybe_isnan ())
      op1_no_nan.clear_nan ();
    if (op2.maybe_isnan ())
      op2_no_nan.clear_nan ();
    if (!range_op_handler (LE_EXPR).fold_range (r, type, op1_no_nan,
						op2_no_nan, trio))
      return false;
    // The result is the same as the ordered version when the
    // comparison is true or when the operands cannot be NANs.
    if (!maybe_isnan (op1, op2) || r == range_true (type))
      return true;
    else
      {
	r = range_true_and_false (type);
	return true;
      }
  }
  bool op1_range (frange &r, tree type,
		  const irange &lhs, const frange &op2,
		  relation_trio = TRIO_VARYING) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs, const frange &op1,
		  relation_trio = TRIO_VARYING) const final override;
} fop_unordered_le;

bool
foperator_unordered_le::op1_range (frange &r, tree type,
				   const irange &lhs, const frange &op2,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else if (op2.undefined_p ())
	return false;
      else
	build_le (r, type, op2);
      break;

    case BRS_FALSE:
      // A false UNORDERED_LE means both operands are !NAN, so it's
      // impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (build_gt (r, type, op2))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

bool
foperator_unordered_le::op2_range (frange &r,
				   tree type,
				   const irange &lhs,
				   const frange &op1,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else if (op1.undefined_p ())
	return false;
      else
	build_ge (r, type, op1);
      break;

    case BRS_FALSE:
      // A false UNORDERED_LE means both operands are !NAN, so it's
      // impossible for op1 to be a NAN.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_lt (r, type, op1))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

class foperator_unordered_gt : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio trio = TRIO_VARYING) const final override
  {
    if (op1.known_isnan () || op2.known_isnan ())
      {
	r = range_true (type);
	return true;
      }
    frange op1_no_nan = op1;
    frange op2_no_nan = op2;
    if (op1.maybe_isnan ())
      op1_no_nan.clear_nan ();
    if (op2.maybe_isnan ())
      op2_no_nan.clear_nan ();
    if (!range_op_handler (GT_EXPR).fold_range (r, type, op1_no_nan,
						op2_no_nan, trio))
      return false;
    // The result is the same as the ordered version when the
    // comparison is true or when the operands cannot be NANs.
    if (!maybe_isnan (op1, op2) || r == range_true (type))
      return true;
    else
      {
	r = range_true_and_false (type);
	return true;
      }
  }
  bool op1_range (frange &r, tree type,
		  const irange &lhs, const frange &op2,
		  relation_trio = TRIO_VARYING) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs, const frange &op1,
		  relation_trio = TRIO_VARYING) const final override;
} fop_unordered_gt;

bool
foperator_unordered_gt::op1_range (frange &r,
				   tree type,
				   const irange &lhs,
				   const frange &op2,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else if (op2.undefined_p ())
	return false;
      else
	build_gt (r, type, op2);
      break;

    case BRS_FALSE:
      // A false UNORDERED_GT means both operands are !NAN, so it's
      // impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (op2.undefined_p ())
	return false;
      else if (build_le (r, type, op2))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

bool
foperator_unordered_gt::op2_range (frange &r,
				   tree type,
				   const irange &lhs,
				   const frange &op1,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else if (op1.undefined_p ())
	return false;
      else
	build_lt (r, type, op1);
      break;

    case BRS_FALSE:
      // A false UNORDERED_GT means both operands are !NAN, so it's
      // impossible for op1 to be a NAN.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_ge (r, type, op1))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

class foperator_unordered_ge : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio trio = TRIO_VARYING) const final override
  {
    if (op1.known_isnan () || op2.known_isnan ())
      {
	r = range_true (type);
	return true;
      }
    frange op1_no_nan = op1;
    frange op2_no_nan = op2;
    if (op1.maybe_isnan ())
      op1_no_nan.clear_nan ();
    if (op2.maybe_isnan ())
      op2_no_nan.clear_nan ();
    if (!range_op_handler (GE_EXPR).fold_range (r, type, op1_no_nan,
						op2_no_nan, trio))
      return false;
    // The result is the same as the ordered version when the
    // comparison is true or when the operands cannot be NANs.
    if (!maybe_isnan (op1, op2) || r == range_true (type))
      return true;
    else
      {
	r = range_true_and_false (type);
	return true;
      }
  }
  bool op1_range (frange &r, tree type,
		  const irange &lhs, const frange &op2,
		  relation_trio = TRIO_VARYING) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs, const frange &op1,
		  relation_trio = TRIO_VARYING) const final override;
} fop_unordered_ge;

bool
foperator_unordered_ge::op1_range (frange &r,
				   tree type,
				   const irange &lhs,
				   const frange &op2,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op2.maybe_isnan ())
	r.set_varying (type);
      else if (op2.undefined_p ())
	return false;
      else
	build_ge (r, type, op2);
      break;

    case BRS_FALSE:
      // A false UNORDERED_GE means both operands are !NAN, so it's
      // impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else if (op2.undefined_p ())
	return false;
      else if (build_lt (r, type, op2))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

bool
foperator_unordered_ge::op2_range (frange &r, tree type,
				   const irange &lhs,
				   const frange &op1,
				   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      if (op1.maybe_isnan ())
	r.set_varying (type);
      else if (op1.undefined_p ())
	return false;
      else
	build_le (r, type, op1);
      break;

    case BRS_FALSE:
      // A false UNORDERED_GE means both operands are !NAN, so it's
      // impossible for op1 to be a NAN.
      if (op1.known_isnan ())
	r.set_undefined ();
      else if (op1.undefined_p ())
	return false;
      else if (build_gt (r, type, op1))
	r.clear_nan ();
      break;

    default:
      break;
    }
  return true;
}

class foperator_unordered_equal : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio trio = TRIO_VARYING) const final override
  {
    if (op1.known_isnan () || op2.known_isnan ())
      {
	r = range_true (type);
	return true;
      }
    frange op1_no_nan = op1;
    frange op2_no_nan = op2;
    if (op1.maybe_isnan ())
      op1_no_nan.clear_nan ();
    if (op2.maybe_isnan ())
      op2_no_nan.clear_nan ();
    if (!range_op_handler (EQ_EXPR).fold_range (r, type, op1_no_nan,
						op2_no_nan, trio))
      return false;
    // The result is the same as the ordered version when the
    // comparison is true or when the operands cannot be NANs.
    if (!maybe_isnan (op1, op2) || r == range_true (type))
      return true;
    else
      {
	r = range_true_and_false (type);
	return true;
      }
  }
  bool op1_range (frange &r, tree type,
		  const irange &lhs, const frange &op2,
		  relation_trio = TRIO_VARYING) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs, const frange &op1,
		  relation_trio rel = TRIO_VARYING) const final override
  {
    return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
  }
} fop_unordered_equal;

bool
foperator_unordered_equal::op1_range (frange &r, tree type,
				      const irange &lhs,
				      const frange &op2,
				      relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // If it's true, the result is the same as OP2 plus a NAN.
      r = op2;
      // Add both zeros if there's the possibility of zero equality.
      frange_add_zeros (r, type);
      // Add the possibility of a NAN.
      r.update_nan ();
      break;

    case BRS_FALSE:
      // A false UNORDERED_EQ means both operands are !NAN, so it's
      // impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else
	{
	  // The false side indicates !NAN and not equal.  We can at least
	  // represent !NAN.
	  r.set_varying (type);
	  r.clear_nan ();
	}
      break;

    default:
      break;
    }
  return true;
}

class foperator_ltgt : public range_operator
{
  using range_operator::fold_range;
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  bool fold_range (irange &r, tree type,
		   const frange &op1, const frange &op2,
		   relation_trio trio = TRIO_VARYING) const final override
  {
    if (op1.known_isnan () || op2.known_isnan ())
      {
	r = range_false (type);
	return true;
      }
    frange op1_no_nan = op1;
    frange op2_no_nan = op2;
    if (op1.maybe_isnan ())
      op1_no_nan.clear_nan ();
    if (op2.maybe_isnan ())
      op2_no_nan.clear_nan ();
    if (!range_op_handler (NE_EXPR).fold_range (r, type, op1_no_nan,
						op2_no_nan, trio))
      return false;
    // The result is the same as the ordered version when the
    // comparison is true or when the operands cannot be NANs.
    if (!maybe_isnan (op1, op2) || r == range_false (type))
      return true;
    else
      {
	r = range_true_and_false (type);
	return true;
      }
  }
  bool op1_range (frange &r, tree type,
		  const irange &lhs, const frange &op2,
		  relation_trio = TRIO_VARYING) const final override;
  bool op2_range (frange &r, tree type,
		  const irange &lhs, const frange &op1,
		  relation_trio rel = TRIO_VARYING) const final override
  {
    return op1_range (r, type, lhs, op1, rel.swap_op1_op2 ());
  }
} fop_ltgt;

bool
foperator_ltgt::op1_range (frange &r, tree type,
			   const irange &lhs,
			   const frange &op2,
			   relation_trio) const
{
  switch (get_bool_state (r, lhs, type))
    {
    case BRS_TRUE:
      // A true LTGT means both operands are !NAN, so it's
      // impossible for op2 to be a NAN.
      if (op2.known_isnan ())
	r.set_undefined ();
      else
	{
	  // The true side indicates !NAN and not equal.  We can at least
	  // represent !NAN.
	  r.set_varying (type);
	  r.clear_nan ();
	}
      break;

    case BRS_FALSE:
      // If it's false, the result is the same as OP2 plus a NAN.
      r = op2;
      // Add both zeros if there's the possibility of zero equality.
      frange_add_zeros (r, type);
      // Add the possibility of a NAN.
      r.update_nan ();
      break;

    default:
      break;
    }
  return true;
}

// Final tweaks for float binary op op1_range/op2_range.
// Return TRUE if the operation is performed and a valid range is available.

static bool
float_binary_op_range_finish (bool ret, frange &r, tree type,
			      const frange &lhs, bool div_op2 = false)
{
  if (!ret)
    return false;

  // If we get a known NAN from reverse op, it means either that
  // the other operand was known NAN (in that case we know nothing),
  // or the reverse operation introduced a known NAN.
  // Say for lhs = op1 * op2 if lhs is [-0, +0] and op2 is too,
  // 0 / 0 is known NAN.  Just punt in that case.
  // If NANs aren't honored, we get for 0 / 0 UNDEFINED, so punt as well.
  // Or if lhs is a known NAN, we also don't know anything.
  if (r.known_isnan () || lhs.known_isnan () || r.undefined_p ())
    {
      r.set_varying (type);
      return true;
    }

  // If lhs isn't NAN, then neither operand could be NAN,
  // even if the reverse operation does introduce a maybe_nan.
  if (!lhs.maybe_isnan ())
    {
      r.clear_nan ();
      if (div_op2
	  ? !(real_compare (LE_EXPR, &lhs.lower_bound (), &dconst0)
	      && real_compare (GE_EXPR, &lhs.upper_bound (), &dconst0))
	  : !(real_isinf (&lhs.lower_bound ())
	      || real_isinf (&lhs.upper_bound ())))
	// For reverse + or - or * or op1 of /, if result is finite, then
	// r must be finite too, as X + INF or X - INF or X * INF or
	// INF / X is always +-INF or NAN.  For op2 of /, if result is
	// non-zero and not NAN, r must be finite, as X / INF is always
	// 0 or NAN.
	frange_drop_infs (r, type);
    }
  // If lhs is a maybe or known NAN, the operand could be
  // NAN.
  else
    r.update_nan ();
  return true;
}

// True if [lb, ub] is [+-0, +-0].
static bool
zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
{
  return real_iszero (&lb) && real_iszero (&ub);
}

// True if +0 or -0 is in [lb, ub] range.
static bool
contains_zero_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
{
  return (real_compare (LE_EXPR, &lb, &dconst0)
	  && real_compare (GE_EXPR, &ub, &dconst0));
}

// True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
static bool
singleton_inf_p (const REAL_VALUE_TYPE &lb, const REAL_VALUE_TYPE &ub)
{
  return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
}

// Return -1 if binary op result must have sign bit set,
// 1 if binary op result must have sign bit clear,
// 0 otherwise.
// Sign bit of binary op result is exclusive or of the
// operand's sign bits.
static int
signbit_known_p (const REAL_VALUE_TYPE &lh_lb, const REAL_VALUE_TYPE &lh_ub,
		 const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub)
{
  if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
      && real_isneg (&rh_lb) == real_isneg (&rh_ub))
    {
      if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
	return 1;
      else
	return -1;
    }
  return 0;
}

// Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
// signbit_known.
static void
zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
{
  ub = lb = dconst0;
  if (signbit_known <= 0)
    lb = dconstm0;
  if (signbit_known < 0)
    ub = lb;
}

// Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending on
// signbit_known.
static void
inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
{
  if (signbit_known > 0)
    ub = lb = dconstinf;
  else if (signbit_known < 0)
    ub = lb = dconstninf;
  else
    {
      lb = dconstninf;
      ub = dconstinf;
    }
}

// Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
// signbit_known.
static void
zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, int signbit_known)
{
  if (signbit_known > 0)
    {
      lb = dconst0;
      ub = dconstinf;
    }
  else if (signbit_known < 0)
    {
      lb = dconstninf;
      ub = dconstm0;
    }
  else
    {
      lb = dconstninf;
      ub = dconstinf;
    }
}

/* Extend the LHS range by 1ulp in each direction.  For op1_range
   or op2_range of binary operations just computing the inverse
   operation on ranges isn't sufficient.  Consider e.g.
   [1., 1.] = op1 + [1., 1.].  op1's range is not [0., 0.], but
   [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for
   which adding 1. to it results in 1. after rounding to nearest.
   So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp)
   in each direction.  See PR109008 for more details.  */

static frange
float_widen_lhs_range (tree type, const frange &lhs)
{
  frange ret = lhs;
  if (lhs.known_isnan ())
    return ret;
  REAL_VALUE_TYPE lb = lhs.lower_bound ();
  REAL_VALUE_TYPE ub = lhs.upper_bound ();
  if (real_isfinite (&lb))
    {
      frange_nextafter (TYPE_MODE (type), lb, dconstninf);
      if (real_isinf (&lb))
	{
	  /* For -DBL_MAX, instead of -Inf use
	     nexttoward (-DBL_MAX, -LDBL_MAX) in a hypothetical
	     wider type with the same mantissa precision but larger
	     exponent range; it is outside of range of double values,
	     but makes it clear it is just one ulp larger rather than
	     infinite amount larger.  */
	  lb = dconstm1;
	  SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
	}
      if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
	{
	  /* If not -frounding-math nor IBM double double, actually widen
	     just by 0.5ulp rather than 1ulp.  */
	  REAL_VALUE_TYPE tem;
	  real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb);
	  real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2);
	}
    }
  if (real_isfinite (&ub))
    {
      frange_nextafter (TYPE_MODE (type), ub, dconstinf);
      if (real_isinf (&ub))
	{
	  /* For DBL_MAX similarly.  */
	  ub = dconst1;
	  SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1);
	}
      if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type)))
	{
	  /* If not -frounding-math nor IBM double double, actually widen
	     just by 0.5ulp rather than 1ulp.  */
	  REAL_VALUE_TYPE tem;
	  real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub);
	  real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2);
	}
    }
  /* Temporarily disable -ffinite-math-only, so that frange::set doesn't
     reduce the range back to real_min_representable (type) as lower bound
     or real_max_representable (type) as upper bound.  */
  bool save_flag_finite_math_only = flag_finite_math_only;
  flag_finite_math_only = false;
  ret.set (type, lb, ub, lhs.get_nan_state ());
  flag_finite_math_only = save_flag_finite_math_only;
  return ret;
}

bool
operator_plus::op1_range (frange &r, tree type, const frange &lhs,
			  const frange &op2, relation_trio) const
{
  if (lhs.undefined_p ())
    return false;
  range_op_handler minus (MINUS_EXPR);
  if (!minus)
    return false;
  frange wlhs = float_widen_lhs_range (type, lhs);
  return float_binary_op_range_finish (minus.fold_range (r, type, wlhs, op2),
				       r, type, wlhs);
}

bool
operator_plus::op2_range (frange &r, tree type,
			  const frange &lhs, const frange &op1,
			  relation_trio) const
{
  return op1_range (r, type, lhs, op1);
}

void
operator_plus::rv_fold (frange &r, tree type,
			const REAL_VALUE_TYPE &lh_lb,
			const REAL_VALUE_TYPE &lh_ub,
			const REAL_VALUE_TYPE &rh_lb,
			const REAL_VALUE_TYPE &rh_ub,
			relation_kind) const
{
  REAL_VALUE_TYPE lb, ub;
  bool maybe_nan = false;

  frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
  frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);

  // [-INF] + [+INF] = NAN
  if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
    maybe_nan = true;
  // [+INF] + [-INF] = NAN
  else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
    maybe_nan = true;

  // Handle possible NANs by saturating to the appropriate INF if only
  // one end is a NAN.  If both ends are a NAN, just return a NAN.
  bool lb_nan = real_isnan (&lb);
  bool ub_nan = real_isnan (&ub);
  if (lb_nan && ub_nan)
    {
      r.set_nan (type);
      return;
    }
  if (lb_nan)
    lb = dconstninf;
  else if (ub_nan)
    ub = dconstinf;
  r.set (type, lb, ub, nan_state (maybe_nan));
}


bool
operator_minus::op1_range (frange &r, tree type,
			   const frange &lhs, const frange &op2,
			   relation_trio) const
{
  if (lhs.undefined_p ())
    return false;
  frange wlhs = float_widen_lhs_range (type, lhs);
  return float_binary_op_range_finish (
	      range_op_handler (PLUS_EXPR).fold_range (r, type, wlhs, op2),
	      r, type, wlhs);
}

bool
operator_minus::op2_range (frange &r, tree type,
			   const frange &lhs, const frange &op1,
			   relation_trio) const
{
  if (lhs.undefined_p ())
    return false;
  frange wlhs = float_widen_lhs_range (type, lhs);
  return float_binary_op_range_finish (fold_range (r, type, op1, wlhs),
				       r, type, wlhs);
}

void
operator_minus::rv_fold (frange &r, tree type,
			 const REAL_VALUE_TYPE &lh_lb,
			 const REAL_VALUE_TYPE &lh_ub,
			 const REAL_VALUE_TYPE &rh_lb,
			 const REAL_VALUE_TYPE &rh_ub,
			 relation_kind) const
{
  REAL_VALUE_TYPE lb, ub;
  bool maybe_nan = false;

  frange_arithmetic (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
  frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);

  // [+INF] - [+INF] = NAN
  if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
    maybe_nan = true;
  // [-INF] - [-INF] = NAN
  else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
    maybe_nan = true;

  // Handle possible NANs by saturating to the appropriate INF if only
  // one end is a NAN.  If both ends are a NAN, just return a NAN.
  bool lb_nan = real_isnan (&lb);
  bool ub_nan = real_isnan (&ub);
  if (lb_nan && ub_nan)
    {
      r.set_nan (type);
      return;
    }
  if (lb_nan)
    lb = dconstninf;
  else if (ub_nan)
    ub = dconstinf;
  r.set (type, lb, ub, nan_state (maybe_nan));
}


// Given CP[0] to CP[3] floating point values rounded to -INF,
// set LB to the smallest of them (treating -0 as smaller to +0).
// Given CP[4] to CP[7] floating point values rounded to +INF,
// set UB to the largest of them (treating -0 as smaller to +0).

static void
find_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
	    const REAL_VALUE_TYPE (&cp)[8])
{
  lb = cp[0];
  ub = cp[4];
  for (int i = 1; i < 4; ++i)
    {
      if (real_less (&cp[i], &lb)
	  || (real_iszero (&lb) && real_isnegzero (&cp[i])))
	lb = cp[i];
      if (real_less (&ub, &cp[i + 4])
	  || (real_isnegzero (&ub) && real_iszero (&cp[i + 4])))
	ub = cp[i + 4];
    }
}


bool
operator_mult::op1_range (frange &r, tree type,
			  const frange &lhs, const frange &op2,
			  relation_trio) const
{
  if (lhs.undefined_p ())
    return false;
  range_op_handler rdiv (RDIV_EXPR);
  if (!rdiv)
    return false;
  frange wlhs = float_widen_lhs_range (type, lhs);
  bool ret = rdiv.fold_range (r, type, wlhs, op2);
  if (ret == false)
    return false;
  if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
    return float_binary_op_range_finish (ret, r, type, wlhs);
  const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
  const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
  const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
  const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
  if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op2_lb, op2_ub))
      || ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
	  && (real_isinf (&op2_lb) || real_isinf (&op2_ub))))
    {
      // If both lhs and op2 could be zeros or both could be infinities,
      // we don't know anything about op1 except maybe for the sign
      // and perhaps if it can be NAN or not.
      REAL_VALUE_TYPE lb, ub;
      int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
      zero_to_inf_range (lb, ub, signbit_known);
      r.set (type, lb, ub);
    }
  // Otherwise, if op2 is a singleton INF and lhs doesn't include INF,
  // or if lhs must be zero and op2 doesn't include zero, it would be
  // UNDEFINED, while rdiv.fold_range computes a zero or singleton INF
  // range.  Those are supersets of UNDEFINED, so let's keep that way.
  return float_binary_op_range_finish (ret, r, type, wlhs);
}

bool
operator_mult::op2_range (frange &r, tree type,
			  const frange &lhs, const frange &op1,
			  relation_trio) const
{
  return op1_range (r, type, lhs, op1);
}

void
operator_mult::rv_fold (frange &r, tree type,
			const REAL_VALUE_TYPE &lh_lb,
			const REAL_VALUE_TYPE &lh_ub,
			const REAL_VALUE_TYPE &rh_lb,
			const REAL_VALUE_TYPE &rh_ub,
			relation_kind kind) const
{
  bool is_square
    = (kind == VREL_EQ
       && real_equal (&lh_lb, &rh_lb)
       && real_equal (&lh_ub, &rh_ub)
       && real_isneg (&lh_lb) == real_isneg (&rh_lb)
       && real_isneg (&lh_ub) == real_isneg (&rh_ub));
  REAL_VALUE_TYPE lb, ub;
  bool maybe_nan = false;
  // x * x never produces a new NAN and we only multiply the same
  // values, so the 0 * INF problematic cases never appear there.
  if (!is_square)
    {
      // [+-0, +-0] * [+INF,+INF] (or [-INF,-INF] or swapped is a known NAN.
      if ((zero_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub))
	  || (zero_p (rh_lb, rh_ub) && singleton_inf_p (lh_lb, lh_ub)))
	{
	  r.set_nan (type);
	  return;
	}

      // Otherwise, if one range includes zero and the other ends with +-INF,
      // it is a maybe NAN.
      if ((contains_zero_p (lh_lb, lh_ub)
	   && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
	  || (contains_zero_p (rh_lb, rh_ub)
	      && (real_isinf (&lh_lb) || real_isinf (&lh_ub))))
	{
	  maybe_nan = true;

	  int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);

	  // If one of the ranges that includes INF is singleton
	  // and the other range includes zero, the resulting
	  // range is INF and NAN, because the 0 * INF boundary
	  // case will be NAN, but already nextafter (0, 1) * INF
	  // is INF.
	  if (singleton_inf_p (lh_lb, lh_ub)
	      || singleton_inf_p (rh_lb, rh_ub))
	    {
	      inf_range (lb, ub, signbit_known);
	      r.set (type, lb, ub, nan_state (true));
	      return;
	    }

	  // If one of the multiplicands must be zero, the resulting
	  // range is +-0 and NAN.
	  if (zero_p (lh_lb, lh_ub) || zero_p (rh_lb, rh_ub))
	    {
	      zero_range (lb, ub, signbit_known);
	      r.set (type, lb, ub, nan_state (true));
	      return;
	    }

	  // Otherwise one of the multiplicands could be
	  // [0.0, nextafter (0.0, 1.0)] and the [DBL_MAX, INF]
	  // or similarly with different signs.  0.0 * DBL_MAX
	  // is still 0.0, nextafter (0.0, 1.0) * INF is still INF,
	  // so if the signs are always the same or always different,
	  // result is [+0.0, +INF] or [-INF, -0.0], otherwise VARYING.
	  zero_to_inf_range (lb, ub, signbit_known);
	  r.set (type, lb, ub, nan_state (true));
	  return;
	}
    }

  REAL_VALUE_TYPE cp[8];
  // Do a cross-product.  At this point none of the multiplications
  // should produce a NAN.
  frange_arithmetic (MULT_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
  frange_arithmetic (MULT_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
  if (is_square)
    {
      // For x * x we can just do max (lh_lb * lh_lb, lh_ub * lh_ub)
      // as maximum and -0.0 as minimum if 0.0 is in the range,
      // otherwise min (lh_lb * lh_lb, lh_ub * lh_ub).
      // -0.0 rather than 0.0 because VREL_EQ doesn't prove that
      // x and y are bitwise equal, just that they compare equal.
      if (contains_zero_p (lh_lb, lh_ub))
	{
	  if (real_isneg (&lh_lb) == real_isneg (&lh_ub))
	    cp[1] = dconst0;
	  else
	    cp[1] = dconstm0;
	}
      else
	cp[1] = cp[0];
      cp[2] = cp[0];
      cp[5] = cp[4];
      cp[6] = cp[4];
    }
  else
    {
      frange_arithmetic (MULT_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
      frange_arithmetic (MULT_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
      frange_arithmetic (MULT_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
      frange_arithmetic (MULT_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
    }
  frange_arithmetic (MULT_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
  frange_arithmetic (MULT_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);

  find_range (lb, ub, cp);

  gcc_checking_assert (!real_isnan (&lb));
  gcc_checking_assert (!real_isnan (&ub));
  r.set (type, lb, ub, nan_state (maybe_nan));
}


class foperator_div : public range_operator
{
  using range_operator::op1_range;
  using range_operator::op2_range;
public:
  virtual bool op1_range (frange &r, tree type,
			  const frange &lhs,
			  const frange &op2,
			  relation_trio = TRIO_VARYING) const final override
  {
    if (lhs.undefined_p ())
      return false;
    frange wlhs = float_widen_lhs_range (type, lhs);
    bool ret = range_op_handler (MULT_EXPR).fold_range (r, type, wlhs, op2);
    if (!ret)
      return ret;
    if (wlhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
      return float_binary_op_range_finish (ret, r, type, wlhs);
    const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
    const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
    const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
    const REAL_VALUE_TYPE &op2_ub = op2.upper_bound ();
    if ((contains_zero_p (lhs_lb, lhs_ub)
	 && (real_isinf (&op2_lb) || real_isinf (&op2_ub)))
	|| ((contains_zero_p (op2_lb, op2_ub))
	    && (real_isinf (&lhs_lb) || real_isinf (&lhs_ub))))
      {
	// If both lhs could be zero and op2 infinity or vice versa,
	// we don't know anything about op1 except maybe for the sign
	// and perhaps if it can be NAN or not.
	REAL_VALUE_TYPE lb, ub;
	int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op2_lb, op2_ub);
	zero_to_inf_range (lb, ub, signbit_known);
	r.set (type, lb, ub);
      }
    return float_binary_op_range_finish (ret, r, type, wlhs);
  }
  virtual bool op2_range (frange &r, tree type,
			  const frange &lhs,
			  const frange &op1,
			  relation_trio = TRIO_VARYING) const final override
  {
    if (lhs.undefined_p ())
      return false;
    frange wlhs = float_widen_lhs_range (type, lhs);
    bool ret = fold_range (r, type, op1, wlhs);
    if (!ret)
      return ret;
    if (wlhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
      return float_binary_op_range_finish (ret, r, type, wlhs, true);
    const REAL_VALUE_TYPE &lhs_lb = wlhs.lower_bound ();
    const REAL_VALUE_TYPE &lhs_ub = wlhs.upper_bound ();
    const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
    const REAL_VALUE_TYPE &op1_ub = op1.upper_bound ();
    if ((contains_zero_p (lhs_lb, lhs_ub) && contains_zero_p (op1_lb, op1_ub))
	|| ((real_isinf (&lhs_lb) || real_isinf (&lhs_ub))
	    && (real_isinf (&op1_lb) || real_isinf (&op1_ub))))
      {
	// If both lhs and op1 could be zeros or both could be infinities,
	// we don't know anything about op2 except maybe for the sign
	// and perhaps if it can be NAN or not.
	REAL_VALUE_TYPE lb, ub;
	int signbit_known = signbit_known_p (lhs_lb, lhs_ub, op1_lb, op1_ub);
	zero_to_inf_range (lb, ub, signbit_known);
	r.set (type, lb, ub);
      }
    return float_binary_op_range_finish (ret, r, type, wlhs, true);
  }
private:
  void rv_fold (frange &r, tree type,
		const REAL_VALUE_TYPE &lh_lb,
		const REAL_VALUE_TYPE &lh_ub,
		const REAL_VALUE_TYPE &rh_lb,
		const REAL_VALUE_TYPE &rh_ub,
		relation_kind) const final override
  {
    // +-0.0 / +-0.0 or +-INF / +-INF is a known NAN.
    if ((zero_p (lh_lb, lh_ub) && zero_p (rh_lb, rh_ub))
	|| (singleton_inf_p (lh_lb, lh_ub) && singleton_inf_p (rh_lb, rh_ub)))
      {
	r.set_nan (type);
	return;
      }

    REAL_VALUE_TYPE lb, ub;
    bool maybe_nan = false;
    // If +-0.0 is in both ranges, it is a maybe NAN.
    if (contains_zero_p (lh_lb, lh_ub) && contains_zero_p (rh_lb, rh_ub))
      maybe_nan = true;
    // If +-INF is in both ranges, it is a maybe NAN.
    else if ((real_isinf (&lh_lb) || real_isinf (&lh_ub))
	     && (real_isinf (&rh_lb) || real_isinf (&rh_ub)))
      maybe_nan = true;

    int signbit_known = signbit_known_p (lh_lb, lh_ub, rh_lb, rh_ub);

    // If dividend must be zero, the range is just +-0
    // (including if the divisor is +-INF).
    // If divisor must be +-INF, the range is just +-0
    // (including if the dividend is zero).
    if (zero_p (lh_lb, lh_ub) || singleton_inf_p (rh_lb, rh_ub))
      {
	zero_range (lb, ub, signbit_known);
	r.set (type, lb, ub, nan_state (maybe_nan));
	return;
      }

    // If divisor must be zero, the range is just +-INF
    // (including if the dividend is +-INF).
    // If dividend must be +-INF, the range is just +-INF
    // (including if the dividend is zero).
    if (zero_p (rh_lb, rh_ub) || singleton_inf_p (lh_lb, lh_ub))
      {
	inf_range (lb, ub, signbit_known);
	r.set (type, lb, ub, nan_state (maybe_nan));
	return;
      }

    // Otherwise if both operands may be zero, divisor could be
    // nextafter(0.0, +-1.0) and dividend +-0.0
    // in which case result is going to INF or vice versa and
    // result +0.0.  So, all we can say for that case is if the
    // signs of divisor and dividend are always the same we have
    // [+0.0, +INF], if they are always different we have
    // [-INF, -0.0].  If they vary, VARYING.
    // If both may be +-INF, divisor could be INF and dividend FLT_MAX,
    // in which case result is going to INF or vice versa and
    // result +0.0.  So, all we can say for that case is if the
    // signs of divisor and dividend are always the same we have
    // [+0.0, +INF], if they are always different we have
    // [-INF, -0.0].  If they vary, VARYING.
    if (maybe_nan)
      {
	zero_to_inf_range (lb, ub, signbit_known);
	r.set (type, lb, ub, nan_state (maybe_nan));
	return;
      }

    REAL_VALUE_TYPE cp[8];
    // Do a cross-division.  At this point none of the divisions should
    // produce a NAN.
    frange_arithmetic (RDIV_EXPR, type, cp[0], lh_lb, rh_lb, dconstninf);
    frange_arithmetic (RDIV_EXPR, type, cp[1], lh_lb, rh_ub, dconstninf);
    frange_arithmetic (RDIV_EXPR, type, cp[2], lh_ub, rh_lb, dconstninf);
    frange_arithmetic (RDIV_EXPR, type, cp[3], lh_ub, rh_ub, dconstninf);
    frange_arithmetic (RDIV_EXPR, type, cp[4], lh_lb, rh_lb, dconstinf);
    frange_arithmetic (RDIV_EXPR, type, cp[5], lh_lb, rh_ub, dconstinf);
    frange_arithmetic (RDIV_EXPR, type, cp[6], lh_ub, rh_lb, dconstinf);
    frange_arithmetic (RDIV_EXPR, type, cp[7], lh_ub, rh_ub, dconstinf);

    find_range (lb, ub, cp);

    // If divisor may be zero (but is not known to be only zero),
    // and dividend can't be zero, the range can go up to -INF or +INF
    // depending on the signs.
    if (contains_zero_p (rh_lb, rh_ub))
      {
	if (signbit_known <= 0)
	  real_inf (&lb, true);
	if (signbit_known >= 0)
	  real_inf (&ub, false);
      }

    gcc_checking_assert (!real_isnan (&lb));
    gcc_checking_assert (!real_isnan (&ub));
    r.set (type, lb, ub, nan_state (maybe_nan));
  }
} fop_div;

bool
operator_cast::fold_range (frange &r, tree type, const frange &op1,
			   const frange &, relation_trio) const
{
  REAL_VALUE_TYPE lb, ub;
  enum machine_mode mode = TYPE_MODE (type);
  bool mode_composite = MODE_COMPOSITE_P (mode);

  if (empty_range_varying (r, type, op1, op1))
    return true;
  if (!MODE_HAS_NANS (mode) && op1.maybe_isnan ())
    {
      r.set_varying (type);
      return true;
    }
  if (op1.known_isnan ())
    {
      r.set_nan (type);
      return true;
    }

  const REAL_VALUE_TYPE &lh_lb = op1.lower_bound ();
  const REAL_VALUE_TYPE &lh_ub = op1.upper_bound ();
  real_convert (&lb, mode, &lh_lb);
  real_convert (&ub, mode, &lh_ub);

  if (flag_rounding_math)
    {
      if (real_less (&lh_lb, &lb))
	{
	  if (mode_composite
	      && (real_isdenormal (&lb, mode) || real_iszero (&lb)))
	    {
	      // IBM extended denormals only have DFmode precision.
	      REAL_VALUE_TYPE tmp, tmp2;
	      real_convert (&tmp2, DFmode, &lh_lb);
	      real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2,
			      &dconstninf);
	      real_convert (&lb, mode, &tmp);
	    }
	  else
	    frange_nextafter (mode, lb, dconstninf);
	}
      if (real_less (&ub, &lh_ub))
	{
	  if (mode_composite
	      && (real_isdenormal (&ub, mode) || real_iszero (&ub)))
	    {
	      // IBM extended denormals only have DFmode precision.
	      REAL_VALUE_TYPE tmp, tmp2;
	      real_convert (&tmp2, DFmode, &lh_ub);
	      real_nextafter (&tmp, REAL_MODE_FORMAT (DFmode), &tmp2,
			      &dconstinf);
	      real_convert (&ub, mode, &tmp);
	    }
	  else
	    frange_nextafter (mode, ub, dconstinf);
	}
    }

  r.set (type, lb, ub, op1.get_nan_state ());

  if (flag_trapping_math
      && MODE_HAS_INFINITIES (TYPE_MODE (type))
      && r.known_isinf ()
      && !op1.known_isinf ())
    {
      REAL_VALUE_TYPE inf = r.lower_bound ();
      if (real_isneg (&inf))
	{
	  REAL_VALUE_TYPE min = real_min_representable (type);
	  r.set (type, inf, min);
	}
      else
	{
	  REAL_VALUE_TYPE max = real_max_representable (type);
	  r.set (type, max, inf);
	}
    }

  r.flush_denormals_to_zero ();
  return true;
}

// Implement fold for a cast from float to another float.
bool
operator_cast::op1_range (frange &r, tree type, const frange &lhs,
			  const frange &op2, relation_trio) const
{
  if (lhs.undefined_p ())
    return false;
  tree lhs_type = lhs.type ();
  enum machine_mode mode = TYPE_MODE (type);
  enum machine_mode lhs_mode = TYPE_MODE (lhs_type);
  frange wlhs;
  bool rm;
  if (REAL_MODE_FORMAT (mode)->ieee_bits
      && REAL_MODE_FORMAT (lhs_mode)->ieee_bits
      && (REAL_MODE_FORMAT (lhs_mode)->ieee_bits
	  >= REAL_MODE_FORMAT (mode)->ieee_bits)
      && pow2p_hwi (REAL_MODE_FORMAT (mode)->ieee_bits))
    {
      /* If the cast is widening from IEEE exchange mode to
	 wider exchange mode or extended mode, no need to extend
	 the range on reverse operation.  */
      rm = false;
      wlhs = lhs;
    }
  else
    {
      rm = true;
      wlhs = float_widen_lhs_range (lhs_type, lhs);
    }
  auto save_flag_rounding_math = flag_rounding_math;
  flag_rounding_math = rm;
  bool ret = float_binary_op_range_finish (fold_range (r, type, wlhs, op2),
					   r, type, lhs);
  flag_rounding_math = save_flag_rounding_math;
  return ret;
}

// Implement fold for a cast from float to an int.
bool
operator_cast::fold_range (irange &r, tree type, const frange &op1,
			   const irange &, relation_trio) const
{
  if (empty_range_varying (r, type, op1, op1))
    return true;
  if (op1.maybe_isnan () || op1.maybe_isinf ())
    {
      r.set_varying (type);
      return true;
    }
  REAL_VALUE_TYPE lb, ub;
  real_trunc (&lb, VOIDmode, &op1.lower_bound ());
  real_trunc (&ub, VOIDmode, &op1.upper_bound ());
  REAL_VALUE_TYPE l, u;
  l = real_value_from_int_cst (NULL_TREE, TYPE_MIN_VALUE (type));
  if (real_less (&lb, &l))
    {
      r.set_varying (type);
      return true;
    }
  u = real_value_from_int_cst (NULL_TREE, TYPE_MAX_VALUE (type));
  if (real_less (&u, &ub))
    {
      r.set_varying (type);
      return true;
    }
  bool fail = false;
  wide_int wlb = real_to_integer (&lb, &fail, TYPE_PRECISION (type));
  wide_int wub = real_to_integer (&ub, &fail, TYPE_PRECISION (type));
  if (fail)
    {
      r.set_varying (type);
      return true;
    }
  r.set (type, wlb, wub);
  return true;
}

// Implement op1_range for a cast from float to an int.
bool
operator_cast::op1_range (frange &r, tree type, const irange &lhs,
			  const frange &, relation_trio) const
{
  if (lhs.undefined_p ())
    return false;
  REAL_VALUE_TYPE lb, lbo, ub, ubo;
  wide_int lhs_lb = lhs.lower_bound ();
  wide_int lhs_ub = lhs.upper_bound ();
  tree lhs_type = lhs.type ();
  enum machine_mode mode = TYPE_MODE (type);
  real_from_integer (&lbo, VOIDmode, lhs_lb, TYPE_SIGN (lhs_type));
  real_from_integer (&ubo, VOIDmode, lhs_ub, TYPE_SIGN (lhs_type));
  real_convert (&lb, mode, &lbo);
  real_convert (&ub, mode, &ubo);
  if (real_identical (&lb, &lbo))
    {
      /* If low bound is exactly representable in type,
	 use nextafter (lb - 1., +inf).  */
      real_arithmetic (&lb, PLUS_EXPR, &lbo, &dconstm1);
      real_convert (&lb, mode, &lb);
      if (!real_identical (&lb, &lbo))
	frange_nextafter (mode, lb, dconstinf);
      if (real_identical (&lb, &lbo))
	frange_nextafter (mode, lb, dconstninf);
    }
  else if (real_less (&lbo, &lb))
    frange_nextafter (mode, lb, dconstninf);
  if (real_identical (&ub, &ubo))
    {
      /* If upper bound is exactly representable in type,
	 use nextafter (ub + 1., -inf).  */
      real_arithmetic (&ub, PLUS_EXPR, &ubo, &dconst1);
      real_convert (&ub, mode, &ub);
      if (!real_identical (&ub, &ubo))
	frange_nextafter (mode, ub, dconstninf);
      if (real_identical (&ub, &ubo))
	frange_nextafter (mode, ub, dconstinf);
    }
  else if (real_less (&ub, &ubo))
    frange_nextafter (mode, ub, dconstinf);
  r.set (type, lb, ub, nan_state (false));
  return true;
}

// Implement fold for a cast from int to a float.
bool
operator_cast::fold_range (frange &r, tree type, const irange &op1,
			   const frange &, relation_trio) const
{
  if (empty_range_varying (r, type, op1, op1))
    return true;
  REAL_VALUE_TYPE lb, ub;
  wide_int op1_lb = op1.lower_bound ();
  wide_int op1_ub = op1.upper_bound ();
  tree op1_type = op1.type ();
  enum machine_mode mode = flag_rounding_math ? VOIDmode : TYPE_MODE (type);
  real_from_integer (&lb, mode, op1_lb, TYPE_SIGN (op1_type));
  real_from_integer (&ub, mode, op1_ub, TYPE_SIGN (op1_type));
  if (flag_rounding_math)
    {
      REAL_VALUE_TYPE lbo = lb, ubo = ub;
      mode = TYPE_MODE (type);
      real_convert (&lb, mode, &lb);
      real_convert (&ub, mode, &ub);
      if (real_less (&lbo, &lb))
	frange_nextafter (mode, lb, dconstninf);
      if (real_less (&ub, &ubo))
	frange_nextafter (mode, ub, dconstinf);
    }
  r.set (type, lb, ub, nan_state (false));
  frange_drop_infs (r, type);
  if (r.undefined_p ())
    r.set_varying (type);
  return true;
}

// Implement op1_range for a cast from int to a float.
bool
operator_cast::op1_range (irange &r, tree type, const frange &lhs,
			  const irange &, relation_trio) const
{
  if (lhs.undefined_p ())
    return false;
  if (lhs.known_isnan ())
    {
      r.set_varying (type);
      return true;
    }
  REAL_VALUE_TYPE lb = lhs.lower_bound ();
  REAL_VALUE_TYPE ub = lhs.upper_bound ();
  enum machine_mode mode = TYPE_MODE (lhs.type ());
  frange_nextafter (mode, lb, dconstninf);
  frange_nextafter (mode, ub, dconstinf);
  if (flag_rounding_math)
    {
      real_floor (&lb, mode, &lb);
      real_ceil (&ub, mode, &ub);
    }
  else
    {
      real_trunc (&lb, mode, &lb);
      real_trunc (&ub, mode, &ub);
    }
  REAL_VALUE_TYPE l, u;
  wide_int wlb, wub;
  l = real_value_from_int_cst (NULL_TREE, TYPE_MIN_VALUE (type));
  if (real_less (&lb, &l))
    wlb = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
  else
    {
      bool fail = false;
      wlb = real_to_integer (&lb, &fail, TYPE_PRECISION (type));
      if (fail)
	wlb = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    }
  u = real_value_from_int_cst (NULL_TREE, TYPE_MAX_VALUE (type));
  if (real_less (&u, &ub))
    wub = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
  else
    {
      bool fail = false;
      wub = real_to_integer (&ub, &fail, TYPE_PRECISION (type));
      if (fail)
	wub = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    }
  r.set (type, wlb, wub);
  return true;
}

// Initialize any float operators to the primary table

void
range_op_table::initialize_float_ops ()
{
  set (UNLE_EXPR, fop_unordered_le);
  set (UNLT_EXPR, fop_unordered_lt);
  set (UNGE_EXPR, fop_unordered_ge);
  set (UNGT_EXPR, fop_unordered_gt);
  set (UNEQ_EXPR, fop_unordered_equal);
  set (ORDERED_EXPR, fop_ordered);
  set (UNORDERED_EXPR, fop_unordered);
  set (LTGT_EXPR, fop_ltgt);
  set (RDIV_EXPR, fop_div);
}

#if CHECKING_P
#include "selftest.h"

namespace selftest
{

// Build an frange from string endpoints.

static inline frange
frange_float (const char *lb, const char *ub, tree type = float_type_node)
{
  REAL_VALUE_TYPE min, max;
  gcc_assert (real_from_string (&min, lb) == 0);
  gcc_assert (real_from_string (&max, ub) == 0);
  return frange (type, min, max);
}

void
range_op_float_tests ()
{
  frange r, r0, r1;
  frange trange (float_type_node);

  // negate([-5, +10]) => [-10, 5]
  r0 = frange_float ("-5", "10");
  range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
  ASSERT_EQ (r, frange_float ("-10", "5"));

  // negate([0, 1] -NAN) => [-1, -0] +NAN
  r0 = frange_float ("0", "1");
  r0.update_nan (true);
  range_op_handler (NEGATE_EXPR).fold_range (r, float_type_node, r0, trange);
  r1 = frange_float ("-1", "-0");
  r1.update_nan (false);
  ASSERT_EQ (r, r1);

  // [-INF,+INF] + [-INF,+INF] could be a NAN.
  range_op_handler plus (PLUS_EXPR);
  r0.set_varying (float_type_node);
  r1.set_varying (float_type_node);
  r0.clear_nan ();
  r1.clear_nan ();
  plus.fold_range (r, float_type_node, r0, r1);
  if (HONOR_NANS (float_type_node))
    ASSERT_TRUE (r.maybe_isnan ());
}

} // namespace selftest

#endif // CHECKING_P
