/* Code for GIMPLE range op related routines.
   Copyright (C) 2019-2024 Free Software Foundation, Inc.
   Contributed by Andrew MacLeod <amacleod@redhat.com>
   and 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 "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "optabs-tree.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "wide-int.h"
#include "fold-const.h"
#include "case-cfn-macros.h"
#include "omp-general.h"
#include "cfgloop.h"
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
#include "langhooks.h"
#include "vr-values.h"
#include "range.h"
#include "value-query.h"
#include "gimple-range.h"
#include "attr-fnspec.h"
#include "realmpfr.h"

// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
// on the statement.  For efficiency, it is an error to not pass in enough
// elements for the vector.  Return the number of ssa-names.

unsigned
gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
{
  tree ssa;
  int count = 0;

  gimple_range_op_handler handler (stmt);
  if (handler)
    {
      gcc_checking_assert (vec_size >= 2);
      if ((ssa = gimple_range_ssa_p (handler.operand1 ())))
	vec[count++] = ssa;
      if ((ssa = gimple_range_ssa_p (handler.operand2 ())))
	vec[count++] = ssa;
    }
  else if (is_a<gassign *> (stmt)
	   && gimple_assign_rhs_code (stmt) == COND_EXPR)
    {
      gcc_checking_assert (vec_size >= 3);
      gassign *st = as_a<gassign *> (stmt);
      if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
	vec[count++] = ssa;
      if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
	vec[count++] = ssa;
      if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
	vec[count++] = ssa;
    }
  return count;
}

// Return the base of the RHS of an assignment.

static tree
gimple_range_base_of_assignment (const gimple *stmt)
{
  gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
  tree op1 = gimple_assign_rhs1 (stmt);
  if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
    return get_base_address (TREE_OPERAND (op1, 0));
  return op1;
}

// If statement is supported by range-ops, set the CODE and return the TYPE.

static inline enum tree_code
get_code (gimple *s)
{
  if (const gassign *ass = dyn_cast<const gassign *> (s))
    return gimple_assign_rhs_code (ass);
  if (const gcond *cond = dyn_cast<const gcond *> (s))
    return gimple_cond_code (cond);
  return ERROR_MARK;
}

// If statement S has a supported range_op handler return TRUE.

bool
gimple_range_op_handler::supported_p (gimple *s)
{
  enum tree_code code = get_code (s);
  if (range_op_handler (code))
    return true;
  if (is_a <gcall *> (s) && gimple_range_op_handler (s))
    return true;
  return false;
}

// Construct a handler object for statement S.

gimple_range_op_handler::gimple_range_op_handler (gimple *s)
{
  range_op_handler oper (get_code (s));
  m_stmt = s;
  m_op1 = NULL_TREE;
  m_op2 = NULL_TREE;

  if (oper)
    switch (gimple_code (m_stmt))
      {
	case GIMPLE_COND:
	  m_op1 = gimple_cond_lhs (m_stmt);
	  m_op2 = gimple_cond_rhs (m_stmt);
	  // Check that operands are supported types.  One check is enough.
	  if (Value_Range::supports_type_p (TREE_TYPE (m_op1)))
	    m_operator = oper.range_op ();
	  gcc_checking_assert (m_operator);
	  return;
	case GIMPLE_ASSIGN:
	  m_op1 = gimple_range_base_of_assignment (m_stmt);
	  if (m_op1 && TREE_CODE (m_op1) == MEM_REF)
	    {
	      // If the base address is an SSA_NAME, we return it
	      // here.  This allows processing of the range of that
	      // name, while the rest of the expression is simply
	      // ignored.  The code in range_ops will see the
	      // ADDR_EXPR and do the right thing.
	      tree ssa = TREE_OPERAND (m_op1, 0);
	      if (TREE_CODE (ssa) == SSA_NAME)
		m_op1 = ssa;
	    }
	  if (gimple_num_ops (m_stmt) >= 3)
	    m_op2 = gimple_assign_rhs2 (m_stmt);
	  // Check that operands are supported types.  One check is enough.
	  if ((m_op1 && !Value_Range::supports_type_p (TREE_TYPE (m_op1))))
	    return;
	  m_operator = oper.range_op ();
	  gcc_checking_assert (m_operator);
	  return;
	default:
	  gcc_unreachable ();
	  return;
      }
  // If no range-op table entry handled this stmt, check for other supported
  // statements.
  if (is_a <gcall *> (m_stmt))
    maybe_builtin_call ();
  else
    maybe_non_standard ();
  gcc_checking_assert (m_operator);
}

// Calculate what we can determine of the range of this unary
// statement's operand if the lhs of the expression has the range
// LHS_RANGE.  Return false if nothing can be determined.

bool
gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
{
  gcc_checking_assert (gimple_num_ops (m_stmt) < 3);
  // Give up on empty ranges.
  if (lhs_range.undefined_p ())
    return false;

  // Unary operations require the type of the first operand in the
  // second range position.
  tree type = TREE_TYPE (operand1 ());
  Value_Range type_range (type);
  type_range.set_varying (type);
  return op1_range (r, type, lhs_range, type_range);
}

// Calculate what we can determine of the range of this statement's
// first operand if the lhs of the expression has the range LHS_RANGE
// and the second operand has the range OP2_RANGE.  Return false if
// nothing can be determined.

bool
gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
				   const vrange &op2_range, relation_trio k)
{
  // Give up on empty ranges.
  if (lhs_range.undefined_p ())
    return false;

  // Unary operation are allowed to pass a range in for second operand
  // as there are often additional restrictions beyond the type which
  // can be imposed.  See operator_cast::op1_range().
  tree type = TREE_TYPE (operand1 ());
  // If op2 is undefined, solve as if it is varying.
  if (op2_range.undefined_p ())
    {
      if (gimple_num_ops (m_stmt) < 3)
	return false;
      tree op2_type;
      // This is sometimes invoked on single operand stmts.
      if (operand2 ())
	op2_type = TREE_TYPE (operand2 ());
      else
	op2_type = TREE_TYPE (operand1 ());
      Value_Range trange (op2_type);
      trange.set_varying (op2_type);
      return op1_range (r, type, lhs_range, trange, k);
    }
  return op1_range (r, type, lhs_range, op2_range, k);
}

// Calculate what we can determine of the range of this statement's
// second operand if the lhs of the expression has the range LHS_RANGE
// and the first operand has the range OP1_RANGE.  Return false if
// nothing can be determined.

bool
gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
				   const vrange &op1_range, relation_trio k)
{
  // Give up on empty ranges.
  if (lhs_range.undefined_p ())
    return false;

  tree type = TREE_TYPE (operand2 ());
  // If op1 is undefined, solve as if it is varying.
  if (op1_range.undefined_p ())
    {
      tree op1_type = TREE_TYPE (operand1 ());
      Value_Range trange (op1_type);
      trange.set_varying (op1_type);
      return op2_range (r, type, lhs_range, trange, k);
    }
  return op2_range (r, type, lhs_range, op1_range, k);
}

// --------------------------------------------------------------------

// Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
class cfn_constant_float_p : public range_operator
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const frange &lh,
			   const irange &, relation_trio) const
  {
    if (lh.singleton_p ())
      {
	wide_int one = wi::one (TYPE_PRECISION (type));
	r.set (type, one, one);
	return true;
      }
    if (cfun->after_inlining)
      {
	r.set_zero (type);
	return true;
      }
    return false;
  }
} op_cfn_constant_float_p;

// Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
class cfn_constant_p : public range_operator
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &, relation_trio) const
  {
    if (lh.singleton_p ())
      {
	wide_int one = wi::one (TYPE_PRECISION (type));
	r.set (type, one, one);
	return true;
      }
    if (cfun->after_inlining)
      {
	r.set_zero (type);
	return true;
      }
    return false;
  }
} op_cfn_constant_p;

// Implement range operator for integral/pointer functions returning
// the first argument.
class cfn_pass_through_arg1 : public range_operator
{
public:
  using range_operator::fold_range;
  using range_operator::op1_range;
  virtual bool fold_range (irange &r, tree, const irange &lh,
			   const irange &, relation_trio) const
  {
    r = lh;
    return true;
  }
  virtual bool op1_range (irange &r, tree, const irange &lhs,
			  const irange &, relation_trio) const
  {
    r = lhs;
    return true;
  }
} op_cfn_pass_through_arg1;

// Implement range operator for CFN_BUILT_IN_SIGNBIT.
class cfn_signbit : public range_operator
{
public:
  using range_operator::fold_range;
  using range_operator::op1_range;
  virtual bool fold_range (irange &r, tree type, const frange &lh,
			   const irange &, relation_trio) const override
  {
    bool signbit;
    if (lh.signbit_p (signbit))
      {
	if (signbit)
	  r.set_nonzero (type);
	else
	  r.set_zero (type);
	return true;
      }
   return false;
  }
  virtual bool op1_range (frange &r, tree type, const irange &lhs,
			  const frange &, relation_trio) const override
  {
    if (lhs.zero_p ())
      {
	r.set (type, dconst0, frange_val_max (type));
	r.update_nan (false);
	return true;
      }
    if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()))))
      {
	r.set (type, frange_val_min (type), dconstm0);
	r.update_nan (true);
	return true;
      }
    return false;
  }
} op_cfn_signbit;

// Implement range operator for CFN_BUILT_IN_COPYSIGN
class cfn_copysign : public range_operator
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (frange &r, tree type, const frange &lh,
			   const frange &rh, relation_trio) const override
  {
    frange neg;
    if (!range_op_handler (ABS_EXPR).fold_range (r, type, lh, frange (type)))
      return false;
    if (!range_op_handler (NEGATE_EXPR).fold_range (neg, type, r,
						    frange (type)))
      return false;

    bool signbit;
    if (rh.signbit_p (signbit))
      {
	// If the sign is negative, flip the result from ABS,
	// otherwise leave things positive.
	if (signbit)
	  r = neg;
      }
    else
      // If the sign is unknown, keep the positive and negative
      // alternatives.
      r.union_ (neg);
    return true;
  }
} op_cfn_copysign;

/* Compute FUNC (ARG) where FUNC is a mpfr function.  If RES_LOW is non-NULL,
   set it to low bound of possible range if the function is expected to have
   ULPS precision and similarly if RES_HIGH is non-NULL, set it to high bound.
   If the function returns false, the results weren't set.  */

static bool
frange_mpfr_arg1 (REAL_VALUE_TYPE *res_low, REAL_VALUE_TYPE *res_high,
		  int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
		  const REAL_VALUE_TYPE &arg, tree type, unsigned ulps)
{
  if (ulps == ~0U || !real_isfinite (&arg))
    return false;
  machine_mode mode = TYPE_MODE (type);
  const real_format *format = REAL_MODE_FORMAT (mode);
  auto_mpfr m (format->p);
  mpfr_from_real (m, &arg, MPFR_RNDN);
  mpfr_clear_flags ();
  bool inexact = func (m, m, MPFR_RNDN);
  if (!mpfr_number_p (m) || mpfr_overflow_p () || mpfr_underflow_p ())
    return false;

  REAL_VALUE_TYPE value, result;
  real_from_mpfr (&value, m, format, MPFR_RNDN);
  if (!real_isfinite (&value))
    return false;
  if ((value.cl == rvc_zero) != (mpfr_zero_p (m) != 0))
    inexact = true;

  real_convert (&result, format, &value);
  if (!real_isfinite (&result))
    return false;
  bool round_low = false;
  bool round_high = false;
  if (!ulps && flag_rounding_math)
    ++ulps;
  if (inexact || !real_identical (&result, &value))
    {
      if (MODE_COMPOSITE_P (mode))
	round_low = round_high = true;
      else
	{
	  round_low = !real_less (&result, &value);
	  round_high = !real_less (&value, &result);
	}
    }
  if (res_low)
    {
      *res_low = result;
      for (unsigned int i = 0; i < ulps + round_low; ++i)
	frange_nextafter (mode, *res_low, dconstninf);
    }
  if (res_high)
    {
      *res_high = result;
      for (unsigned int i = 0; i < ulps + round_high; ++i)
	frange_nextafter (mode, *res_high, dconstinf);
    }
  return true;
}

class cfn_sqrt : public range_operator
{
public:
  using range_operator::fold_range;
  using range_operator::op1_range;
  virtual bool fold_range (frange &r, tree type,
			   const frange &lh, const frange &,
			   relation_trio) const final override
  {
    if (lh.undefined_p ())
      return false;
    if (lh.known_isnan () || real_less (&lh.upper_bound (), &dconstm0))
      {
	r.set_nan (type);
	return true;
      }
    unsigned bulps
      = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
    if (bulps == ~0U)
      r.set_varying (type);
    else if (bulps == 0)
      r.set (type, dconstm0, dconstinf);
    else
      {
	REAL_VALUE_TYPE boundmin = dconstm0;
	while (bulps--)
	  frange_nextafter (TYPE_MODE (type), boundmin, dconstninf);
	r.set (type, boundmin, dconstinf);
      }
    if (!lh.maybe_isnan () && !real_less (&lh.lower_bound (), &dconst0))
      r.clear_nan ();

    unsigned ulps
      = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
    if (ulps == ~0U)
      return true;
    REAL_VALUE_TYPE lb = lh.lower_bound ();
    REAL_VALUE_TYPE ub = lh.upper_bound ();
    if (!frange_mpfr_arg1 (&lb, NULL, mpfr_sqrt, lb, type, ulps))
      lb = dconstninf;
    if (!frange_mpfr_arg1 (NULL, &ub, mpfr_sqrt, ub, type, ulps))
      ub = dconstinf;
    frange r2;
    r2.set (type, lb, ub);
    r2.flush_denormals_to_zero ();
    r.intersect (r2);
    return true;
  }
  virtual bool op1_range (frange &r, tree type,
			  const frange &lhs, const frange &,
			  relation_trio) const final override
  {
    if (lhs.undefined_p ())
      return false;

    // A known NAN means the input is [-INF,-0.) U +-NAN.
    if (lhs.known_isnan ())
      {
      known_nan:
	REAL_VALUE_TYPE ub = dconstm0;
	frange_nextafter (TYPE_MODE (type), ub, dconstninf);
	r.set (type, dconstninf, ub);
	// No r.flush_denormals_to_zero (); here - it is a reverse op.
	return true;
      }

    // Results outside of [-0.0, +Inf] are impossible.
    unsigned bulps
      = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), true);
    if (bulps != ~0U)
      {
	const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
	REAL_VALUE_TYPE m0 = dconstm0;
	while (bulps--)
	  frange_nextafter (TYPE_MODE (type), m0, dconstninf);
	if (real_less (&ub, &m0))
	  {
	    if (!lhs.maybe_isnan ())
	      r.set_undefined ();
	    else
	      // If lhs could be NAN and finite result is impossible,
	      // the range is like lhs.known_isnan () above.
	      goto known_nan;
	    return true;
	  }
      }

    if (!lhs.maybe_isnan ())
      // If NAN is not valid result, the input cannot include either
      // a NAN nor values smaller than -0.
      r.set (type, dconstm0, dconstinf, nan_state (false, false));
    else
      r.set_varying (type);

    unsigned ulps
      = targetm.libm_function_max_error (CFN_SQRT, TYPE_MODE (type), false);
    if (ulps == ~0U)
      return true;
    REAL_VALUE_TYPE lb = lhs.lower_bound ();
    REAL_VALUE_TYPE ub = lhs.upper_bound ();
    if (!lhs.maybe_isnan () && real_less (&dconst0, &lb))
      {
	for (unsigned i = 0; i < ulps; ++i)
	  frange_nextafter (TYPE_MODE (type), lb, dconstninf);
	if (real_less (&dconst0, &lb))
	  {
	    REAL_VALUE_TYPE op = lb;
	    frange_arithmetic (MULT_EXPR, type, lb, op, op, dconstninf);
	  }
	else
	  lb = dconstninf;
      }
    else
      lb = dconstninf;
    if (real_isfinite (&ub) && real_less (&dconst0, &ub))
      {
	for (unsigned i = 0; i < ulps; ++i)
	  frange_nextafter (TYPE_MODE (type), ub, dconstinf);
	if (real_isfinite (&ub))
	  {
	    REAL_VALUE_TYPE op = ub;
	    frange_arithmetic (MULT_EXPR, type, ub, op, op, dconstinf);
	  }
	else
	  ub = dconstinf;
      }
    else
      ub = dconstinf;
    frange r2;
    r2.set (type, lb, ub);
    r.intersect (r2);
    return true;
  }
} op_cfn_sqrt;

class cfn_sincos : public range_operator
{
public:
  using range_operator::fold_range;
  using range_operator::op1_range;
  cfn_sincos (combined_fn cfn) { m_cfn = cfn; }
  virtual bool fold_range (frange &r, tree type,
			   const frange &lh, const frange &,
			   relation_trio) const final override
  {
    if (lh.undefined_p ())
      return false;
    if (lh.known_isnan () || lh.known_isinf ())
      {
	r.set_nan (type);
	return true;
      }
    unsigned bulps = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type),
						      true);
    if (bulps == ~0U)
      r.set_varying (type);
    else if (bulps == 0)
      r.set (type, dconstm1, dconst1);
    else
      {
	REAL_VALUE_TYPE boundmin, boundmax;
	boundmax = dconst1;
	while (bulps--)
	  frange_nextafter (TYPE_MODE (type), boundmax, dconstinf);
	real_arithmetic (&boundmin, NEGATE_EXPR, &boundmax, NULL);
	r.set (type, boundmin, boundmax);
      }
    if (!lh.maybe_isnan () && !lh.maybe_isinf ())
      r.clear_nan ();

    unsigned ulps
      = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), false);
    if (ulps == ~0U)
      return true;
    REAL_VALUE_TYPE lb = lh.lower_bound ();
    REAL_VALUE_TYPE ub = lh.upper_bound ();
    REAL_VALUE_TYPE diff;
    real_arithmetic (&diff, MINUS_EXPR, &ub, &lb);
    if (!real_isfinite (&diff))
      return true;
    REAL_VALUE_TYPE pi = dconst_pi ();
    REAL_VALUE_TYPE pix2;
    real_arithmetic (&pix2, PLUS_EXPR, &pi, &pi);
    // We can only try to narrow the range further if ub-lb < 2*pi.
    if (!real_less (&diff, &pix2))
      return true;
    REAL_VALUE_TYPE lb_lo, lb_hi, ub_lo, ub_hi;
    REAL_VALUE_TYPE lb_deriv_lo, lb_deriv_hi, ub_deriv_lo, ub_deriv_hi;
    if (!frange_mpfr_arg1 (&lb_lo, &lb_hi,
			   m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, lb,
			   type, ulps)
	|| !frange_mpfr_arg1 (&ub_lo, &ub_hi,
			      m_cfn == CFN_SIN ? mpfr_sin : mpfr_cos, ub,
			      type, ulps)
	|| !frange_mpfr_arg1 (&lb_deriv_lo, &lb_deriv_hi,
			      m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, lb,
			      type, 0)
	|| !frange_mpfr_arg1 (&ub_deriv_lo, &ub_deriv_hi,
			      m_cfn == CFN_SIN ? mpfr_cos : mpfr_sin, ub,
			      type, 0))
      return true;
    if (m_cfn == CFN_COS)
      {
	// Derivative of cos is -sin, so negate.
	lb_deriv_lo.sign ^= 1;
	lb_deriv_hi.sign ^= 1;
	ub_deriv_lo.sign ^= 1;
	ub_deriv_hi.sign ^= 1;
      }

    if (real_less (&lb_lo, &ub_lo))
      lb = lb_lo;
    else
      lb = ub_lo;
    if (real_less (&lb_hi, &ub_hi))
      ub = ub_hi;
    else
      ub = lb_hi;

    // The range between the function result on the boundaries may need
    // to be extended to +1 (+Inf) or -1 (-Inf) or both depending on the
    // derivative or length of the argument range (diff).

    // First handle special case, where the derivative has different signs,
    // so the bound must be roughly -1 or +1.
    if (real_isneg (&lb_deriv_lo) != real_isneg (&lb_deriv_hi))
      {
	if (real_isneg (&lb_lo))
	  lb = dconstninf;
	else
	  ub = dconstinf;
      }
    if (real_isneg (&ub_deriv_lo) != real_isneg (&ub_deriv_hi))
      {
	if (real_isneg (&ub_lo))
	  lb = dconstninf;
	else
	  ub = dconstinf;
      }

    // If derivative at lower_bound and upper_bound have the same sign,
    // the function grows or declines on the whole range if diff < pi, so
    // [lb, ub] is correct, and if diff >= pi the result range must include
    // both the minimum and maximum.
    if (real_isneg (&lb_deriv_lo) == real_isneg (&ub_deriv_lo))
      {
	if (!real_less (&diff, &pi))
	  return true;
      }
    // If function declines at lower_bound and grows at upper_bound,
    // the result range must include the minimum, so set lb to -Inf.
    else if (real_isneg (&lb_deriv_lo))
      lb = dconstninf;
    // If function grows at lower_bound and declines at upper_bound,
    // the result range must include the maximum, so set ub to +Inf.
    else
      ub = dconstinf;
    frange r2;
    r2.set (type, lb, ub);
    r2.flush_denormals_to_zero ();
    r.intersect (r2);
    return true;
  }
  virtual bool op1_range (frange &r, tree type,
			  const frange &lhs, const frange &,
			  relation_trio) const final override
  {
    if (lhs.undefined_p ())
      return false;

    // A known NAN means the input is [-INF,-INF][+INF,+INF] U +-NAN,
    // which we can't currently represent.
    if (lhs.known_isnan ())
      {
	r.set_varying (type);
	return true;
      }

    // Results outside of [-1.0, +1.0] are impossible.
    unsigned bulps
      = targetm.libm_function_max_error (m_cfn, TYPE_MODE (type), true);
    if (bulps != ~0U)
      {
	const REAL_VALUE_TYPE &lb = lhs.lower_bound ();
	const REAL_VALUE_TYPE &ub = lhs.upper_bound ();
	REAL_VALUE_TYPE m1 = dconstm1;
	REAL_VALUE_TYPE p1 = dconst1;
	while (bulps--)
	  {
	    frange_nextafter (TYPE_MODE (type), m1, dconstninf);
	    frange_nextafter (TYPE_MODE (type), p1, dconstinf);
	  }
	if (real_less (&ub, &m1) || real_less (&p1, &lb))
	  {
	    if (!lhs.maybe_isnan ())
	      r.set_undefined ();
	    else
	      /* If lhs could be NAN and finite result is impossible,
		 the range is like lhs.known_isnan () above,
		 [-INF,-INF][+INF,+INF] U +-NAN.  */
	      r.set_varying (type);
	    return true;
	  }
      }

    if (!lhs.maybe_isnan ())
      {
	// If NAN is not valid result, the input cannot include either
	// a NAN nor a +-INF.
	REAL_VALUE_TYPE lb = real_min_representable (type);
	REAL_VALUE_TYPE ub = real_max_representable (type);
	r.set (type, lb, ub, nan_state (false, false));
      }
    else
      r.set_varying (type);
    return true;
  }
private:
  combined_fn m_cfn;
} op_cfn_sin (CFN_SIN), op_cfn_cos (CFN_COS);

// Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
class cfn_toupper_tolower : public range_operator
{
public:
  using range_operator::fold_range;
  cfn_toupper_tolower (bool toupper)  { m_toupper = toupper; }
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &, relation_trio) const;
private:
  bool get_letter_range (tree type, irange &lowers, irange &uppers) const;
  bool m_toupper;
} op_cfn_toupper (true), op_cfn_tolower (false);

// Return TRUE if we recognize the target character set and return the
// range for lower case and upper case letters.

bool
cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
				       irange &uppers) const
{
  // ASCII
  int a = lang_hooks.to_target_charset ('a');
  int z = lang_hooks.to_target_charset ('z');
  int A = lang_hooks.to_target_charset ('A');
  int Z = lang_hooks.to_target_charset ('Z');

  if ((z - a == 25) && (Z - A == 25))
    {
      lowers = int_range<2> (type,
			     wi::shwi (a, TYPE_PRECISION (type)),
			     wi::shwi (z, TYPE_PRECISION (type)));
      uppers = int_range<2> (type,
			     wi::shwi (A, TYPE_PRECISION (type)),
			     wi::shwi (Z, TYPE_PRECISION (type)));
      return true;
    }
  // Unknown character set.
  return false;
}

bool
cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
				 const irange &, relation_trio) const
{
  int_range<3> lowers;
  int_range<3> uppers;
  if (!get_letter_range (type, lowers, uppers))
    return false;

  r = lh;
  if (m_toupper)
    {
      // Return the range passed in without any lower case characters,
      // but including all the upper case ones.
      lowers.invert ();
      r.intersect (lowers);
      r.union_ (uppers);
    }
  else
    {
      // Return the range passed in without any lower case characters,
      // but including all the upper case ones.
      uppers.invert ();
      r.intersect (uppers);
      r.union_ (lowers);
    }
  return true;
}

// Implement range operator for CFN_BUILT_IN_FFS.
class cfn_ffs : public range_operator
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &, relation_trio) const
  {
    if (lh.undefined_p ())
      return false;
    // __builtin_ffs* and __builtin_popcount* return [0, prec].
    int prec = TYPE_PRECISION (lh.type ());
    // If arg is non-zero, then ffs or popcount are non-zero.
    int mini = range_includes_zero_p (lh) ? 0 : 1;
    int maxi = prec;

    // If some high bits are known to be zero, decrease the maximum.
    int_range_max tmp = lh;
    if (TYPE_SIGN (tmp.type ()) == SIGNED)
      range_cast (tmp, unsigned_type_for (tmp.type ()));
    wide_int max = tmp.upper_bound ();
    maxi = wi::floor_log2 (max) + 1;
    r.set (type,
	   wi::shwi (mini, TYPE_PRECISION (type)),
	   wi::shwi (maxi, TYPE_PRECISION (type)));
    return true;
  }
} op_cfn_ffs;

// Implement range operator for CFN_BUILT_IN_POPCOUNT.
class cfn_popcount : public cfn_ffs
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &rh, relation_trio rel) const
  {
    if (lh.undefined_p ())
      return false;
    unsigned prec = TYPE_PRECISION (type);
    irange_bitmask bm = lh.get_bitmask ();
    wide_int nz = bm.get_nonzero_bits ();
    wide_int high = wi::shwi (wi::popcount (nz), prec);
    // Calculating the popcount of a singleton is trivial.
    if (lh.singleton_p ())
      {
	r.set (type, high, high);
	return true;
      }
    if (cfn_ffs::fold_range (r, type, lh, rh, rel))
      {
	wide_int known_ones = ~bm.mask () & bm.value ();
	wide_int low = wi::shwi (wi::popcount (known_ones), prec);
	int_range<2> tmp (type, low, high);
	r.intersect (tmp);
	return true;
      }
    return false;
  }
} op_cfn_popcount;

// Implement range operator for CFN_BUILT_IN_CLZ
class cfn_clz : public range_operator
{
public:
  cfn_clz (bool internal) { m_gimple_call_internal_p = internal; }
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &rh, relation_trio) const;
private:
  bool m_gimple_call_internal_p;
} op_cfn_clz (false), op_cfn_clz_internal (true);

bool
cfn_clz::fold_range (irange &r, tree type, const irange &lh,
		     const irange &rh, relation_trio) const
{
  // __builtin_c[lt]z* return [0, prec-1], except when the
  // argument is 0, but that is undefined behavior.
  //
  // For __builtin_c[lt]z* consider argument of 0 always undefined
  // behavior, for internal fns likewise, unless it has 2 arguments,
  // then the second argument is the value at zero.
  if (lh.undefined_p ())
    return false;
  int prec = TYPE_PRECISION (lh.type ());
  int mini = 0;
  int maxi = prec - 1;
  if (m_gimple_call_internal_p)
    {
      // Only handle the single common value.
      if (rh.lower_bound () == prec)
	maxi = prec;
      else
	// Magic value to give up, unless we can prove arg is non-zero.
	mini = -2;
    }

  // From clz of minimum we can compute result maximum.
  if (wi::gt_p (lh.lower_bound (), 0, TYPE_SIGN (lh.type ())))
    {
      maxi = prec - 1 - wi::floor_log2 (lh.lower_bound ());
      if (mini == -2)
	mini = 0;
    }
  else if (!range_includes_zero_p (lh))
    {
      mini = 0;
      maxi = prec - 1;
    }
  if (mini == -2)
    return false;
  // From clz of maximum we can compute result minimum.
  wide_int max = lh.upper_bound ();
  int newmini = prec - 1 - wi::floor_log2 (max);
  if (max == 0)
    {
      // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
      // return [prec, prec], otherwise ignore the range.
      if (maxi == prec)
	mini = prec;
    }
  else
    mini = newmini;

  if (mini == -2)
    return false;
  r.set (type,
	 wi::shwi (mini, TYPE_PRECISION (type)),
	 wi::shwi (maxi, TYPE_PRECISION (type)));
  return true;
}

// Implement range operator for CFN_BUILT_IN_CTZ
class cfn_ctz : public range_operator
{
public:
  cfn_ctz (bool internal) { m_gimple_call_internal_p = internal; }
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &rh, relation_trio) const;
private:
  bool m_gimple_call_internal_p;
} op_cfn_ctz (false), op_cfn_ctz_internal (true);

bool
cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
		     const irange &rh, relation_trio) const
{
  if (lh.undefined_p ())
    return false;
  int prec = TYPE_PRECISION (lh.type ());
  int mini = 0;
  int maxi = prec - 1;

  if (m_gimple_call_internal_p)
    {
      // Handle only the two common values.
      if (rh.lower_bound () == -1)
	mini = -1;
      else if (rh.lower_bound () == prec)
	maxi = prec;
      else
	// Magic value to give up, unless we can prove arg is non-zero.
	mini = -2;
    }
  // If arg is non-zero, then use [0, prec - 1].
  if (!range_includes_zero_p (lh))
    {
      mini = 0;
      maxi = prec - 1;
    }
  // If some high bits are known to be zero, we can decrease
  // the maximum.
  wide_int max = lh.upper_bound ();
  if (max == 0)
    {
      // Argument is [0, 0].  If CTZ_DEFINED_VALUE_AT_ZERO
      // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
      // Otherwise ignore the range.
      if (mini == -1)
	maxi = -1;
      else if (maxi == prec)
	mini = prec;
    }
  // If value at zero is prec and 0 is in the range, we can't lower
  // the upper bound.  We could create two separate ranges though,
  // [0,floor_log2(max)][prec,prec] though.
  else if (maxi != prec)
    maxi = wi::floor_log2 (max);

  if (mini == -2)
    return false;
  r.set (type,
	 wi::shwi (mini, TYPE_PRECISION (type)),
	 wi::shwi (maxi, TYPE_PRECISION (type)));
  return true;
}


// Implement range operator for CFN_BUILT_IN_
class cfn_clrsb : public range_operator
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &, relation_trio) const
  {
    if (lh.undefined_p ())
      return false;
    int prec = TYPE_PRECISION (lh.type ());
    r.set (type,
	   wi::zero (TYPE_PRECISION (type)),
	   wi::shwi (prec - 1, TYPE_PRECISION (type)));
    return true;
  }
} op_cfn_clrsb;


// Implement range operator for CFN_BUILT_IN_
class cfn_ubsan : public range_operator
{
public:
  cfn_ubsan (enum tree_code code) { m_code = code; }
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &rh, relation_trio rel) const
  {
    bool saved_flag_wrapv = flag_wrapv;
    // Pretend the arithmetic is wrapping.  If there is any overflow,
    // we'll complain, but will actually do wrapping operation.
    flag_wrapv = 1;
    bool result = range_op_handler (m_code).fold_range (r, type, lh, rh, rel);
    flag_wrapv = saved_flag_wrapv;

    // If for both arguments vrp_valueize returned non-NULL, this should
    // have been already folded and if not, it wasn't folded because of
    // overflow.  Avoid removing the UBSAN_CHECK_* calls in that case.
    if (result && r.singleton_p ())
      r.set_varying (type);
    return result;
  }
private:
  enum tree_code m_code;
};

cfn_ubsan op_cfn_ubsan_add (PLUS_EXPR);
cfn_ubsan op_cfn_ubsan_sub (MINUS_EXPR);
cfn_ubsan op_cfn_ubsan_mul (MULT_EXPR);


// Implement range operator for CFN_BUILT_IN_STRLEN
class cfn_strlen : public range_operator
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &,
			   const irange &, relation_trio) const
  {
    wide_int max = irange_val_max (ptrdiff_type_node);
    // To account for the terminating NULL, the maximum length
    // is one less than the maximum array size, which in turn
    // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
    // smaller than the former type).
    // FIXME: Use max_object_size() - 1 here.
    r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2);
    return true;
  }
} op_cfn_strlen;


// Implement range operator for CFN_BUILT_IN_GOACC_DIM
class cfn_goacc_dim : public range_operator
{
public:
  cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &lh,
			   const irange &, relation_trio) const
  {
    tree axis_tree;
    if (!lh.singleton_p (&axis_tree))
      return false;
    HOST_WIDE_INT axis = TREE_INT_CST_LOW (axis_tree);
    int size = oacc_get_fn_dim_size (current_function_decl, axis);
    if (!size)
      // If it's dynamic, the backend might know a hardware limitation.
      size = targetm.goacc.dim_limit (axis);

    r.set (type,
	   wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
	   size
	   ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
	   : irange_val_max (type));
    return true;
  }
private:
  bool m_is_pos;
} op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);


// Implement range operator for CFN_BUILT_IN_
class cfn_parity : public range_operator
{
public:
  using range_operator::fold_range;
  virtual bool fold_range (irange &r, tree type, const irange &,
			   const irange &, relation_trio) const
  {
    r = range_true_and_false (type);
    return true;
  }
} op_cfn_parity;

// Set up a gimple_range_op_handler for any nonstandard function which can be
// supported via range-ops.

void
gimple_range_op_handler::maybe_non_standard ()
{
  range_op_handler signed_op (OP_WIDEN_MULT_SIGNED);
  gcc_checking_assert (signed_op);
  range_op_handler unsigned_op (OP_WIDEN_MULT_UNSIGNED);
  gcc_checking_assert (unsigned_op);

  if (gimple_code (m_stmt) == GIMPLE_ASSIGN)
    switch (gimple_assign_rhs_code (m_stmt))
      {
	case WIDEN_MULT_EXPR:
	{
	  m_op1 = gimple_assign_rhs1 (m_stmt);
	  m_op2 = gimple_assign_rhs2 (m_stmt);
	  tree ret = gimple_assign_lhs (m_stmt);
	  bool signed1 = TYPE_SIGN (TREE_TYPE (m_op1)) == SIGNED;
	  bool signed2 = TYPE_SIGN (TREE_TYPE (m_op2)) == SIGNED;
	  bool signed_ret = TYPE_SIGN (TREE_TYPE (ret)) == SIGNED;

	  /* Normally these operands should all have the same sign, but
	     some passes and violate this by taking mismatched sign args.  At
	     the moment the only one that's possible is mismatch inputs and
	     unsigned output.  Once ranger supports signs for the operands we
	     can properly fix it,  for now only accept the case we can do
	     correctly.  */
	  if ((signed1 ^ signed2) && signed_ret)
	    return;

	  if (signed2 && !signed1)
	    std::swap (m_op1, m_op2);

	  if (signed1 || signed2)
	    m_operator = signed_op.range_op ();
	  else
	    m_operator = unsigned_op.range_op ();
	  break;
	}
	default:
	  break;
      }
}

// Set up a gimple_range_op_handler for any built in function which can be
// supported via range-ops.

void
gimple_range_op_handler::maybe_builtin_call ()
{
  gcc_checking_assert (is_a <gcall *> (m_stmt));

  gcall *call = as_a <gcall *> (m_stmt);
  combined_fn func = gimple_call_combined_fn (call);
  if (func == CFN_LAST)
    return;
  tree type = gimple_range_type (call);
  gcc_checking_assert (type);
  if (!Value_Range::supports_type_p (type))
    return;

  switch (func)
    {
    case CFN_BUILT_IN_CONSTANT_P:
      m_op1 = gimple_call_arg (call, 0);
      if (irange::supports_p (TREE_TYPE (m_op1)))
	m_operator = &op_cfn_constant_p;
      else if (frange::supports_p (TREE_TYPE (m_op1)))
	m_operator = &op_cfn_constant_float_p;
      break;

    CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT):
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_signbit;
      break;

    CASE_CFN_COPYSIGN_ALL:
      m_op1 = gimple_call_arg (call, 0);
      m_op2 = gimple_call_arg (call, 1);
      m_operator = &op_cfn_copysign;
      break;

    CASE_CFN_SQRT:
    CASE_CFN_SQRT_FN:
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_sqrt;
      break;

    CASE_CFN_SIN:
    CASE_CFN_SIN_FN:
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_sin;
      break;

    CASE_CFN_COS:
    CASE_CFN_COS_FN:
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_cos;
      break;

    case CFN_BUILT_IN_TOUPPER:
    case CFN_BUILT_IN_TOLOWER:
      // Only proceed If the argument is compatible with the LHS.
      m_op1 = gimple_call_arg (call, 0);
      if (range_compatible_p (type, TREE_TYPE (m_op1)))
	m_operator = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower
						    : &op_cfn_toupper;
      break;

    CASE_CFN_FFS:
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_ffs;
      break;

    CASE_CFN_POPCOUNT:
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_popcount;
      break;

    CASE_CFN_CLZ:
      m_op1 = gimple_call_arg (call, 0);
      if (gimple_call_internal_p (call)
	  && gimple_call_num_args (call) == 2)
	{
	  m_op2 = gimple_call_arg (call, 1);
	  m_operator = &op_cfn_clz_internal;
	}
      else
	m_operator = &op_cfn_clz;
      break;

    CASE_CFN_CTZ:
      m_op1 = gimple_call_arg (call, 0);
      if (gimple_call_internal_p (call)
	  && gimple_call_num_args (call) == 2)
	{
	  m_op2 = gimple_call_arg (call, 1);
	  m_operator = &op_cfn_ctz_internal;
	}
      else
	m_operator = &op_cfn_ctz;
      break;

    CASE_CFN_CLRSB:
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_clrsb;
      break;

    case CFN_UBSAN_CHECK_ADD:
      m_op1 = gimple_call_arg (call, 0);
      m_op2 = gimple_call_arg (call, 1);
      m_operator = &op_cfn_ubsan_add;
      break;

    case CFN_UBSAN_CHECK_SUB:
      m_op1 = gimple_call_arg (call, 0);
      m_op2 = gimple_call_arg (call, 1);
      m_operator = &op_cfn_ubsan_sub;
      break;

    case CFN_UBSAN_CHECK_MUL:
      m_op1 = gimple_call_arg (call, 0);
      m_op2 = gimple_call_arg (call, 1);
      m_operator = &op_cfn_ubsan_mul;
      break;

    case CFN_BUILT_IN_STRLEN:
      {
	tree lhs = gimple_call_lhs (call);
	if (lhs && ptrdiff_type_node && (TYPE_PRECISION (ptrdiff_type_node)
					 == TYPE_PRECISION (TREE_TYPE (lhs))))
	  {
	    m_op1 = gimple_call_arg (call, 0);
	    m_operator = &op_cfn_strlen;
	  }
	break;
      }

    // Optimizing these two internal functions helps the loop
    // optimizer eliminate outer comparisons.  Size is [1,N]
    // and pos is [0,N-1].
    case CFN_GOACC_DIM_SIZE:
      // This call will ensure all the asserts are triggered.
      oacc_get_ifn_dim_arg (call);
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_goacc_dim_size;
      break;

    case CFN_GOACC_DIM_POS:
      // This call will ensure all the asserts are triggered.
      oacc_get_ifn_dim_arg (call);
      m_op1 = gimple_call_arg (call, 0);
      m_operator = &op_cfn_goacc_dim_pos;
      break;

    CASE_CFN_PARITY:
      m_operator = &op_cfn_parity;
      break;

    default:
      {
	unsigned arg;
	if (gimple_call_fnspec (call).returns_arg (&arg) && arg == 0)
	  {
	    m_op1 = gimple_call_arg (call, 0);
	    m_operator = &op_cfn_pass_through_arg1;
	  }
	break;
      }
    }
}
