/* Support routines for Value Range Propagation (VRP).
   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
   Contributed by Diego Novillo <dnovillo@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 "tm.h"
#include "ggc.h"
#include "flags.h"
#include "tree.h"
#include "basic-block.h"
#include "tree-flow.h"
#include "tree-pass.h"
#include "tree-dump.h"
#include "timevar.h"
#include "diagnostic.h"
#include "toplev.h"
#include "intl.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-propagate.h"
#include "tree-chrec.h"

/* Set of SSA names found during the dominator traversal of a
   sub-graph in find_assert_locations.  */
static sbitmap found_in_subgraph;

/* Local functions.  */
static int compare_values (tree val1, tree val2);
static int compare_values_warnv (tree val1, tree val2, bool *);
static void vrp_meet (value_range_t *, value_range_t *);
static tree vrp_evaluate_conditional_warnv (tree, bool, bool *);

/* Location information for ASSERT_EXPRs.  Each instance of this
   structure describes an ASSERT_EXPR for an SSA name.  Since a single
   SSA name may have more than one assertion associated with it, these
   locations are kept in a linked list attached to the corresponding
   SSA name.  */
struct assert_locus_d
{
  /* Basic block where the assertion would be inserted.  */
  basic_block bb;

  /* Some assertions need to be inserted on an edge (e.g., assertions
     generated by COND_EXPRs).  In those cases, BB will be NULL.  */
  edge e;

  /* Pointer to the statement that generated this assertion.  */
  block_stmt_iterator si;

  /* Predicate code for the ASSERT_EXPR.  Must be COMPARISON_CLASS_P.  */
  enum tree_code comp_code;

  /* Value being compared against.  */
  tree val;

  /* Next node in the linked list.  */
  struct assert_locus_d *next;
};

typedef struct assert_locus_d *assert_locus_t;

/* If bit I is present, it means that SSA name N_i has a list of
   assertions that should be inserted in the IL.  */
static bitmap need_assert_for;

/* Array of locations lists where to insert assertions.  ASSERTS_FOR[I]
   holds a list of ASSERT_LOCUS_T nodes that describe where
   ASSERT_EXPRs for SSA name N_I should be inserted.  */
static assert_locus_t *asserts_for;

/* Set of blocks visited in find_assert_locations.  Used to avoid
   visiting the same block more than once.  */
static sbitmap blocks_visited;

/* Value range array.  After propagation, VR_VALUE[I] holds the range
   of values that SSA name N_I may take.  */
static value_range_t **vr_value;

/* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
   number of executable edges we saw the last time we visited the
   node.  */
static int *vr_phi_edge_counts;


/* Return whether TYPE should use an overflow infinity distinct from
   TYPE_{MIN,MAX}_VALUE.  We use an overflow infinity value to
   represent a signed overflow during VRP computations.  An infinity
   is distinct from a half-range, which will go from some number to
   TYPE_{MIN,MAX}_VALUE.  */

static inline bool
needs_overflow_infinity (const_tree type)
{
  return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
}

/* Return whether TYPE can support our overflow infinity
   representation: we use the TREE_OVERFLOW flag, which only exists
   for constants.  If TYPE doesn't support this, we don't optimize
   cases which would require signed overflow--we drop them to
   VARYING.  */

static inline bool
supports_overflow_infinity (const_tree type)
{
#ifdef ENABLE_CHECKING
  gcc_assert (needs_overflow_infinity (type));
#endif
  return (TYPE_MIN_VALUE (type) != NULL_TREE
	  && CONSTANT_CLASS_P (TYPE_MIN_VALUE (type))
	  && TYPE_MAX_VALUE (type) != NULL_TREE
	  && CONSTANT_CLASS_P (TYPE_MAX_VALUE (type)));
}

/* VAL is the maximum or minimum value of a type.  Return a
   corresponding overflow infinity.  */

static inline tree
make_overflow_infinity (tree val)
{
#ifdef ENABLE_CHECKING
  gcc_assert (val != NULL_TREE && CONSTANT_CLASS_P (val));
#endif
  val = copy_node (val);
  TREE_OVERFLOW (val) = 1;
  return val;
}

/* Return a negative overflow infinity for TYPE.  */

static inline tree
negative_overflow_infinity (tree type)
{
#ifdef ENABLE_CHECKING
  gcc_assert (supports_overflow_infinity (type));
#endif
  return make_overflow_infinity (TYPE_MIN_VALUE (type));
}

/* Return a positive overflow infinity for TYPE.  */

static inline tree
positive_overflow_infinity (tree type)
{
#ifdef ENABLE_CHECKING
  gcc_assert (supports_overflow_infinity (type));
#endif
  return make_overflow_infinity (TYPE_MAX_VALUE (type));
}

/* Return whether VAL is a negative overflow infinity.  */

static inline bool
is_negative_overflow_infinity (const_tree val)
{
  return (needs_overflow_infinity (TREE_TYPE (val))
	  && CONSTANT_CLASS_P (val)
	  && TREE_OVERFLOW (val)
	  && operand_equal_p (val, TYPE_MIN_VALUE (TREE_TYPE (val)), 0));
}

/* Return whether VAL is a positive overflow infinity.  */

static inline bool
is_positive_overflow_infinity (const_tree val)
{
  return (needs_overflow_infinity (TREE_TYPE (val))
	  && CONSTANT_CLASS_P (val)
	  && TREE_OVERFLOW (val)
	  && operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0));
}

/* Return whether VAL is a positive or negative overflow infinity.  */

static inline bool
is_overflow_infinity (const_tree val)
{
  return (needs_overflow_infinity (TREE_TYPE (val))
	  && CONSTANT_CLASS_P (val)
	  && TREE_OVERFLOW (val)
	  && (operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0)
	      || operand_equal_p (val, TYPE_MIN_VALUE (TREE_TYPE (val)), 0)));
}

/* If VAL is now an overflow infinity, return VAL.  Otherwise, return
   the same value with TREE_OVERFLOW clear.  This can be used to avoid
   confusing a regular value with an overflow value.  */

static inline tree
avoid_overflow_infinity (tree val)
{
  if (!is_overflow_infinity (val))
    return val;

  if (operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0))
    return TYPE_MAX_VALUE (TREE_TYPE (val));
  else
    {
#ifdef ENABLE_CHECKING
      gcc_assert (operand_equal_p (val, TYPE_MIN_VALUE (TREE_TYPE (val)), 0));
#endif
      return TYPE_MIN_VALUE (TREE_TYPE (val));
    }
}


/* Return whether VAL is equal to the maximum value of its type.  This
   will be true for a positive overflow infinity.  We can't do a
   simple equality comparison with TYPE_MAX_VALUE because C typedefs
   and Ada subtypes can produce types whose TYPE_MAX_VALUE is not ==
   to the integer constant with the same value in the type.  */

static inline bool
vrp_val_is_max (const_tree val)
{
  tree type_max = TYPE_MAX_VALUE (TREE_TYPE (val));

  return (val == type_max
	  || (type_max != NULL_TREE
	      && operand_equal_p (val, type_max, 0)));
}

/* Return whether VAL is equal to the minimum value of its type.  This
   will be true for a negative overflow infinity.  */

static inline bool
vrp_val_is_min (const_tree val)
{
  tree type_min = TYPE_MIN_VALUE (TREE_TYPE (val));

  return (val == type_min
	  || (type_min != NULL_TREE
	      && operand_equal_p (val, type_min, 0)));
}


/* Return true if ARG is marked with the nonnull attribute in the
   current function signature.  */

static bool
nonnull_arg_p (const_tree arg)
{
  tree t, attrs, fntype;
  unsigned HOST_WIDE_INT arg_num;

  gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg)));

  /* The static chain decl is always non null.  */
  if (arg == cfun->static_chain_decl)
    return true;

  fntype = TREE_TYPE (current_function_decl);
  attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));

  /* If "nonnull" wasn't specified, we know nothing about the argument.  */
  if (attrs == NULL_TREE)
    return false;

  /* If "nonnull" applies to all the arguments, then ARG is non-null.  */
  if (TREE_VALUE (attrs) == NULL_TREE)
    return true;

  /* Get the position number for ARG in the function signature.  */
  for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
       t;
       t = TREE_CHAIN (t), arg_num++)
    {
      if (t == arg)
	break;
    }

  gcc_assert (t == arg);

  /* Now see if ARG_NUM is mentioned in the nonnull list.  */
  for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
    {
      if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
	return true;
    }

  return false;
}


/* Set value range VR to {T, MIN, MAX, EQUIV}.  */

static void
set_value_range (value_range_t *vr, enum value_range_type t, tree min,
		 tree max, bitmap equiv)
{
#if defined ENABLE_CHECKING
  /* Check the validity of the range.  */
  if (t == VR_RANGE || t == VR_ANTI_RANGE)
    {
      int cmp;

      gcc_assert (min && max);

      if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
	gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));

      cmp = compare_values (min, max);
      gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);

      if (needs_overflow_infinity (TREE_TYPE (min)))
	gcc_assert (!is_overflow_infinity (min)
		    || !is_overflow_infinity (max));
    }

  if (t == VR_UNDEFINED || t == VR_VARYING)
    gcc_assert (min == NULL_TREE && max == NULL_TREE);

  if (t == VR_UNDEFINED || t == VR_VARYING)
    gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
#endif

  vr->type = t;
  vr->min = min;
  vr->max = max;

  /* Since updating the equivalence set involves deep copying the
     bitmaps, only do it if absolutely necessary.  */
  if (vr->equiv == NULL
      && equiv != NULL)
    vr->equiv = BITMAP_ALLOC (NULL);

  if (equiv != vr->equiv)
    {
      if (equiv && !bitmap_empty_p (equiv))
	bitmap_copy (vr->equiv, equiv);
      else
	bitmap_clear (vr->equiv);
    }
}


/* Copy value range FROM into value range TO.  */

static inline void
copy_value_range (value_range_t *to, value_range_t *from)
{
  set_value_range (to, from->type, from->min, from->max, from->equiv);
}


/* Set value range VR to VR_VARYING.  */

static inline void
set_value_range_to_varying (value_range_t *vr)
{
  vr->type = VR_VARYING;
  vr->min = vr->max = NULL_TREE;
  if (vr->equiv)
    bitmap_clear (vr->equiv);
}

/* Set value range VR to a single value.  This function is only called
   with values we get from statements, and exists to clear the
   TREE_OVERFLOW flag so that we don't think we have an overflow
   infinity when we shouldn't.  */

static inline void
set_value_range_to_value (value_range_t *vr, tree val, bitmap equiv)
{
  gcc_assert (is_gimple_min_invariant (val));
  val = avoid_overflow_infinity (val);
  set_value_range (vr, VR_RANGE, val, val, equiv);
}

/* Set value range VR to a non-negative range of type TYPE.
   OVERFLOW_INFINITY indicates whether to use an overflow infinity
   rather than TYPE_MAX_VALUE; this should be true if we determine
   that the range is nonnegative based on the assumption that signed
   overflow does not occur.  */

static inline void
set_value_range_to_nonnegative (value_range_t *vr, tree type,
				bool overflow_infinity)
{
  tree zero;

  if (overflow_infinity && !supports_overflow_infinity (type))
    {
      set_value_range_to_varying (vr);
      return;
    }

  zero = build_int_cst (type, 0);
  set_value_range (vr, VR_RANGE, zero,
		   (overflow_infinity
		    ? positive_overflow_infinity (type)
		    : TYPE_MAX_VALUE (type)),
		   vr->equiv);
}

/* Set value range VR to a non-NULL range of type TYPE.  */

static inline void
set_value_range_to_nonnull (value_range_t *vr, tree type)
{
  tree zero = build_int_cst (type, 0);
  set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv);
}


/* Set value range VR to a NULL range of type TYPE.  */

static inline void
set_value_range_to_null (value_range_t *vr, tree type)
{
  set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv);
}


/* Set value range VR to a range of a truthvalue of type TYPE.  */

static inline void
set_value_range_to_truthvalue (value_range_t *vr, tree type)
{
  if (TYPE_PRECISION (type) == 1)
    set_value_range_to_varying (vr);
  else
    set_value_range (vr, VR_RANGE,
		     build_int_cst (type, 0), build_int_cst (type, 1),
		     vr->equiv);
}


/* Set value range VR to VR_UNDEFINED.  */

static inline void
set_value_range_to_undefined (value_range_t *vr)
{
  vr->type = VR_UNDEFINED;
  vr->min = vr->max = NULL_TREE;
  if (vr->equiv)
    bitmap_clear (vr->equiv);
}


/* Return value range information for VAR.  

   If we have no values ranges recorded (ie, VRP is not running), then
   return NULL.  Otherwise create an empty range if none existed for VAR.  */

static value_range_t *
get_value_range (const_tree var)
{
  value_range_t *vr;
  tree sym;
  unsigned ver = SSA_NAME_VERSION (var);

  /* If we have no recorded ranges, then return NULL.  */
  if (! vr_value)
    return NULL;

  vr = vr_value[ver];
  if (vr)
    return vr;

  /* Create a default value range.  */
  vr_value[ver] = vr = XCNEW (value_range_t);

  /* Defer allocating the equivalence set.  */
  vr->equiv = NULL;

  /* If VAR is a default definition, the variable can take any value
     in VAR's type.  */
  sym = SSA_NAME_VAR (var);
  if (SSA_NAME_IS_DEFAULT_DEF (var))
    {
      /* Try to use the "nonnull" attribute to create ~[0, 0]
	 anti-ranges for pointers.  Note that this is only valid with
	 default definitions of PARM_DECLs.  */
      if (TREE_CODE (sym) == PARM_DECL
	  && POINTER_TYPE_P (TREE_TYPE (sym))
	  && nonnull_arg_p (sym))
	set_value_range_to_nonnull (vr, TREE_TYPE (sym));
      else
	set_value_range_to_varying (vr);
    }

  return vr;
}

/* Return true, if VAL1 and VAL2 are equal values for VRP purposes.  */

static inline bool
vrp_operand_equal_p (const_tree val1, const_tree val2)
{
  if (val1 == val2)
    return true;
  if (!val1 || !val2 || !operand_equal_p (val1, val2, 0))
    return false;
  if (is_overflow_infinity (val1))
    return is_overflow_infinity (val2);
  return true;
}

/* Return true, if the bitmaps B1 and B2 are equal.  */

static inline bool
vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
{
  return (b1 == b2
	  || (b1 && b2
	      && bitmap_equal_p (b1, b2)));
}

/* Update the value range and equivalence set for variable VAR to
   NEW_VR.  Return true if NEW_VR is different from VAR's previous
   value.

   NOTE: This function assumes that NEW_VR is a temporary value range
   object created for the sole purpose of updating VAR's range.  The
   storage used by the equivalence set from NEW_VR will be freed by
   this function.  Do not call update_value_range when NEW_VR
   is the range object associated with another SSA name.  */

static inline bool
update_value_range (const_tree var, value_range_t *new_vr)
{
  value_range_t *old_vr;
  bool is_new;

  /* Update the value range, if necessary.  */
  old_vr = get_value_range (var);
  is_new = old_vr->type != new_vr->type
	   || !vrp_operand_equal_p (old_vr->min, new_vr->min)
	   || !vrp_operand_equal_p (old_vr->max, new_vr->max)
	   || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);

  if (is_new)
    set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
	             new_vr->equiv);

  BITMAP_FREE (new_vr->equiv);

  return is_new;
}


/* Add VAR and VAR's equivalence set to EQUIV.  This is the central
   point where equivalence processing can be turned on/off.  */

static void
add_equivalence (bitmap *equiv, const_tree var)
{
  unsigned ver = SSA_NAME_VERSION (var);
  value_range_t *vr = vr_value[ver];

  if (*equiv == NULL)
    *equiv = BITMAP_ALLOC (NULL);
  bitmap_set_bit (*equiv, ver);
  if (vr && vr->equiv)
    bitmap_ior_into (*equiv, vr->equiv);
}


/* Return true if VR is ~[0, 0].  */

static inline bool
range_is_nonnull (value_range_t *vr)
{
  return vr->type == VR_ANTI_RANGE
	 && integer_zerop (vr->min)
	 && integer_zerop (vr->max);
}


/* Return true if VR is [0, 0].  */

static inline bool
range_is_null (value_range_t *vr)
{
  return vr->type == VR_RANGE
	 && integer_zerop (vr->min)
	 && integer_zerop (vr->max);
}


/* Return true if value range VR involves at least one symbol.  */

static inline bool
symbolic_range_p (value_range_t *vr)
{
  return (!is_gimple_min_invariant (vr->min)
          || !is_gimple_min_invariant (vr->max));
}

/* Return true if value range VR uses an overflow infinity.  */

static inline bool
overflow_infinity_range_p (value_range_t *vr)
{
  return (vr->type == VR_RANGE
	  && (is_overflow_infinity (vr->min)
	      || is_overflow_infinity (vr->max)));
}

/* Return false if we can not make a valid comparison based on VR;
   this will be the case if it uses an overflow infinity and overflow
   is not undefined (i.e., -fno-strict-overflow is in effect).
   Otherwise return true, and set *STRICT_OVERFLOW_P to true if VR
   uses an overflow infinity.  */

static bool
usable_range_p (value_range_t *vr, bool *strict_overflow_p)
{
  gcc_assert (vr->type == VR_RANGE);
  if (is_overflow_infinity (vr->min))
    {
      *strict_overflow_p = true;
      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->min)))
	return false;
    }
  if (is_overflow_infinity (vr->max))
    {
      *strict_overflow_p = true;
      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->max)))
	return false;
    }
  return true;
}


/* Like tree_expr_nonnegative_warnv_p, but this function uses value
   ranges obtained so far.  */

static bool
vrp_expr_computes_nonnegative (tree expr, bool *strict_overflow_p)
{
  return tree_expr_nonnegative_warnv_p (expr, strict_overflow_p);
}

/* Like tree_expr_nonzero_warnv_p, but this function uses value ranges
   obtained so far.  */

static bool
vrp_expr_computes_nonzero (tree expr, bool *strict_overflow_p)
{
  if (tree_expr_nonzero_warnv_p (expr, strict_overflow_p))
    return true;

  /* If we have an expression of the form &X->a, then the expression
     is nonnull if X is nonnull.  */
  if (TREE_CODE (expr) == ADDR_EXPR)
    {
      tree base = get_base_address (TREE_OPERAND (expr, 0));

      if (base != NULL_TREE
	  && TREE_CODE (base) == INDIRECT_REF
	  && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
	{
	  value_range_t *vr = get_value_range (TREE_OPERAND (base, 0));
	  if (range_is_nonnull (vr))
	    return true;
	}
    }

  return false;
}

/* Returns true if EXPR is a valid value (as expected by compare_values) --
   a gimple invariant, or SSA_NAME +- CST.  */

static bool
valid_value_p (tree expr)
{
  if (TREE_CODE (expr) == SSA_NAME)
    return true;

  if (TREE_CODE (expr) == PLUS_EXPR
      || TREE_CODE (expr) == MINUS_EXPR)
    return (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME
	    && TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST);
  
  return is_gimple_min_invariant (expr);
}

/* Return 
   1 if VAL < VAL2
   0 if !(VAL < VAL2)
   -2 if those are incomparable.  */
static inline int
operand_less_p (tree val, tree val2)
{
  /* LT is folded faster than GE and others.  Inline the common case.  */
  if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
    {
      if (TYPE_UNSIGNED (TREE_TYPE (val)))
	return INT_CST_LT_UNSIGNED (val, val2);
      else
	{
	  if (INT_CST_LT (val, val2))
	    return 1;
	}
    }
  else
    {
      tree tcmp;

      fold_defer_overflow_warnings ();

      tcmp = fold_binary_to_constant (LT_EXPR, boolean_type_node, val, val2);

      fold_undefer_and_ignore_overflow_warnings ();

      if (!tcmp)
	return -2;

      if (!integer_zerop (tcmp))
	return 1;
    }

  /* val >= val2, not considering overflow infinity.  */
  if (is_negative_overflow_infinity (val))
    return is_negative_overflow_infinity (val2) ? 0 : 1;
  else if (is_positive_overflow_infinity (val2))
    return is_positive_overflow_infinity (val) ? 0 : 1;

  return 0;
}

/* Compare two values VAL1 and VAL2.  Return
   
   	-2 if VAL1 and VAL2 cannot be compared at compile-time,
   	-1 if VAL1 < VAL2,
   	 0 if VAL1 == VAL2,
	+1 if VAL1 > VAL2, and
	+2 if VAL1 != VAL2

   This is similar to tree_int_cst_compare but supports pointer values
   and values that cannot be compared at compile time.

   If STRICT_OVERFLOW_P is not NULL, then set *STRICT_OVERFLOW_P to
   true if the return value is only valid if we assume that signed
   overflow is undefined.  */

static int
compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
{
  if (val1 == val2)
    return 0;

  /* Below we rely on the fact that VAL1 and VAL2 are both pointers or
     both integers.  */
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (val1))
	      == POINTER_TYPE_P (TREE_TYPE (val2)));
  /* Convert the two values into the same type.  This is needed because
     sizetype causes sign extension even for unsigned types.  */
  val2 = fold_convert (TREE_TYPE (val1), val2);
  STRIP_USELESS_TYPE_CONVERSION (val2);

  if ((TREE_CODE (val1) == SSA_NAME
       || TREE_CODE (val1) == PLUS_EXPR
       || TREE_CODE (val1) == MINUS_EXPR)
      && (TREE_CODE (val2) == SSA_NAME
	  || TREE_CODE (val2) == PLUS_EXPR
	  || TREE_CODE (val2) == MINUS_EXPR))
    {
      tree n1, c1, n2, c2;
      enum tree_code code1, code2;
  
      /* If VAL1 and VAL2 are of the form 'NAME [+-] CST' or 'NAME',
	 return -1 or +1 accordingly.  If VAL1 and VAL2 don't use the
	 same name, return -2.  */
      if (TREE_CODE (val1) == SSA_NAME)
	{
	  code1 = SSA_NAME;
	  n1 = val1;
	  c1 = NULL_TREE;
	}
      else
	{
	  code1 = TREE_CODE (val1);
	  n1 = TREE_OPERAND (val1, 0);
	  c1 = TREE_OPERAND (val1, 1);
	  if (tree_int_cst_sgn (c1) == -1)
	    {
	      if (is_negative_overflow_infinity (c1))
		return -2;
	      c1 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c1), c1);
	      if (!c1)
		return -2;
	      code1 = code1 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
	    }
	}

      if (TREE_CODE (val2) == SSA_NAME)
	{
	  code2 = SSA_NAME;
	  n2 = val2;
	  c2 = NULL_TREE;
	}
      else
	{
	  code2 = TREE_CODE (val2);
	  n2 = TREE_OPERAND (val2, 0);
	  c2 = TREE_OPERAND (val2, 1);
	  if (tree_int_cst_sgn (c2) == -1)
	    {
	      if (is_negative_overflow_infinity (c2))
		return -2;
	      c2 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c2), c2);
	      if (!c2)
		return -2;
	      code2 = code2 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
	    }
	}

      /* Both values must use the same name.  */
      if (n1 != n2)
	return -2;

      if (code1 == SSA_NAME
	  && code2 == SSA_NAME)
	/* NAME == NAME  */
	return 0;

      /* If overflow is defined we cannot simplify more.  */
      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
	return -2;

      if (strict_overflow_p != NULL
	  && (code1 == SSA_NAME || !TREE_NO_WARNING (val1))
	  && (code2 == SSA_NAME || !TREE_NO_WARNING (val2)))
	*strict_overflow_p = true;

      if (code1 == SSA_NAME)
	{
	  if (code2 == PLUS_EXPR)
	    /* NAME < NAME + CST  */
	    return -1;
	  else if (code2 == MINUS_EXPR)
	    /* NAME > NAME - CST  */
	    return 1;
	}
      else if (code1 == PLUS_EXPR)
	{
	  if (code2 == SSA_NAME)
	    /* NAME + CST > NAME  */
	    return 1;
	  else if (code2 == PLUS_EXPR)
	    /* NAME + CST1 > NAME + CST2, if CST1 > CST2  */
	    return compare_values_warnv (c1, c2, strict_overflow_p);
	  else if (code2 == MINUS_EXPR)
	    /* NAME + CST1 > NAME - CST2  */
	    return 1;
	}
      else if (code1 == MINUS_EXPR)
	{
	  if (code2 == SSA_NAME)
	    /* NAME - CST < NAME  */
	    return -1;
	  else if (code2 == PLUS_EXPR)
	    /* NAME - CST1 < NAME + CST2  */
	    return -1;
	  else if (code2 == MINUS_EXPR)
	    /* NAME - CST1 > NAME - CST2, if CST1 < CST2.  Notice that
	       C1 and C2 are swapped in the call to compare_values.  */
	    return compare_values_warnv (c2, c1, strict_overflow_p);
	}

      gcc_unreachable ();
    }

  /* We cannot compare non-constants.  */
  if (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2))
    return -2;

  if (!POINTER_TYPE_P (TREE_TYPE (val1)))
    {
      /* We cannot compare overflowed values, except for overflow
	 infinities.  */
      if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
	{
	  if (strict_overflow_p != NULL)
	    *strict_overflow_p = true;
	  if (is_negative_overflow_infinity (val1))
	    return is_negative_overflow_infinity (val2) ? 0 : -1;
	  else if (is_negative_overflow_infinity (val2))
	    return 1;
	  else if (is_positive_overflow_infinity (val1))
	    return is_positive_overflow_infinity (val2) ? 0 : 1;
	  else if (is_positive_overflow_infinity (val2))
	    return -1;
	  return -2;
	}

      return tree_int_cst_compare (val1, val2);
    }
  else
    {
      tree t;

      /* First see if VAL1 and VAL2 are not the same.  */
      if (val1 == val2 || operand_equal_p (val1, val2, 0))
	return 0;
      
      /* If VAL1 is a lower address than VAL2, return -1.  */
      if (operand_less_p (val1, val2) == 1)
	return -1;

      /* If VAL1 is a higher address than VAL2, return +1.  */
      if (operand_less_p (val2, val1) == 1)
	return 1;

      /* If VAL1 is different than VAL2, return +2.
	 For integer constants we either have already returned -1 or 1
	 or they are equivalent.  We still might succeed in proving
	 something about non-trivial operands.  */
      if (TREE_CODE (val1) != INTEGER_CST
	  || TREE_CODE (val2) != INTEGER_CST)
	{
          t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
	  if (t && tree_expr_nonzero_p (t))
	    return 2;
	}

      return -2;
    }
}

/* Compare values like compare_values_warnv, but treat comparisons of
   nonconstants which rely on undefined overflow as incomparable.  */

static int
compare_values (tree val1, tree val2)
{
  bool sop;
  int ret;

  sop = false;
  ret = compare_values_warnv (val1, val2, &sop);
  if (sop
      && (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)))
    ret = -2;
  return ret;
}


/* Return 1 if VAL is inside value range VR (VR->MIN <= VAL <= VR->MAX),
          0 if VAL is not inside VR,
	 -2 if we cannot tell either way.

   FIXME, the current semantics of this functions are a bit quirky
	  when taken in the context of VRP.  In here we do not care
	  about VR's type.  If VR is the anti-range ~[3, 5] the call
	  value_inside_range (4, VR) will return 1.

	  This is counter-intuitive in a strict sense, but the callers
	  currently expect this.  They are calling the function
	  merely to determine whether VR->MIN <= VAL <= VR->MAX.  The
	  callers are applying the VR_RANGE/VR_ANTI_RANGE semantics
	  themselves.

	  This also applies to value_ranges_intersect_p and
	  range_includes_zero_p.  The semantics of VR_RANGE and
	  VR_ANTI_RANGE should be encoded here, but that also means
	  adapting the users of these functions to the new semantics.  

   Benchmark compile/20001226-1.c compilation time after changing this
   function.  */

static inline int
value_inside_range (tree val, value_range_t * vr)
{
  int cmp1, cmp2;

  cmp1 = operand_less_p (val, vr->min);
  if (cmp1 == -2)
    return -2;
  if (cmp1 == 1)
    return 0;

  cmp2 = operand_less_p (vr->max, val);
  if (cmp2 == -2)
    return -2;

  return !cmp2;
}


/* Return true if value ranges VR0 and VR1 have a non-empty
   intersection.  
   
   Benchmark compile/20001226-1.c compilation time after changing this
   function.
   */

static inline bool
value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)
{
  /* The value ranges do not intersect if the maximum of the first range is
     less than the minimum of the second range or vice versa.
     When those relations are unknown, we can't do any better.  */
  if (operand_less_p (vr0->max, vr1->min) != 0)
    return false;
  if (operand_less_p (vr1->max, vr0->min) != 0)
    return false;
  return true;
}


/* Return true if VR includes the value zero, false otherwise.  FIXME,
   currently this will return false for an anti-range like ~[-4, 3].
   This will be wrong when the semantics of value_inside_range are
   modified (currently the users of this function expect these
   semantics).  */

static inline bool
range_includes_zero_p (value_range_t *vr)
{
  tree zero;

  gcc_assert (vr->type != VR_UNDEFINED
              && vr->type != VR_VARYING
	      && !symbolic_range_p (vr));

  zero = build_int_cst (TREE_TYPE (vr->min), 0);
  return (value_inside_range (zero, vr) == 1);
}

/* Return true if T, an SSA_NAME, is known to be nonnegative.  Return
   false otherwise or if no value range information is available.  */

bool
ssa_name_nonnegative_p (const_tree t)
{
  value_range_t *vr = get_value_range (t);

  if (!vr)
    return false;

  /* Testing for VR_ANTI_RANGE is not useful here as any anti-range
     which would return a useful value should be encoded as a VR_RANGE.  */
  if (vr->type == VR_RANGE)
    {
      int result = compare_values (vr->min, integer_zero_node);

      return (result == 0 || result == 1);
    }
  return false;
}

/* Return true if T, an SSA_NAME, is known to be nonzero.  Return
   false otherwise or if no value range information is available.  */

bool
ssa_name_nonzero_p (const_tree t)
{
  value_range_t *vr = get_value_range (t);

  if (!vr)
    return false;

  /* A VR_RANGE which does not include zero is a nonzero value.  */
  if (vr->type == VR_RANGE && !symbolic_range_p (vr))
    return ! range_includes_zero_p (vr);

  /* A VR_ANTI_RANGE which does include zero is a nonzero value.  */
  if (vr->type == VR_ANTI_RANGE && !symbolic_range_p (vr))
    return range_includes_zero_p (vr);

  return false;
}


/* Extract value range information from an ASSERT_EXPR EXPR and store
   it in *VR_P.  */

static void
extract_range_from_assert (value_range_t *vr_p, tree expr)
{
  tree var, cond, limit, min, max, type;
  value_range_t *var_vr, *limit_vr;
  enum tree_code cond_code;

  var = ASSERT_EXPR_VAR (expr);
  cond = ASSERT_EXPR_COND (expr);

  gcc_assert (COMPARISON_CLASS_P (cond));

  /* Find VAR in the ASSERT_EXPR conditional.  */
  if (var == TREE_OPERAND (cond, 0))
    {
      /* If the predicate is of the form VAR COMP LIMIT, then we just
	 take LIMIT from the RHS and use the same comparison code.  */
      limit = TREE_OPERAND (cond, 1);
      cond_code = TREE_CODE (cond);
    }
  else
    {
      /* If the predicate is of the form LIMIT COMP VAR, then we need
	 to flip around the comparison code to create the proper range
	 for VAR.  */
      limit = TREE_OPERAND (cond, 0);
      cond_code = swap_tree_comparison (TREE_CODE (cond));
    }

  limit = avoid_overflow_infinity (limit);

  type = TREE_TYPE (limit);
  gcc_assert (limit != var);

  /* For pointer arithmetic, we only keep track of pointer equality
     and inequality.  */
  if (POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
    {
      set_value_range_to_varying (vr_p);
      return;
    }

  /* If LIMIT is another SSA name and LIMIT has a range of its own,
     try to use LIMIT's range to avoid creating symbolic ranges
     unnecessarily. */
  limit_vr = (TREE_CODE (limit) == SSA_NAME) ? get_value_range (limit) : NULL;

  /* LIMIT's range is only interesting if it has any useful information.  */
  if (limit_vr
      && (limit_vr->type == VR_UNDEFINED
	  || limit_vr->type == VR_VARYING
	  || symbolic_range_p (limit_vr)))
    limit_vr = NULL;

  /* Initially, the new range has the same set of equivalences of
     VAR's range.  This will be revised before returning the final
     value.  Since assertions may be chained via mutually exclusive
     predicates, we will need to trim the set of equivalences before
     we are done.  */
  gcc_assert (vr_p->equiv == NULL);
  add_equivalence (&vr_p->equiv, var);

  /* Extract a new range based on the asserted comparison for VAR and
     LIMIT's value range.  Notice that if LIMIT has an anti-range, we
     will only use it for equality comparisons (EQ_EXPR).  For any
     other kind of assertion, we cannot derive a range from LIMIT's
     anti-range that can be used to describe the new range.  For
     instance, ASSERT_EXPR <x_2, x_2 <= b_4>.  If b_4 is ~[2, 10],
     then b_4 takes on the ranges [-INF, 1] and [11, +INF].  There is
     no single range for x_2 that could describe LE_EXPR, so we might
     as well build the range [b_4, +INF] for it.  */
  if (cond_code == EQ_EXPR)
    {
      enum value_range_type range_type;

      if (limit_vr)
	{
	  range_type = limit_vr->type;
	  min = limit_vr->min;
	  max = limit_vr->max;
	}
      else
	{
	  range_type = VR_RANGE;
	  min = limit;
	  max = limit;
	}

      set_value_range (vr_p, range_type, min, max, vr_p->equiv);

      /* When asserting the equality VAR == LIMIT and LIMIT is another
	 SSA name, the new range will also inherit the equivalence set
	 from LIMIT.  */
      if (TREE_CODE (limit) == SSA_NAME)
	add_equivalence (&vr_p->equiv, limit);
    }
  else if (cond_code == NE_EXPR)
    {
      /* As described above, when LIMIT's range is an anti-range and
	 this assertion is an inequality (NE_EXPR), then we cannot
	 derive anything from the anti-range.  For instance, if
	 LIMIT's range was ~[0, 0], the assertion 'VAR != LIMIT' does
	 not imply that VAR's range is [0, 0].  So, in the case of
	 anti-ranges, we just assert the inequality using LIMIT and
	 not its anti-range.

	 If LIMIT_VR is a range, we can only use it to build a new
	 anti-range if LIMIT_VR is a single-valued range.  For
	 instance, if LIMIT_VR is [0, 1], the predicate
	 VAR != [0, 1] does not mean that VAR's range is ~[0, 1].
	 Rather, it means that for value 0 VAR should be ~[0, 0]
	 and for value 1, VAR should be ~[1, 1].  We cannot
	 represent these ranges.

	 The only situation in which we can build a valid
	 anti-range is when LIMIT_VR is a single-valued range
	 (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX).  In that case, 
	 build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX].  */
      if (limit_vr
	  && limit_vr->type == VR_RANGE
	  && compare_values (limit_vr->min, limit_vr->max) == 0)
	{
	  min = limit_vr->min;
	  max = limit_vr->max;
	}
      else
	{
	  /* In any other case, we cannot use LIMIT's range to build a
	     valid anti-range.  */
	  min = max = limit;
	}

      /* If MIN and MAX cover the whole range for their type, then
	 just use the original LIMIT.  */
      if (INTEGRAL_TYPE_P (type)
	  && vrp_val_is_min (min)
	  && vrp_val_is_max (max))
	min = max = limit;

      set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv);
    }
  else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
    {
      min = TYPE_MIN_VALUE (type);

      if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
	max = limit;
      else
	{
	  /* If LIMIT_VR is of the form [N1, N2], we need to build the
	     range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
	     LT_EXPR.  */
	  max = limit_vr->max;
	}

      /* If the maximum value forces us to be out of bounds, simply punt.
	 It would be pointless to try and do anything more since this
	 all should be optimized away above us.  */
      if ((cond_code == LT_EXPR
	   && compare_values (max, min) == 0)
	  || is_overflow_infinity (max))
	set_value_range_to_varying (vr_p);
      else
	{
	  /* For LT_EXPR, we create the range [MIN, MAX - 1].  */
	  if (cond_code == LT_EXPR)
	    {
	      tree one = build_int_cst (type, 1);
	      max = fold_build2 (MINUS_EXPR, type, max, one);
	      if (EXPR_P (max))
		TREE_NO_WARNING (max) = 1;
	    }

	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
	}
    }
  else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
    {
      max = TYPE_MAX_VALUE (type);

      if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
	min = limit;
      else
	{
	  /* If LIMIT_VR is of the form [N1, N2], we need to build the
	     range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
	     GT_EXPR.  */
	  min = limit_vr->min;
	}

      /* If the minimum value forces us to be out of bounds, simply punt.
	 It would be pointless to try and do anything more since this
	 all should be optimized away above us.  */
      if ((cond_code == GT_EXPR
	   && compare_values (min, max) == 0)
	  || is_overflow_infinity (min))
	set_value_range_to_varying (vr_p);
      else
	{
	  /* For GT_EXPR, we create the range [MIN + 1, MAX].  */
	  if (cond_code == GT_EXPR)
	    {
	      tree one = build_int_cst (type, 1);
	      min = fold_build2 (PLUS_EXPR, type, min, one);
	      if (EXPR_P (min))
		TREE_NO_WARNING (min) = 1;
	    }

	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
	}
    }
  else
    gcc_unreachable ();

  /* If VAR already had a known range, it may happen that the new
     range we have computed and VAR's range are not compatible.  For
     instance,

	if (p_5 == NULL)
	  p_6 = ASSERT_EXPR <p_5, p_5 == NULL>;
	  x_7 = p_6->fld;
	  p_8 = ASSERT_EXPR <p_6, p_6 != NULL>;

     While the above comes from a faulty program, it will cause an ICE
     later because p_8 and p_6 will have incompatible ranges and at
     the same time will be considered equivalent.  A similar situation
     would arise from

     	if (i_5 > 10)
	  i_6 = ASSERT_EXPR <i_5, i_5 > 10>;
	  if (i_5 < 5)
	    i_7 = ASSERT_EXPR <i_6, i_6 < 5>;

     Again i_6 and i_7 will have incompatible ranges.  It would be
     pointless to try and do anything with i_7's range because
     anything dominated by 'if (i_5 < 5)' will be optimized away.
     Note, due to the wa in which simulation proceeds, the statement
     i_7 = ASSERT_EXPR <...> we would never be visited because the
     conditional 'if (i_5 < 5)' always evaluates to false.  However,
     this extra check does not hurt and may protect against future
     changes to VRP that may get into a situation similar to the
     NULL pointer dereference example.

     Note that these compatibility tests are only needed when dealing
     with ranges or a mix of range and anti-range.  If VAR_VR and VR_P
     are both anti-ranges, they will always be compatible, because two
     anti-ranges will always have a non-empty intersection.  */

  var_vr = get_value_range (var);

  /* We may need to make adjustments when VR_P and VAR_VR are numeric
     ranges or anti-ranges.  */
  if (vr_p->type == VR_VARYING
      || vr_p->type == VR_UNDEFINED
      || var_vr->type == VR_VARYING
      || var_vr->type == VR_UNDEFINED
      || symbolic_range_p (vr_p)
      || symbolic_range_p (var_vr))
    return;

  if (var_vr->type == VR_RANGE && vr_p->type == VR_RANGE)
    {
      /* If the two ranges have a non-empty intersection, we can
	 refine the resulting range.  Since the assert expression
	 creates an equivalency and at the same time it asserts a
	 predicate, we can take the intersection of the two ranges to
	 get better precision.  */
      if (value_ranges_intersect_p (var_vr, vr_p))
	{
	  /* Use the larger of the two minimums.  */
	  if (compare_values (vr_p->min, var_vr->min) == -1)
	    min = var_vr->min;
	  else
	    min = vr_p->min;

	  /* Use the smaller of the two maximums.  */
	  if (compare_values (vr_p->max, var_vr->max) == 1)
	    max = var_vr->max;
	  else
	    max = vr_p->max;

	  set_value_range (vr_p, vr_p->type, min, max, vr_p->equiv);
	}
      else
	{
	  /* The two ranges do not intersect, set the new range to
	     VARYING, because we will not be able to do anything
	     meaningful with it.  */
	  set_value_range_to_varying (vr_p);
	}
    }
  else if ((var_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
           || (var_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
    {
      /* A range and an anti-range will cancel each other only if
	 their ends are the same.  For instance, in the example above,
	 p_8's range ~[0, 0] and p_6's range [0, 0] are incompatible,
	 so VR_P should be set to VR_VARYING.  */
      if (compare_values (var_vr->min, vr_p->min) == 0
	  && compare_values (var_vr->max, vr_p->max) == 0)
	set_value_range_to_varying (vr_p);
      else
	{
	  tree min, max, anti_min, anti_max, real_min, real_max;
	  int cmp;

	  /* We want to compute the logical AND of the two ranges;
	     there are three cases to consider.


	     1. The VR_ANTI_RANGE range is completely within the 
		VR_RANGE and the endpoints of the ranges are
		different.  In that case the resulting range
		should be whichever range is more precise.
		Typically that will be the VR_RANGE.

	     2. The VR_ANTI_RANGE is completely disjoint from
		the VR_RANGE.  In this case the resulting range
		should be the VR_RANGE.

	     3. There is some overlap between the VR_ANTI_RANGE
		and the VR_RANGE.

		3a. If the high limit of the VR_ANTI_RANGE resides
		    within the VR_RANGE, then the result is a new
		    VR_RANGE starting at the high limit of the
		    the VR_ANTI_RANGE + 1 and extending to the
		    high limit of the original VR_RANGE.

		3b. If the low limit of the VR_ANTI_RANGE resides
		    within the VR_RANGE, then the result is a new
		    VR_RANGE starting at the low limit of the original
		    VR_RANGE and extending to the low limit of the
		    VR_ANTI_RANGE - 1.  */
	  if (vr_p->type == VR_ANTI_RANGE)
	    {
	      anti_min = vr_p->min;
	      anti_max = vr_p->max;
	      real_min = var_vr->min;
	      real_max = var_vr->max;
	    }
	  else
	    {
	      anti_min = var_vr->min;
	      anti_max = var_vr->max;
	      real_min = vr_p->min;
	      real_max = vr_p->max;
	    }


	  /* Case 1, VR_ANTI_RANGE completely within VR_RANGE,
	     not including any endpoints.  */
	  if (compare_values (anti_max, real_max) == -1
	      && compare_values (anti_min, real_min) == 1)
	    {
	      set_value_range (vr_p, VR_RANGE, real_min,
			       real_max, vr_p->equiv);
	    }
	  /* Case 2, VR_ANTI_RANGE completely disjoint from
	     VR_RANGE.  */
	  else if (compare_values (anti_min, real_max) == 1
		   || compare_values (anti_max, real_min) == -1)
	    {
	      set_value_range (vr_p, VR_RANGE, real_min,
			       real_max, vr_p->equiv);
	    }
	  /* Case 3a, the anti-range extends into the low
	     part of the real range.  Thus creating a new
	     low for the real range.  */
	  else if (((cmp = compare_values (anti_max, real_min)) == 1
		    || cmp == 0)
		   && compare_values (anti_max, real_max) == -1)
	    {
	      gcc_assert (!is_positive_overflow_infinity (anti_max));
	      if (needs_overflow_infinity (TREE_TYPE (anti_max))
		  && vrp_val_is_max (anti_max))
		{
		  if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
		    {
		      set_value_range_to_varying (vr_p);
		      return;
		    }
		  min = positive_overflow_infinity (TREE_TYPE (var_vr->min));
		}
	      else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
		min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
				   anti_max,
				   build_int_cst (TREE_TYPE (var_vr->min), 1));
	      else
		min = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (var_vr->min),
				   anti_max, size_int (1));
	      max = real_max;
	      set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
	    }
	  /* Case 3b, the anti-range extends into the high
	     part of the real range.  Thus creating a new
	     higher for the real range.  */
	  else if (compare_values (anti_min, real_min) == 1
		   && ((cmp = compare_values (anti_min, real_max)) == -1
		       || cmp == 0))
	    {
	      gcc_assert (!is_negative_overflow_infinity (anti_min));
	      if (needs_overflow_infinity (TREE_TYPE (anti_min))
		  && vrp_val_is_min (anti_min))
		{
		  if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
		    {
		      set_value_range_to_varying (vr_p);
		      return;
		    }
		  max = negative_overflow_infinity (TREE_TYPE (var_vr->min));
		}
	      else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
		max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
				   anti_min,
				   build_int_cst (TREE_TYPE (var_vr->min), 1));
	      else
		max = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (var_vr->min),
				   anti_min,
				   size_int (-1));
	      min = real_min;
	      set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
	    }
	}
    }
}


/* Extract range information from SSA name VAR and store it in VR.  If
   VAR has an interesting range, use it.  Otherwise, create the
   range [VAR, VAR] and return it.  This is useful in situations where
   we may have conditionals testing values of VARYING names.  For
   instance,

   	x_3 = y_5;
	if (x_3 > y_5)
	  ...

    Even if y_5 is deemed VARYING, we can determine that x_3 > y_5 is
    always false.  */

static void
extract_range_from_ssa_name (value_range_t *vr, tree var)
{
  value_range_t *var_vr = get_value_range (var);

  if (var_vr->type != VR_UNDEFINED && var_vr->type != VR_VARYING)
    copy_value_range (vr, var_vr);
  else
    set_value_range (vr, VR_RANGE, var, var, NULL);

  add_equivalence (&vr->equiv, var);
}


/* Wrapper around int_const_binop.  If the operation overflows and we
   are not using wrapping arithmetic, then adjust the result to be
   -INF or +INF depending on CODE, VAL1 and VAL2.  This can return
   NULL_TREE if we need to use an overflow infinity representation but
   the type does not support it.  */

static tree
vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
{
  tree res;

  res = int_const_binop (code, val1, val2, 0);

  /* If we are not using wrapping arithmetic, operate symbolically
     on -INF and +INF.  */
  if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
    {
      int checkz = compare_values (res, val1);
      bool overflow = false;

      /* Ensure that res = val1 [+*] val2 >= val1
         or that res = val1 - val2 <= val1.  */
      if ((code == PLUS_EXPR
	   && !(checkz == 1 || checkz == 0))
          || (code == MINUS_EXPR
	      && !(checkz == 0 || checkz == -1)))
	{
	  overflow = true;
	}
      /* Checking for multiplication overflow is done by dividing the
	 output of the multiplication by the first input of the
	 multiplication.  If the result of that division operation is
	 not equal to the second input of the multiplication, then the
	 multiplication overflowed.  */
      else if (code == MULT_EXPR && !integer_zerop (val1))
	{
	  tree tmp = int_const_binop (TRUNC_DIV_EXPR,
				      res,
				      val1, 0);
	  int check = compare_values (tmp, val2);

	  if (check != 0)
	    overflow = true;
	}

      if (overflow)
	{
	  res = copy_node (res);
	  TREE_OVERFLOW (res) = 1;
	}

    }
  else if ((TREE_OVERFLOW (res)
	    && !TREE_OVERFLOW (val1)
	    && !TREE_OVERFLOW (val2))
	   || is_overflow_infinity (val1)
	   || is_overflow_infinity (val2))
    {
      /* If the operation overflowed but neither VAL1 nor VAL2 are
	 overflown, return -INF or +INF depending on the operation
	 and the combination of signs of the operands.  */
      int sgn1 = tree_int_cst_sgn (val1);
      int sgn2 = tree_int_cst_sgn (val2);

      if (needs_overflow_infinity (TREE_TYPE (res))
	  && !supports_overflow_infinity (TREE_TYPE (res)))
	return NULL_TREE;

      /* We have to punt on adding infinities of different signs,
	 since we can't tell what the sign of the result should be.
	 Likewise for subtracting infinities of the same sign.  */
      if (((code == PLUS_EXPR && sgn1 != sgn2)
	   || (code == MINUS_EXPR && sgn1 == sgn2))
	  && is_overflow_infinity (val1)
	  && is_overflow_infinity (val2))
	return NULL_TREE;

      /* Don't try to handle division or shifting of infinities.  */
      if ((code == TRUNC_DIV_EXPR
	   || code == FLOOR_DIV_EXPR
	   || code == CEIL_DIV_EXPR
	   || code == EXACT_DIV_EXPR
	   || code == ROUND_DIV_EXPR
	   || code == RSHIFT_EXPR)
	  && (is_overflow_infinity (val1)
	      || is_overflow_infinity (val2)))
	return NULL_TREE;

      /* Notice that we only need to handle the restricted set of
	 operations handled by extract_range_from_binary_expr.
	 Among them, only multiplication, addition and subtraction
	 can yield overflow without overflown operands because we
	 are working with integral types only... except in the
	 case VAL1 = -INF and VAL2 = -1 which overflows to +INF
	 for division too.  */

      /* For multiplication, the sign of the overflow is given
	 by the comparison of the signs of the operands.  */
      if ((code == MULT_EXPR && sgn1 == sgn2)
          /* For addition, the operands must be of the same sign
	     to yield an overflow.  Its sign is therefore that
	     of one of the operands, for example the first.  For
	     infinite operands X + -INF is negative, not positive.  */
	  || (code == PLUS_EXPR
	      && (sgn1 >= 0
		  ? !is_negative_overflow_infinity (val2)
		  : is_positive_overflow_infinity (val2)))
	  /* For subtraction, non-infinite operands must be of
	     different signs to yield an overflow.  Its sign is
	     therefore that of the first operand or the opposite of
	     that of the second operand.  A first operand of 0 counts
	     as positive here, for the corner case 0 - (-INF), which
	     overflows, but must yield +INF.  For infinite operands 0
	     - INF is negative, not positive.  */
	  || (code == MINUS_EXPR
	      && (sgn1 >= 0
		  ? !is_positive_overflow_infinity (val2)
		  : is_negative_overflow_infinity (val2)))
	  /* We only get in here with positive shift count, so the
	     overflow direction is the same as the sign of val1.
	     Actually rshift does not overflow at all, but we only
	     handle the case of shifting overflowed -INF and +INF.  */
	  || (code == RSHIFT_EXPR
	      && sgn1 >= 0)
	  /* For division, the only case is -INF / -1 = +INF.  */
	  || code == TRUNC_DIV_EXPR
	  || code == FLOOR_DIV_EXPR
	  || code == CEIL_DIV_EXPR
	  || code == EXACT_DIV_EXPR
	  || code == ROUND_DIV_EXPR)
	return (needs_overflow_infinity (TREE_TYPE (res))
		? positive_overflow_infinity (TREE_TYPE (res))
		: TYPE_MAX_VALUE (TREE_TYPE (res)));
      else
	return (needs_overflow_infinity (TREE_TYPE (res))
		? negative_overflow_infinity (TREE_TYPE (res))
		: TYPE_MIN_VALUE (TREE_TYPE (res)));
    }

  return res;
}


/* Extract range information from a binary expression EXPR based on
   the ranges of each of its operands and the expression code.  */

static void
extract_range_from_binary_expr (value_range_t *vr, tree expr)
{
  enum tree_code code = TREE_CODE (expr);
  enum value_range_type type;
  tree op0, op1, min, max;
  int cmp;
  value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
  value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };

  /* Not all binary expressions can be applied to ranges in a
     meaningful way.  Handle only arithmetic operations.  */
  if (code != PLUS_EXPR
      && code != MINUS_EXPR
      && code != POINTER_PLUS_EXPR
      && code != MULT_EXPR
      && code != TRUNC_DIV_EXPR
      && code != FLOOR_DIV_EXPR
      && code != CEIL_DIV_EXPR
      && code != EXACT_DIV_EXPR
      && code != ROUND_DIV_EXPR
      && code != RSHIFT_EXPR
      && code != MIN_EXPR
      && code != MAX_EXPR
      && code != BIT_AND_EXPR
      && code != TRUTH_ANDIF_EXPR
      && code != TRUTH_ORIF_EXPR
      && code != TRUTH_AND_EXPR
      && code != TRUTH_OR_EXPR)
    {
      set_value_range_to_varying (vr);
      return;
    }

  /* Get value ranges for each operand.  For constant operands, create
     a new value range with the operand to simplify processing.  */
  op0 = TREE_OPERAND (expr, 0);
  if (TREE_CODE (op0) == SSA_NAME)
    vr0 = *(get_value_range (op0));
  else if (is_gimple_min_invariant (op0))
    set_value_range_to_value (&vr0, op0, NULL);
  else
    set_value_range_to_varying (&vr0);

  op1 = TREE_OPERAND (expr, 1);
  if (TREE_CODE (op1) == SSA_NAME)
    vr1 = *(get_value_range (op1));
  else if (is_gimple_min_invariant (op1))
    set_value_range_to_value (&vr1, op1, NULL);
  else
    set_value_range_to_varying (&vr1);

  /* If either range is UNDEFINED, so is the result.  */
  if (vr0.type == VR_UNDEFINED || vr1.type == VR_UNDEFINED)
    {
      set_value_range_to_undefined (vr);
      return;
    }

  /* The type of the resulting value range defaults to VR0.TYPE.  */
  type = vr0.type;

  /* Refuse to operate on VARYING ranges, ranges of different kinds
     and symbolic ranges.  As an exception, we allow BIT_AND_EXPR
     because we may be able to derive a useful range even if one of
     the operands is VR_VARYING or symbolic range.  TODO, we may be
     able to derive anti-ranges in some cases.  */
  if (code != BIT_AND_EXPR
      && code != TRUTH_AND_EXPR
      && code != TRUTH_OR_EXPR
      && (vr0.type == VR_VARYING
	  || vr1.type == VR_VARYING
	  || vr0.type != vr1.type
	  || symbolic_range_p (&vr0)
	  || symbolic_range_p (&vr1)))
    {
      set_value_range_to_varying (vr);
      return;
    }

  /* Now evaluate the expression to determine the new range.  */
  if (POINTER_TYPE_P (TREE_TYPE (expr))
      || POINTER_TYPE_P (TREE_TYPE (op0))
      || POINTER_TYPE_P (TREE_TYPE (op1)))
    {
      if (code == MIN_EXPR || code == MAX_EXPR)
	{
	  /* For MIN/MAX expressions with pointers, we only care about
	     nullness, if both are non null, then the result is nonnull.
	     If both are null, then the result is null. Otherwise they
	     are varying.  */
	  if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1))
	    set_value_range_to_nonnull (vr, TREE_TYPE (expr));
	  else if (range_is_null (&vr0) && range_is_null (&vr1))
	    set_value_range_to_null (vr, TREE_TYPE (expr));
	  else
	    set_value_range_to_varying (vr);

	  return;
	}
      gcc_assert (code == POINTER_PLUS_EXPR);
      /* For pointer types, we are really only interested in asserting
	 whether the expression evaluates to non-NULL.  */
      if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
	set_value_range_to_nonnull (vr, TREE_TYPE (expr));
      else if (range_is_null (&vr0) && range_is_null (&vr1))
	set_value_range_to_null (vr, TREE_TYPE (expr));
      else
	set_value_range_to_varying (vr);

      return;
    }

  /* For integer ranges, apply the operation to each end of the
     range and see what we end up with.  */
  if (code == TRUTH_ANDIF_EXPR
      || code == TRUTH_ORIF_EXPR
      || code == TRUTH_AND_EXPR
      || code == TRUTH_OR_EXPR)
    {
      /* If one of the operands is zero, we know that the whole
	 expression evaluates zero.  */
      if (code == TRUTH_AND_EXPR
	  && ((vr0.type == VR_RANGE
	       && integer_zerop (vr0.min)
	       && integer_zerop (vr0.max))
	      || (vr1.type == VR_RANGE
		  && integer_zerop (vr1.min)
		  && integer_zerop (vr1.max))))
	{
	  type = VR_RANGE;
	  min = max = build_int_cst (TREE_TYPE (expr), 0);
	}
      /* If one of the operands is one, we know that the whole
	 expression evaluates one.  */
      else if (code == TRUTH_OR_EXPR
	       && ((vr0.type == VR_RANGE
		    && integer_onep (vr0.min)
		    && integer_onep (vr0.max))
		   || (vr1.type == VR_RANGE
		       && integer_onep (vr1.min)
		       && integer_onep (vr1.max))))
	{
	  type = VR_RANGE;
	  min = max = build_int_cst (TREE_TYPE (expr), 1);
	}
      else if (vr0.type != VR_VARYING
	       && vr1.type != VR_VARYING
	       && vr0.type == vr1.type
	       && !symbolic_range_p (&vr0)
	       && !overflow_infinity_range_p (&vr0)
	       && !symbolic_range_p (&vr1)
	       && !overflow_infinity_range_p (&vr1))
	{
	  /* Boolean expressions cannot be folded with int_const_binop.  */
	  min = fold_binary (code, TREE_TYPE (expr), vr0.min, vr1.min);
	  max = fold_binary (code, TREE_TYPE (expr), vr0.max, vr1.max);
	}
      else
	{
	  /* The result of a TRUTH_*_EXPR is always true or false.  */
	  set_value_range_to_truthvalue (vr, TREE_TYPE (expr));
	  return;
	}
    }
  else if (code == PLUS_EXPR
	   || code == MIN_EXPR
	   || code == MAX_EXPR)
    {
      /* If we have a PLUS_EXPR with two VR_ANTI_RANGEs, drop to
	 VR_VARYING.  It would take more effort to compute a precise
	 range for such a case.  For example, if we have op0 == 1 and
	 op1 == -1 with their ranges both being ~[0,0], we would have
	 op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
	 Note that we are guaranteed to have vr0.type == vr1.type at
	 this point.  */
      if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
	{
	  set_value_range_to_varying (vr);
	  return;
	}

      /* For operations that make the resulting range directly
	 proportional to the original ranges, apply the operation to
	 the same end of each range.  */
      min = vrp_int_const_binop (code, vr0.min, vr1.min);
      max = vrp_int_const_binop (code, vr0.max, vr1.max);
    }
  else if (code == MULT_EXPR
	   || code == TRUNC_DIV_EXPR
	   || code == FLOOR_DIV_EXPR
	   || code == CEIL_DIV_EXPR
	   || code == EXACT_DIV_EXPR
	   || code == ROUND_DIV_EXPR
	   || code == RSHIFT_EXPR)
    {
      tree val[4];
      size_t i;
      bool sop;

      /* If we have an unsigned MULT_EXPR with two VR_ANTI_RANGEs,
	 drop to VR_VARYING.  It would take more effort to compute a
	 precise range for such a case.  For example, if we have
	 op0 == 65536 and op1 == 65536 with their ranges both being
	 ~[0,0] on a 32-bit machine, we would have op0 * op1 == 0, so
	 we cannot claim that the product is in ~[0,0].  Note that we
	 are guaranteed to have vr0.type == vr1.type at this
	 point.  */
      if (code == MULT_EXPR
	  && vr0.type == VR_ANTI_RANGE
	  && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
	{
	  set_value_range_to_varying (vr);
	  return;
	}

      /* If we have a RSHIFT_EXPR with any shift values outside [0..prec-1],
	 then drop to VR_VARYING.  Outside of this range we get undefined
	 behavior from the shift operation.  We cannot even trust
	 SHIFT_COUNT_TRUNCATED at this stage, because that applies to rtl
	 shifts, and the operation at the tree level may be widened.  */
      if (code == RSHIFT_EXPR)
	{
	  if (vr1.type == VR_ANTI_RANGE
	      || !vrp_expr_computes_nonnegative (op1, &sop)
	      || (operand_less_p
		  (build_int_cst (TREE_TYPE (vr1.max),
				  TYPE_PRECISION (TREE_TYPE (expr)) - 1),
		   vr1.max) != 0))
	    {
	      set_value_range_to_varying (vr);
	      return;
	    }
	}

      /* Multiplications and divisions are a bit tricky to handle,
	 depending on the mix of signs we have in the two ranges, we
	 need to operate on different values to get the minimum and
	 maximum values for the new range.  One approach is to figure
	 out all the variations of range combinations and do the
	 operations.

	 However, this involves several calls to compare_values and it
	 is pretty convoluted.  It's simpler to do the 4 operations
	 (MIN0 OP MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP
	 MAX1) and then figure the smallest and largest values to form
	 the new range.  */

      /* Divisions by zero result in a VARYING value.  */
      else if (code != MULT_EXPR
	       && (vr0.type == VR_ANTI_RANGE || range_includes_zero_p (&vr1)))
	{
	  set_value_range_to_varying (vr);
	  return;
	}

      /* Compute the 4 cross operations.  */
      sop = false;
      val[0] = vrp_int_const_binop (code, vr0.min, vr1.min);
      if (val[0] == NULL_TREE)
	sop = true;

      if (vr1.max == vr1.min)
	val[1] = NULL_TREE;
      else
	{
	  val[1] = vrp_int_const_binop (code, vr0.min, vr1.max);
	  if (val[1] == NULL_TREE)
	    sop = true;
	}

      if (vr0.max == vr0.min)
	val[2] = NULL_TREE;
      else
	{
	  val[2] = vrp_int_const_binop (code, vr0.max, vr1.min);
	  if (val[2] == NULL_TREE)
	    sop = true;
	}

      if (vr0.min == vr0.max || vr1.min == vr1.max)
	val[3] = NULL_TREE;
      else
	{
	  val[3] = vrp_int_const_binop (code, vr0.max, vr1.max);
	  if (val[3] == NULL_TREE)
	    sop = true;
	}

      if (sop)
	{
	  set_value_range_to_varying (vr);
	  return;
	}

      /* Set MIN to the minimum of VAL[i] and MAX to the maximum
	 of VAL[i].  */
      min = val[0];
      max = val[0];
      for (i = 1; i < 4; i++)
	{
	  if (!is_gimple_min_invariant (min)
	      || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
	      || !is_gimple_min_invariant (max)
	      || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
	    break;

	  if (val[i])
	    {
	      if (!is_gimple_min_invariant (val[i])
		  || (TREE_OVERFLOW (val[i])
		      && !is_overflow_infinity (val[i])))
		{
		  /* If we found an overflowed value, set MIN and MAX
		     to it so that we set the resulting range to
		     VARYING.  */
		  min = max = val[i];
		  break;
		}

	      if (compare_values (val[i], min) == -1)
		min = val[i];

	      if (compare_values (val[i], max) == 1)
		max = val[i];
	    }
	}
    }
  else if (code == MINUS_EXPR)
    {
      /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to
	 VR_VARYING.  It would take more effort to compute a precise
	 range for such a case.  For example, if we have op0 == 1 and
	 op1 == 1 with their ranges both being ~[0,0], we would have
	 op0 - op1 == 0, so we cannot claim that the difference is in
	 ~[0,0].  Note that we are guaranteed to have
	 vr0.type == vr1.type at this point.  */
      if (vr0.type == VR_ANTI_RANGE)
	{
	  set_value_range_to_varying (vr);
	  return;
	}

      /* For MINUS_EXPR, apply the operation to the opposite ends of
	 each range.  */
      min = vrp_int_const_binop (code, vr0.min, vr1.max);
      max = vrp_int_const_binop (code, vr0.max, vr1.min);
    }
  else if (code == BIT_AND_EXPR)
    {
      if (vr0.type == VR_RANGE
	  && vr0.min == vr0.max
	  && TREE_CODE (vr0.max) == INTEGER_CST
	  && !TREE_OVERFLOW (vr0.max)
	  && tree_int_cst_sgn (vr0.max) >= 0)
	{
	  min = build_int_cst (TREE_TYPE (expr), 0);
	  max = vr0.max;
	}
      else if (vr1.type == VR_RANGE
	       && vr1.min == vr1.max
	       && TREE_CODE (vr1.max) == INTEGER_CST
	       && !TREE_OVERFLOW (vr1.max)
	       && tree_int_cst_sgn (vr1.max) >= 0)
	{
	  type = VR_RANGE;
	  min = build_int_cst (TREE_TYPE (expr), 0);
	  max = vr1.max;
	}
      else
	{
	  set_value_range_to_varying (vr);
	  return;
	}
    }
  else
    gcc_unreachable ();

  /* If either MIN or MAX overflowed, then set the resulting range to
     VARYING.  But we do accept an overflow infinity
     representation.  */
  if (min == NULL_TREE
      || !is_gimple_min_invariant (min)
      || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
      || max == NULL_TREE
      || !is_gimple_min_invariant (max)
      || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
    {
      set_value_range_to_varying (vr);
      return;
    }

  /* We punt if:
     1) [-INF, +INF]
     2) [-INF, +-INF(OVF)]
     3) [+-INF(OVF), +INF]
     4) [+-INF(OVF), +-INF(OVF)]
     We learn nothing when we have INF and INF(OVF) on both sides.
     Note that we do accept [-INF, -INF] and [+INF, +INF] without
     overflow.  */
  if ((vrp_val_is_min (min) || is_overflow_infinity (min))
      && (vrp_val_is_max (max) || is_overflow_infinity (max)))
    {
      set_value_range_to_varying (vr);
      return;
    }

  cmp = compare_values (min, max);
  if (cmp == -2 || cmp == 1)
    {
      /* If the new range has its limits swapped around (MIN > MAX),
	 then the operation caused one of them to wrap around, mark
	 the new range VARYING.  */
      set_value_range_to_varying (vr);
    }
  else
    set_value_range (vr, type, min, max, NULL);
}


/* Extract range information from a unary expression EXPR based on
   the range of its operand and the expression code.  */

static void
extract_range_from_unary_expr (value_range_t *vr, tree expr)
{
  enum tree_code code = TREE_CODE (expr);
  tree min, max, op0;
  int cmp;
  value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };

  /* Refuse to operate on certain unary expressions for which we
     cannot easily determine a resulting range.  */
  if (code == FIX_TRUNC_EXPR
      || code == FLOAT_EXPR
      || code == BIT_NOT_EXPR
      || code == NON_LVALUE_EXPR
      || code == CONJ_EXPR)
    {
      set_value_range_to_varying (vr);
      return;
    }

  /* Get value ranges for the operand.  For constant operands, create
     a new value range with the operand to simplify processing.  */
  op0 = TREE_OPERAND (expr, 0);
  if (TREE_CODE (op0) == SSA_NAME)
    vr0 = *(get_value_range (op0));
  else if (is_gimple_min_invariant (op0))
    set_value_range_to_value (&vr0, op0, NULL);
  else
    set_value_range_to_varying (&vr0);

  /* If VR0 is UNDEFINED, so is the result.  */
  if (vr0.type == VR_UNDEFINED)
    {
      set_value_range_to_undefined (vr);
      return;
    }

  /* Refuse to operate on symbolic ranges, or if neither operand is
     a pointer or integral type.  */
  if ((!INTEGRAL_TYPE_P (TREE_TYPE (op0))
       && !POINTER_TYPE_P (TREE_TYPE (op0)))
      || (vr0.type != VR_VARYING
	  && symbolic_range_p (&vr0)))
    {
      set_value_range_to_varying (vr);
      return;
    }

  /* If the expression involves pointers, we are only interested in
     determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]).  */
  if (POINTER_TYPE_P (TREE_TYPE (expr)) || POINTER_TYPE_P (TREE_TYPE (op0)))
    {
      bool sop;

      sop = false;
      if (range_is_nonnull (&vr0)
	  || (tree_expr_nonzero_warnv_p (expr, &sop)
	      && !sop))
	set_value_range_to_nonnull (vr, TREE_TYPE (expr));
      else if (range_is_null (&vr0))
	set_value_range_to_null (vr, TREE_TYPE (expr));
      else
	set_value_range_to_varying (vr);

      return;
    }

  /* Handle unary expressions on integer ranges.  */
  if (code == NOP_EXPR || code == CONVERT_EXPR)
    {
      tree inner_type = TREE_TYPE (op0);
      tree outer_type = TREE_TYPE (expr);

      /* If VR0 represents a simple range, then try to convert
	 the min and max values for the range to the same type
	 as OUTER_TYPE.  If the results compare equal to VR0's
	 min and max values and the new min is still less than
	 or equal to the new max, then we can safely use the newly
	 computed range for EXPR.  This allows us to compute
	 accurate ranges through many casts.  */
      if ((vr0.type == VR_RANGE
	   && !overflow_infinity_range_p (&vr0))
	  || (vr0.type == VR_VARYING
	      && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)))
	{
	  tree new_min, new_max, orig_min, orig_max;

	  /* Convert the input operand min/max to OUTER_TYPE.   If
	     the input has no range information, then use the min/max
	     for the input's type.  */
	  if (vr0.type == VR_RANGE)
	    {
	      orig_min = vr0.min;
	      orig_max = vr0.max;
	    }
	  else
	    {
	      orig_min = TYPE_MIN_VALUE (inner_type);
	      orig_max = TYPE_MAX_VALUE (inner_type);
	    }

	  new_min = fold_convert (outer_type, orig_min);
	  new_max = fold_convert (outer_type, orig_max);

	  /* Verify the new min/max values are gimple values and
	     that they compare equal to the original input's
	     min/max values.  */
	  if (is_gimple_val (new_min)
	      && is_gimple_val (new_max)
	      && tree_int_cst_equal (new_min, orig_min)
	      && tree_int_cst_equal (new_max, orig_max)
	      && (!is_overflow_infinity (new_min)
		  || !is_overflow_infinity (new_max))
	      && (cmp = compare_values (new_min, new_max)) <= 0
	      && cmp >= -1)
	    {
	      set_value_range (vr, VR_RANGE, new_min, new_max, vr->equiv);
	      return;
	    }
	}

      /* When converting types of different sizes, set the result to
	 VARYING.  Things like sign extensions and precision loss may
	 change the range.  For instance, if x_3 is of type 'long long
	 int' and 'y_5 = (unsigned short) x_3', if x_3 is ~[0, 0], it
	 is impossible to know at compile time whether y_5 will be
	 ~[0, 0].  */
      if (TYPE_SIZE (inner_type) != TYPE_SIZE (outer_type)
	  || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
	{
	  set_value_range_to_varying (vr);
	  return;
	}
    }

  /* Conversion of a VR_VARYING value to a wider type can result
     in a usable range.  So wait until after we've handled conversions
     before dropping the result to VR_VARYING if we had a source
     operand that is VR_VARYING.  */
  if (vr0.type == VR_VARYING)
    {
      set_value_range_to_varying (vr);
      return;
    }

  /* Apply the operation to each end of the range and see what we end
     up with.  */
  if (code == NEGATE_EXPR
      && !TYPE_UNSIGNED (TREE_TYPE (expr)))
    {
      /* NEGATE_EXPR flips the range around.  We need to treat
	 TYPE_MIN_VALUE specially.  */
      if (is_positive_overflow_infinity (vr0.max))
	min = negative_overflow_infinity (TREE_TYPE (expr));
      else if (is_negative_overflow_infinity (vr0.max))
	min = positive_overflow_infinity (TREE_TYPE (expr));
      else if (!vrp_val_is_min (vr0.max))
	min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
      else if (needs_overflow_infinity (TREE_TYPE (expr)))
	{
	  if (supports_overflow_infinity (TREE_TYPE (expr))
	      && !is_overflow_infinity (vr0.min)
	      && !vrp_val_is_min (vr0.min))
	    min = positive_overflow_infinity (TREE_TYPE (expr));
	  else
	    {
	      set_value_range_to_varying (vr);
	      return;
	    }
	}
      else
	min = TYPE_MIN_VALUE (TREE_TYPE (expr));

      if (is_positive_overflow_infinity (vr0.min))
	max = negative_overflow_infinity (TREE_TYPE (expr));
      else if (is_negative_overflow_infinity (vr0.min))
	max = positive_overflow_infinity (TREE_TYPE (expr));
      else if (!vrp_val_is_min (vr0.min))
	max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
      else if (needs_overflow_infinity (TREE_TYPE (expr)))
	{
	  if (supports_overflow_infinity (TREE_TYPE (expr)))
	    max = positive_overflow_infinity (TREE_TYPE (expr));
	  else
	    {
	      set_value_range_to_varying (vr);
	      return;
	    }
	}
      else
	max = TYPE_MIN_VALUE (TREE_TYPE (expr));
    }
  else if (code == NEGATE_EXPR
	   && TYPE_UNSIGNED (TREE_TYPE (expr)))
    {
      if (!range_includes_zero_p (&vr0))
	{
	  max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
	  min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
	}
      else
	{
	  if (range_is_null (&vr0))
	    set_value_range_to_null (vr, TREE_TYPE (expr));
	  else
	    set_value_range_to_varying (vr);
	  return;
	}
    }
  else if (code == ABS_EXPR
           && !TYPE_UNSIGNED (TREE_TYPE (expr)))
    {
      /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
         useful range.  */
      if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (expr))
	  && ((vr0.type == VR_RANGE
	       && vrp_val_is_min (vr0.min))
	      || (vr0.type == VR_ANTI_RANGE
		  && !vrp_val_is_min (vr0.min)
		  && !range_includes_zero_p (&vr0))))
	{
	  set_value_range_to_varying (vr);
	  return;
	}
	
      /* ABS_EXPR may flip the range around, if the original range
	 included negative values.  */
      if (is_overflow_infinity (vr0.min))
	min = positive_overflow_infinity (TREE_TYPE (expr));
      else if (!vrp_val_is_min (vr0.min))
	min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
      else if (!needs_overflow_infinity (TREE_TYPE (expr)))
	min = TYPE_MAX_VALUE (TREE_TYPE (expr));
      else if (supports_overflow_infinity (TREE_TYPE (expr)))
	min = positive_overflow_infinity (TREE_TYPE (expr));
      else
	{
	  set_value_range_to_varying (vr);
	  return;
	}

      if (is_overflow_infinity (vr0.max))
	max = positive_overflow_infinity (TREE_TYPE (expr));
      else if (!vrp_val_is_min (vr0.max))
	max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
      else if (!needs_overflow_infinity (TREE_TYPE (expr)))
	max = TYPE_MAX_VALUE (TREE_TYPE (expr));
      else if (supports_overflow_infinity (TREE_TYPE (expr)))
	max = positive_overflow_infinity (TREE_TYPE (expr));
      else
	{
	  set_value_range_to_varying (vr);
	  return;
	}

      cmp = compare_values (min, max);

      /* If a VR_ANTI_RANGEs contains zero, then we have
	 ~[-INF, min(MIN, MAX)].  */
      if (vr0.type == VR_ANTI_RANGE)
	{ 
	  if (range_includes_zero_p (&vr0))
	    {
	      /* Take the lower of the two values.  */
	      if (cmp != 1)
		max = min;

	      /* Create ~[-INF, min (abs(MIN), abs(MAX))]
	         or ~[-INF + 1, min (abs(MIN), abs(MAX))] when
		 flag_wrapv is set and the original anti-range doesn't include
	         TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
	      if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr)))
		{
		  tree type_min_value = TYPE_MIN_VALUE (TREE_TYPE (expr));

		  min = (vr0.min != type_min_value
			 ? int_const_binop (PLUS_EXPR, type_min_value,
					    integer_one_node, 0)
			 : type_min_value);
		}
	      else
		{
		  if (overflow_infinity_range_p (&vr0))
		    min = negative_overflow_infinity (TREE_TYPE (expr));
		  else
		    min = TYPE_MIN_VALUE (TREE_TYPE (expr));
		}
	    }
	  else
	    {
	      /* All else has failed, so create the range [0, INF], even for
	         flag_wrapv since TYPE_MIN_VALUE is in the original
	         anti-range.  */
	      vr0.type = VR_RANGE;
	      min = build_int_cst (TREE_TYPE (expr), 0);
	      if (needs_overflow_infinity (TREE_TYPE (expr)))
		{
		  if (supports_overflow_infinity (TREE_TYPE (expr)))
		    max = positive_overflow_infinity (TREE_TYPE (expr));
		  else
		    {
		      set_value_range_to_varying (vr);
		      return;
		    }
		}
	      else
		max = TYPE_MAX_VALUE (TREE_TYPE (expr));
	    }
	}

      /* If the range contains zero then we know that the minimum value in the
         range will be zero.  */
      else if (range_includes_zero_p (&vr0))
	{
	  if (cmp == 1)
	    max = min;
	  min = build_int_cst (TREE_TYPE (expr), 0);
	}
      else
	{
          /* If the range was reversed, swap MIN and MAX.  */
	  if (cmp == 1)
	    {
	      tree t = min;
	      min = max;
	      max = t;
	    }
	}
    }
  else
    {
      /* Otherwise, operate on each end of the range.  */
      min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
      max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);

      if (needs_overflow_infinity (TREE_TYPE (expr)))
	{
	  gcc_assert (code != NEGATE_EXPR && code != ABS_EXPR);

	  /* If both sides have overflowed, we don't know
	     anything.  */
	  if ((is_overflow_infinity (vr0.min)
	       || TREE_OVERFLOW (min))
	      && (is_overflow_infinity (vr0.max)
		  || TREE_OVERFLOW (max)))
	    {
	      set_value_range_to_varying (vr);
	      return;
	    }

	  if (is_overflow_infinity (vr0.min))
	    min = vr0.min;
	  else if (TREE_OVERFLOW (min))
	    {
	      if (supports_overflow_infinity (TREE_TYPE (expr)))
		min = (tree_int_cst_sgn (min) >= 0
		       ? positive_overflow_infinity (TREE_TYPE (min))
		       : negative_overflow_infinity (TREE_TYPE (min)));
	      else
		{
		  set_value_range_to_varying (vr);
		  return;
		}
	    }

	  if (is_overflow_infinity (vr0.max))
	    max = vr0.max;
	  else if (TREE_OVERFLOW (max))
	    {
	      if (supports_overflow_infinity (TREE_TYPE (expr)))
		max = (tree_int_cst_sgn (max) >= 0
		       ? positive_overflow_infinity (TREE_TYPE (max))
		       : negative_overflow_infinity (TREE_TYPE (max)));
	      else
		{
		  set_value_range_to_varying (vr);
		  return;
		}
	    }
	}
    }

  cmp = compare_values (min, max);
  if (cmp == -2 || cmp == 1)
    {
      /* If the new range has its limits swapped around (MIN > MAX),
	 then the operation caused one of them to wrap around, mark
	 the new range VARYING.  */
      set_value_range_to_varying (vr);
    }
  else
    set_value_range (vr, vr0.type, min, max, NULL);
}


/* Extract range information from a conditional expression EXPR based on
   the ranges of each of its operands and the expression code.  */

static void
extract_range_from_cond_expr (value_range_t *vr, tree expr)
{
  tree op0, op1;
  value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
  value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };

  /* Get value ranges for each operand.  For constant operands, create
     a new value range with the operand to simplify processing.  */
  op0 = COND_EXPR_THEN (expr);
  if (TREE_CODE (op0) == SSA_NAME)
    vr0 = *(get_value_range (op0));
  else if (is_gimple_min_invariant (op0))
    set_value_range_to_value (&vr0, op0, NULL);
  else
    set_value_range_to_varying (&vr0);

  op1 = COND_EXPR_ELSE (expr);
  if (TREE_CODE (op1) == SSA_NAME)
    vr1 = *(get_value_range (op1));
  else if (is_gimple_min_invariant (op1))
    set_value_range_to_value (&vr1, op1, NULL);
  else
    set_value_range_to_varying (&vr1);

  /* The resulting value range is the union of the operand ranges */
  vrp_meet (&vr0, &vr1);
  copy_value_range (vr, &vr0);
}


/* Extract range information from a comparison expression EXPR based
   on the range of its operand and the expression code.  */

static void
extract_range_from_comparison (value_range_t *vr, tree expr)
{
  bool sop = false;
  tree val = vrp_evaluate_conditional_warnv (expr, false, &sop);

  /* A disadvantage of using a special infinity as an overflow
     representation is that we lose the ability to record overflow
     when we don't have an infinity.  So we have to ignore a result
     which relies on overflow.  */

  if (val && !is_overflow_infinity (val) && !sop)
    {
      /* Since this expression was found on the RHS of an assignment,
	 its type may be different from _Bool.  Convert VAL to EXPR's
	 type.  */
      val = fold_convert (TREE_TYPE (expr), val);
      if (is_gimple_min_invariant (val))
	set_value_range_to_value (vr, val, vr->equiv);
      else
	set_value_range (vr, VR_RANGE, val, val, vr->equiv);
    }
  else
    /* The result of a comparison is always true or false.  */
    set_value_range_to_truthvalue (vr, TREE_TYPE (expr));
}


/* Try to compute a useful range out of expression EXPR and store it
   in *VR.  */

static void
extract_range_from_expr (value_range_t *vr, tree expr)
{
  enum tree_code code = TREE_CODE (expr);

  if (code == ASSERT_EXPR)
    extract_range_from_assert (vr, expr);
  else if (code == SSA_NAME)
    extract_range_from_ssa_name (vr, expr);
  else if (TREE_CODE_CLASS (code) == tcc_binary
	   || code == TRUTH_ANDIF_EXPR
	   || code == TRUTH_ORIF_EXPR
	   || code == TRUTH_AND_EXPR
	   || code == TRUTH_OR_EXPR
	   || code == TRUTH_XOR_EXPR)
    extract_range_from_binary_expr (vr, expr);
  else if (TREE_CODE_CLASS (code) == tcc_unary)
    extract_range_from_unary_expr (vr, expr);
  else if (code == COND_EXPR)
    extract_range_from_cond_expr (vr, expr);
  else if (TREE_CODE_CLASS (code) == tcc_comparison)
    extract_range_from_comparison (vr, expr);
  else if (is_gimple_min_invariant (expr))
    set_value_range_to_value (vr, expr, NULL);
  else
    set_value_range_to_varying (vr);

  /* If we got a varying range from the tests above, try a final
     time to derive a nonnegative or nonzero range.  This time
     relying primarily on generic routines in fold in conjunction
     with range data.  */
  if (vr->type == VR_VARYING)
    {
      bool sop = false;

      if (INTEGRAL_TYPE_P (TREE_TYPE (expr))
	  && vrp_expr_computes_nonnegative (expr, &sop))
	set_value_range_to_nonnegative (vr, TREE_TYPE (expr),
					sop || is_overflow_infinity (expr));
      else if (vrp_expr_computes_nonzero (expr, &sop)
	       && !sop)
        set_value_range_to_nonnull (vr, TREE_TYPE (expr));
    }
}

/* Given a range VR, a LOOP and a variable VAR, determine whether it
   would be profitable to adjust VR using scalar evolution information
   for VAR.  If so, update VR with the new limits.  */

static void
adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
			tree var)
{
  tree init, step, chrec, tmin, tmax, min, max, type;
  enum ev_direction dir;

  /* TODO.  Don't adjust anti-ranges.  An anti-range may provide
     better opportunities than a regular range, but I'm not sure.  */
  if (vr->type == VR_ANTI_RANGE)
    return;

  /* Ensure that there are not values in the scev cache based on assumptions
     on ranges of ssa names that were changed
     (in set_value_range/set_value_range_to_varying).  Preserve cached numbers
     of iterations, that were computed before the start of VRP (we do not
     recompute these each time to save the compile time).  */
  scev_reset_except_niters ();

  chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));

  /* Like in PR19590, scev can return a constant function.  */
  if (is_gimple_min_invariant (chrec))
    {
      set_value_range_to_value (vr, chrec, vr->equiv);
      return;
    }

  if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
    return;

  init = initial_condition_in_loop_num (chrec, loop->num);
  step = evolution_part_in_loop_num (chrec, loop->num);

  /* If STEP is symbolic, we can't know whether INIT will be the
     minimum or maximum value in the range.  Also, unless INIT is
     a simple expression, compare_values and possibly other functions
     in tree-vrp won't be able to handle it.  */
  if (step == NULL_TREE
      || !is_gimple_min_invariant (step)
      || !valid_value_p (init))
    return;

  dir = scev_direction (chrec);
  if (/* Do not adjust ranges if we do not know whether the iv increases
	 or decreases,  ... */
      dir == EV_DIR_UNKNOWN
      /* ... or if it may wrap.  */
      || scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
				true))
    return;

  /* We use TYPE_MIN_VALUE and TYPE_MAX_VALUE here instead of
     negative_overflow_infinity and positive_overflow_infinity,
     because we have concluded that the loop probably does not
     wrap.  */

  type = TREE_TYPE (var);
  if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
    tmin = lower_bound_in_type (type, type);
  else
    tmin = TYPE_MIN_VALUE (type);
  if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
    tmax = upper_bound_in_type (type, type);
  else
    tmax = TYPE_MAX_VALUE (type);

  if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
    {
      min = tmin;
      max = tmax;

      /* For VARYING or UNDEFINED ranges, just about anything we get
	 from scalar evolutions should be better.  */

      if (dir == EV_DIR_DECREASES)
	max = init;
      else
	min = init;

      /* If we would create an invalid range, then just assume we
	 know absolutely nothing.  This may be over-conservative,
	 but it's clearly safe, and should happen only in unreachable
         parts of code, or for invalid programs.  */
      if (compare_values (min, max) == 1)
	return;

      set_value_range (vr, VR_RANGE, min, max, vr->equiv);
    }
  else if (vr->type == VR_RANGE)
    {
      min = vr->min;
      max = vr->max;

      if (dir == EV_DIR_DECREASES)
	{
	  /* INIT is the maximum value.  If INIT is lower than VR->MAX
	     but no smaller than VR->MIN, set VR->MAX to INIT.  */
	  if (compare_values (init, max) == -1)
	    {
	      max = init;

	      /* If we just created an invalid range with the minimum
		 greater than the maximum, we fail conservatively.
		 This should happen only in unreachable
		 parts of code, or for invalid programs.  */
	      if (compare_values (min, max) == 1)
		return;
	    }

	  /* According to the loop information, the variable does not
	     overflow.  If we think it does, probably because of an
	     overflow due to arithmetic on a different INF value,
	     reset now.  */
	  if (is_negative_overflow_infinity (min))
	    min = tmin;
	}
      else
	{
	  /* If INIT is bigger than VR->MIN, set VR->MIN to INIT.  */
	  if (compare_values (init, min) == 1)
	    {
	      min = init;

	      /* Again, avoid creating invalid range by failing.  */
	      if (compare_values (min, max) == 1)
		return;
	    }

	  if (is_positive_overflow_infinity (max))
	    max = tmax;
	}

      set_value_range (vr, VR_RANGE, min, max, vr->equiv);
    }
}

/* Return true if VAR may overflow at STMT.  This checks any available
   loop information to see if we can determine that VAR does not
   overflow.  */

static bool
vrp_var_may_overflow (tree var, tree stmt)
{
  struct loop *l;
  tree chrec, init, step;

  if (current_loops == NULL)
    return true;

  l = loop_containing_stmt (stmt);
  if (l == NULL)
    return true;

  chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
  if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
    return true;

  init = initial_condition_in_loop_num (chrec, l->num);
  step = evolution_part_in_loop_num (chrec, l->num);

  if (step == NULL_TREE
      || !is_gimple_min_invariant (step)
      || !valid_value_p (init))
    return true;

  /* If we get here, we know something useful about VAR based on the
     loop information.  If it wraps, it may overflow.  */

  if (scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
			     true))
    return true;

  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
    {
      print_generic_expr (dump_file, var, 0);
      fprintf (dump_file, ": loop information indicates does not overflow\n");
    }

  return false;
}


/* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
   
   - Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for
     all the values in the ranges.

   - Return BOOLEAN_FALSE_NODE if the comparison always returns false.

   - Return NULL_TREE if it is not always possible to determine the
     value of the comparison.

   Also set *STRICT_OVERFLOW_P to indicate whether a range with an
   overflow infinity was used in the test.  */


static tree
compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1,
		bool *strict_overflow_p)
{
  /* VARYING or UNDEFINED ranges cannot be compared.  */
  if (vr0->type == VR_VARYING
      || vr0->type == VR_UNDEFINED
      || vr1->type == VR_VARYING
      || vr1->type == VR_UNDEFINED)
    return NULL_TREE;

  /* Anti-ranges need to be handled separately.  */
  if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
    {
      /* If both are anti-ranges, then we cannot compute any
	 comparison.  */
      if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
	return NULL_TREE;

      /* These comparisons are never statically computable.  */
      if (comp == GT_EXPR
	  || comp == GE_EXPR
	  || comp == LT_EXPR
	  || comp == LE_EXPR)
	return NULL_TREE;

      /* Equality can be computed only between a range and an
	 anti-range.  ~[VAL1, VAL2] == [VAL1, VAL2] is always false.  */
      if (vr0->type == VR_RANGE)
	{
	  /* To simplify processing, make VR0 the anti-range.  */
	  value_range_t *tmp = vr0;
	  vr0 = vr1;
	  vr1 = tmp;
	}

      gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);

      if (compare_values_warnv (vr0->min, vr1->min, strict_overflow_p) == 0
	  && compare_values_warnv (vr0->max, vr1->max, strict_overflow_p) == 0)
	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;

      return NULL_TREE;
    }

  if (!usable_range_p (vr0, strict_overflow_p)
      || !usable_range_p (vr1, strict_overflow_p))
    return NULL_TREE;

  /* Simplify processing.  If COMP is GT_EXPR or GE_EXPR, switch the
     operands around and change the comparison code.  */
  if (comp == GT_EXPR || comp == GE_EXPR)
    {
      value_range_t *tmp;
      comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
      tmp = vr0;
      vr0 = vr1;
      vr1 = tmp;
    }

  if (comp == EQ_EXPR)
    {
      /* Equality may only be computed if both ranges represent
	 exactly one value.  */
      if (compare_values_warnv (vr0->min, vr0->max, strict_overflow_p) == 0
	  && compare_values_warnv (vr1->min, vr1->max, strict_overflow_p) == 0)
	{
	  int cmp_min = compare_values_warnv (vr0->min, vr1->min,
					      strict_overflow_p);
	  int cmp_max = compare_values_warnv (vr0->max, vr1->max,
					      strict_overflow_p);
	  if (cmp_min == 0 && cmp_max == 0)
	    return boolean_true_node;
	  else if (cmp_min != -2 && cmp_max != -2)
	    return boolean_false_node;
	}
      /* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1.  */
      else if (compare_values_warnv (vr0->min, vr1->max,
				     strict_overflow_p) == 1
	       || compare_values_warnv (vr1->min, vr0->max,
					strict_overflow_p) == 1)
	return boolean_false_node;

      return NULL_TREE;
    }
  else if (comp == NE_EXPR)
    {
      int cmp1, cmp2;

      /* If VR0 is completely to the left or completely to the right
	 of VR1, they are always different.  Notice that we need to
	 make sure that both comparisons yield similar results to
	 avoid comparing values that cannot be compared at
	 compile-time.  */
      cmp1 = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
      cmp2 = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
      if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
	return boolean_true_node;

      /* If VR0 and VR1 represent a single value and are identical,
	 return false.  */
      else if (compare_values_warnv (vr0->min, vr0->max,
				     strict_overflow_p) == 0
	       && compare_values_warnv (vr1->min, vr1->max,
					strict_overflow_p) == 0
	       && compare_values_warnv (vr0->min, vr1->min,
					strict_overflow_p) == 0
	       && compare_values_warnv (vr0->max, vr1->max,
					strict_overflow_p) == 0)
	return boolean_false_node;

      /* Otherwise, they may or may not be different.  */
      else
	return NULL_TREE;
    }
  else if (comp == LT_EXPR || comp == LE_EXPR)
    {
      int tst;

      /* If VR0 is to the left of VR1, return true.  */
      tst = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
      if ((comp == LT_EXPR && tst == -1)
	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
	{
	  if (overflow_infinity_range_p (vr0)
	      || overflow_infinity_range_p (vr1))
	    *strict_overflow_p = true;
	  return boolean_true_node;
	}

      /* If VR0 is to the right of VR1, return false.  */
      tst = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
      if ((comp == LT_EXPR && (tst == 0 || tst == 1))
	  || (comp == LE_EXPR && tst == 1))
	{
	  if (overflow_infinity_range_p (vr0)
	      || overflow_infinity_range_p (vr1))
	    *strict_overflow_p = true;
	  return boolean_false_node;
	}

      /* Otherwise, we don't know.  */
      return NULL_TREE;
    }
    
  gcc_unreachable ();
}


/* Given a value range VR, a value VAL and a comparison code COMP, return
   BOOLEAN_TRUE_NODE if VR COMP VAL always returns true for all the
   values in VR.  Return BOOLEAN_FALSE_NODE if the comparison
   always returns false.  Return NULL_TREE if it is not always
   possible to determine the value of the comparison.  Also set
   *STRICT_OVERFLOW_P to indicate whether a range with an overflow
   infinity was used in the test.  */

static tree
compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val,
			  bool *strict_overflow_p)
{
  if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
    return NULL_TREE;

  /* Anti-ranges need to be handled separately.  */
  if (vr->type == VR_ANTI_RANGE)
    {
      /* For anti-ranges, the only predicates that we can compute at
	 compile time are equality and inequality.  */
      if (comp == GT_EXPR
	  || comp == GE_EXPR
	  || comp == LT_EXPR
	  || comp == LE_EXPR)
	return NULL_TREE;

      /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2.  */
      if (value_inside_range (val, vr) == 1)
	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;

      return NULL_TREE;
    }

  if (!usable_range_p (vr, strict_overflow_p))
    return NULL_TREE;

  if (comp == EQ_EXPR)
    {
      /* EQ_EXPR may only be computed if VR represents exactly
	 one value.  */
      if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0)
	{
	  int cmp = compare_values_warnv (vr->min, val, strict_overflow_p);
	  if (cmp == 0)
	    return boolean_true_node;
	  else if (cmp == -1 || cmp == 1 || cmp == 2)
	    return boolean_false_node;
	}
      else if (compare_values_warnv (val, vr->min, strict_overflow_p) == -1
	       || compare_values_warnv (vr->max, val, strict_overflow_p) == -1)
	return boolean_false_node;

      return NULL_TREE;
    }
  else if (comp == NE_EXPR)
    {
      /* If VAL is not inside VR, then they are always different.  */
      if (compare_values_warnv (vr->max, val, strict_overflow_p) == -1
	  || compare_values_warnv (vr->min, val, strict_overflow_p) == 1)
	return boolean_true_node;

      /* If VR represents exactly one value equal to VAL, then return
	 false.  */
      if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0
	  && compare_values_warnv (vr->min, val, strict_overflow_p) == 0)
	return boolean_false_node;

      /* Otherwise, they may or may not be different.  */
      return NULL_TREE;
    }
  else if (comp == LT_EXPR || comp == LE_EXPR)
    {
      int tst;

      /* If VR is to the left of VAL, return true.  */
      tst = compare_values_warnv (vr->max, val, strict_overflow_p);
      if ((comp == LT_EXPR && tst == -1)
	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
	{
	  if (overflow_infinity_range_p (vr))
	    *strict_overflow_p = true;
	  return boolean_true_node;
	}

      /* If VR is to the right of VAL, return false.  */
      tst = compare_values_warnv (vr->min, val, strict_overflow_p);
      if ((comp == LT_EXPR && (tst == 0 || tst == 1))
	  || (comp == LE_EXPR && tst == 1))
	{
	  if (overflow_infinity_range_p (vr))
	    *strict_overflow_p = true;
	  return boolean_false_node;
	}

      /* Otherwise, we don't know.  */
      return NULL_TREE;
    }
  else if (comp == GT_EXPR || comp == GE_EXPR)
    {
      int tst;

      /* If VR is to the right of VAL, return true.  */
      tst = compare_values_warnv (vr->min, val, strict_overflow_p);
      if ((comp == GT_EXPR && tst == 1)
	  || (comp == GE_EXPR && (tst == 0 || tst == 1)))
	{
	  if (overflow_infinity_range_p (vr))
	    *strict_overflow_p = true;
	  return boolean_true_node;
	}

      /* If VR is to the left of VAL, return false.  */
      tst = compare_values_warnv (vr->max, val, strict_overflow_p);
      if ((comp == GT_EXPR && (tst == -1 || tst == 0))
	  || (comp == GE_EXPR && tst == -1))
	{
	  if (overflow_infinity_range_p (vr))
	    *strict_overflow_p = true;
	  return boolean_false_node;
	}

      /* Otherwise, we don't know.  */
      return NULL_TREE;
    }

  gcc_unreachable ();
}


/* Debugging dumps.  */

void dump_value_range (FILE *, value_range_t *);
void debug_value_range (value_range_t *);
void dump_all_value_ranges (FILE *);
void debug_all_value_ranges (void);
void dump_vr_equiv (FILE *, bitmap);
void debug_vr_equiv (bitmap);


/* Dump value range VR to FILE.  */

void
dump_value_range (FILE *file, value_range_t *vr)
{
  if (vr == NULL)
    fprintf (file, "[]");
  else if (vr->type == VR_UNDEFINED)
    fprintf (file, "UNDEFINED");
  else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
    {
      tree type = TREE_TYPE (vr->min);

      fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");

      if (is_negative_overflow_infinity (vr->min))
	fprintf (file, "-INF(OVF)");
      else if (INTEGRAL_TYPE_P (type)
	       && !TYPE_UNSIGNED (type)
	       && vrp_val_is_min (vr->min))
	fprintf (file, "-INF");
      else
	print_generic_expr (file, vr->min, 0);

      fprintf (file, ", ");

      if (is_positive_overflow_infinity (vr->max))
	fprintf (file, "+INF(OVF)");
      else if (INTEGRAL_TYPE_P (type)
	       && vrp_val_is_max (vr->max))
	fprintf (file, "+INF");
      else
	print_generic_expr (file, vr->max, 0);

      fprintf (file, "]");

      if (vr->equiv)
	{
	  bitmap_iterator bi;
	  unsigned i, c = 0;

	  fprintf (file, "  EQUIVALENCES: { ");

	  EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi)
	    {
	      print_generic_expr (file, ssa_name (i), 0);
	      fprintf (file, " ");
	      c++;
	    }

	  fprintf (file, "} (%u elements)", c);
	}
    }
  else if (vr->type == VR_VARYING)
    fprintf (file, "VARYING");
  else
    fprintf (file, "INVALID RANGE");
}


/* Dump value range VR to stderr.  */

void
debug_value_range (value_range_t *vr)
{
  dump_value_range (stderr, vr);
  fprintf (stderr, "\n");
}


/* Dump value ranges of all SSA_NAMEs to FILE.  */

void
dump_all_value_ranges (FILE *file)
{
  size_t i;

  for (i = 0; i < num_ssa_names; i++)
    {
      if (vr_value[i])
	{
	  print_generic_expr (file, ssa_name (i), 0);
	  fprintf (file, ": ");
	  dump_value_range (file, vr_value[i]);
	  fprintf (file, "\n");
	}
    }

  fprintf (file, "\n");
}


/* Dump all value ranges to stderr.  */

void
debug_all_value_ranges (void)
{
  dump_all_value_ranges (stderr);
}


/* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
   create a new SSA name N and return the assertion assignment
   'V = ASSERT_EXPR <V, V OP W>'.  */

static tree
build_assert_expr_for (tree cond, tree v)
{
  tree n, assertion;

  gcc_assert (TREE_CODE (v) == SSA_NAME);
  n = duplicate_ssa_name (v, NULL_TREE);

  if (COMPARISON_CLASS_P (cond))
    {
      tree a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond); 
      assertion = build_gimple_modify_stmt (n, a);
    }
  else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
    {
      /* Given !V, build the assignment N = false.  */
      tree op0 = TREE_OPERAND (cond, 0);
      gcc_assert (op0 == v);
      assertion = build_gimple_modify_stmt (n, boolean_false_node);
    }
  else if (TREE_CODE (cond) == SSA_NAME)
    {
      /* Given V, build the assignment N = true.  */
      gcc_assert (v == cond);
      assertion = build_gimple_modify_stmt (n, boolean_true_node);
    }
  else
    gcc_unreachable ();

  SSA_NAME_DEF_STMT (n) = assertion;

  /* The new ASSERT_EXPR, creates a new SSA name that replaces the
     operand of the ASSERT_EXPR. Register the new name and the old one
     in the replacement table so that we can fix the SSA web after
     adding all the ASSERT_EXPRs.  */
  register_new_name_mapping (n, v);

  return assertion;
}


/* Return false if EXPR is a predicate expression involving floating
   point values.  */

static inline bool
fp_predicate (const_tree expr)
{
  return (COMPARISON_CLASS_P (expr)
	  && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))));
}


/* If the range of values taken by OP can be inferred after STMT executes,
   return the comparison code (COMP_CODE_P) and value (VAL_P) that
   describes the inferred range.  Return true if a range could be
   inferred.  */

static bool
infer_value_range (tree stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
{
  *val_p = NULL_TREE;
  *comp_code_p = ERROR_MARK;

  /* Do not attempt to infer anything in names that flow through
     abnormal edges.  */
  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
    return false;

  /* Similarly, don't infer anything from statements that may throw
     exceptions.  */
  if (tree_could_throw_p (stmt))
    return false;

  /* If STMT is the last statement of a basic block with no
     successors, there is no point inferring anything about any of its
     operands.  We would not be able to find a proper insertion point
     for the assertion, anyway.  */
  if (stmt_ends_bb_p (stmt) && EDGE_COUNT (bb_for_stmt (stmt)->succs) == 0)
    return false;

  /* We can only assume that a pointer dereference will yield
     non-NULL if -fdelete-null-pointer-checks is enabled.  */
  if (flag_delete_null_pointer_checks && POINTER_TYPE_P (TREE_TYPE (op)))
    {
      unsigned num_uses, num_loads, num_stores;

      count_uses_and_derefs (op, stmt, &num_uses, &num_loads, &num_stores);
      if (num_loads + num_stores > 0)
	{
	  *val_p = build_int_cst (TREE_TYPE (op), 0);
	  *comp_code_p = NE_EXPR;
	  return true;
	}
    }

  return false;
}


void dump_asserts_for (FILE *, tree);
void debug_asserts_for (tree);
void dump_all_asserts (FILE *);
void debug_all_asserts (void);

/* Dump all the registered assertions for NAME to FILE.  */

void
dump_asserts_for (FILE *file, tree name)
{
  assert_locus_t loc;

  fprintf (file, "Assertions to be inserted for ");
  print_generic_expr (file, name, 0);
  fprintf (file, "\n");

  loc = asserts_for[SSA_NAME_VERSION (name)];
  while (loc)
    {
      fprintf (file, "\t");
      print_generic_expr (file, bsi_stmt (loc->si), 0);
      fprintf (file, "\n\tBB #%d", loc->bb->index);
      if (loc->e)
	{
	  fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
	           loc->e->dest->index);
	  dump_edge_info (file, loc->e, 0);
	}
      fprintf (file, "\n\tPREDICATE: ");
      print_generic_expr (file, name, 0);
      fprintf (file, " %s ", tree_code_name[(int)loc->comp_code]);
      print_generic_expr (file, loc->val, 0);
      fprintf (file, "\n\n");
      loc = loc->next;
    }

  fprintf (file, "\n");
}


/* Dump all the registered assertions for NAME to stderr.  */

void
debug_asserts_for (tree name)
{
  dump_asserts_for (stderr, name);
}


/* Dump all the registered assertions for all the names to FILE.  */

void
dump_all_asserts (FILE *file)
{
  unsigned i;
  bitmap_iterator bi;

  fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
  EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
    dump_asserts_for (file, ssa_name (i));
  fprintf (file, "\n");
}


/* Dump all the registered assertions for all the names to stderr.  */

void
debug_all_asserts (void)
{
  dump_all_asserts (stderr);
}


/* If NAME doesn't have an ASSERT_EXPR registered for asserting
   'NAME COMP_CODE VAL' at a location that dominates block BB or
   E->DEST, then register this location as a possible insertion point
   for ASSERT_EXPR <NAME, NAME COMP_CODE VAL>.

   BB, E and SI provide the exact insertion point for the new
   ASSERT_EXPR.  If BB is NULL, then the ASSERT_EXPR is to be inserted
   on edge E.  Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
   BB.  If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
   must not be NULL.  */

static void
register_new_assert_for (tree name,
			 enum tree_code comp_code,
			 tree val,
			 basic_block bb,
			 edge e,
			 block_stmt_iterator si)
{
  assert_locus_t n, loc, last_loc;
  bool found;
  basic_block dest_bb;

#if defined ENABLE_CHECKING
  gcc_assert (bb == NULL || e == NULL);

  if (e == NULL)
    gcc_assert (TREE_CODE (bsi_stmt (si)) != COND_EXPR
		&& TREE_CODE (bsi_stmt (si)) != SWITCH_EXPR);
#endif

  /* The new assertion A will be inserted at BB or E.  We need to
     determine if the new location is dominated by a previously
     registered location for A.  If we are doing an edge insertion,
     assume that A will be inserted at E->DEST.  Note that this is not
     necessarily true.
     
     If E is a critical edge, it will be split.  But even if E is
     split, the new block will dominate the same set of blocks that
     E->DEST dominates.
     
     The reverse, however, is not true, blocks dominated by E->DEST
     will not be dominated by the new block created to split E.  So,
     if the insertion location is on a critical edge, we will not use
     the new location to move another assertion previously registered
     at a block dominated by E->DEST.  */
  dest_bb = (bb) ? bb : e->dest;

  /* If NAME already has an ASSERT_EXPR registered for COMP_CODE and
     VAL at a block dominating DEST_BB, then we don't need to insert a new
     one.  Similarly, if the same assertion already exists at a block
     dominated by DEST_BB and the new location is not on a critical
     edge, then update the existing location for the assertion (i.e.,
     move the assertion up in the dominance tree).

     Note, this is implemented as a simple linked list because there
     should not be more than a handful of assertions registered per
     name.  If this becomes a performance problem, a table hashed by
     COMP_CODE and VAL could be implemented.  */
  loc = asserts_for[SSA_NAME_VERSION (name)];
  last_loc = loc;
  found = false;
  while (loc)
    {
      if (loc->comp_code == comp_code
	  && (loc->val == val
	      || operand_equal_p (loc->val, val, 0)))
	{
	  /* If the assertion NAME COMP_CODE VAL has already been
	     registered at a basic block that dominates DEST_BB, then
	     we don't need to insert the same assertion again.  Note
	     that we don't check strict dominance here to avoid
	     replicating the same assertion inside the same basic
	     block more than once (e.g., when a pointer is
	     dereferenced several times inside a block).

	     An exception to this rule are edge insertions.  If the
	     new assertion is to be inserted on edge E, then it will
	     dominate all the other insertions that we may want to
	     insert in DEST_BB.  So, if we are doing an edge
	     insertion, don't do this dominance check.  */
          if (e == NULL
	      && dominated_by_p (CDI_DOMINATORS, dest_bb, loc->bb))
	    return;

	  /* Otherwise, if E is not a critical edge and DEST_BB
	     dominates the existing location for the assertion, move
	     the assertion up in the dominance tree by updating its
	     location information.  */
	  if ((e == NULL || !EDGE_CRITICAL_P (e))
	      && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
	    {
	      loc->bb = dest_bb;
	      loc->e = e;
	      loc->si = si;
	      return;
	    }
	}

      /* Update the last node of the list and move to the next one.  */
      last_loc = loc;
      loc = loc->next;
    }

  /* If we didn't find an assertion already registered for
     NAME COMP_CODE VAL, add a new one at the end of the list of
     assertions associated with NAME.  */
  n = XNEW (struct assert_locus_d);
  n->bb = dest_bb;
  n->e = e;
  n->si = si;
  n->comp_code = comp_code;
  n->val = val;
  n->next = NULL;

  if (last_loc)
    last_loc->next = n;
  else
    asserts_for[SSA_NAME_VERSION (name)] = n;

  bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
}

/* COND is a predicate which uses NAME.  Extract a suitable test code
   and value and store them into *CODE_P and *VAL_P so the predicate
   is normalized to NAME *CODE_P *VAL_P.

   If no extraction was possible, return FALSE, otherwise return TRUE.

   If INVERT is true, then we invert the result stored into *CODE_P.  */

static bool
extract_code_and_val_from_cond (tree name, tree cond, bool invert,
				enum tree_code *code_p, tree *val_p)
{
  enum tree_code comp_code;
  tree val;

  /* Predicates may be a single SSA name or NAME OP VAL.  */
  if (cond == name)
    {
      /* If the predicate is a name, it must be NAME, in which
	 case we create the predicate NAME == true or
	 NAME == false accordingly.  */
      comp_code = EQ_EXPR;
      val = invert ? boolean_false_node : boolean_true_node;
    }
  else
    {
      /* Otherwise, we have a comparison of the form NAME COMP VAL
         or VAL COMP NAME.  */
      if (name == TREE_OPERAND (cond, 1))
        {
	  /* If the predicate is of the form VAL COMP NAME, flip
	     COMP around because we need to register NAME as the
	     first operand in the predicate.  */
	  comp_code = swap_tree_comparison (TREE_CODE (cond));
	  val = TREE_OPERAND (cond, 0);
	}
      else
	{
	  /* The comparison is of the form NAME COMP VAL, so the
	     comparison code remains unchanged.  */
	  comp_code = TREE_CODE (cond);
	  val = TREE_OPERAND (cond, 1);
	}

      /* Invert the comparison code as necessary.  */
      if (invert)
	comp_code = invert_tree_comparison (comp_code, 0);

      /* VRP does not handle float types.  */
      if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (val)))
	return false;

      /* Do not register always-false predicates.
	 FIXME:  this works around a limitation in fold() when dealing with
	 enumerations.  Given 'enum { N1, N2 } x;', fold will not
	 fold 'if (x > N2)' to 'if (0)'.  */
      if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
	  && INTEGRAL_TYPE_P (TREE_TYPE (val)))
	{
	  tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
	  tree max = TYPE_MAX_VALUE (TREE_TYPE (val));

	  if (comp_code == GT_EXPR
	      && (!max
	          || compare_values (val, max) == 0))
	    return false;

	  if (comp_code == LT_EXPR
	      && (!min
	          || compare_values (val, min) == 0))
	    return false;
	}
    }
  *code_p = comp_code;
  *val_p = val;
  return true;
}

/* OP is an operand of a truth value expression which is known to have
   a particular value.  Register any asserts for OP and for any
   operands in OP's defining statement. 

   If CODE is EQ_EXPR, then we want to register OP is zero (false),
   if CODE is NE_EXPR, then we want to register OP is nonzero (true).   */

static bool
register_edge_assert_for_1 (tree op, enum tree_code code,
			    edge e, block_stmt_iterator bsi)
{
  bool retval = false;
  tree op_def, rhs, val;

  /* We only care about SSA_NAMEs.  */
  if (TREE_CODE (op) != SSA_NAME)
    return false;

  /* We know that OP will have a zero or nonzero value.  If OP is used
     more than once go ahead and register an assert for OP. 

     The FOUND_IN_SUBGRAPH support is not helpful in this situation as
     it will always be set for OP (because OP is used in a COND_EXPR in
     the subgraph).  */
  if (!has_single_use (op))
    {
      val = build_int_cst (TREE_TYPE (op), 0);
      register_new_assert_for (op, code, val, NULL, e, bsi);
      retval = true;
    }

  /* Now look at how OP is set.  If it's set from a comparison,
     a truth operation or some bit operations, then we may be able
     to register information about the operands of that assignment.  */
  op_def = SSA_NAME_DEF_STMT (op);
  if (TREE_CODE (op_def) != GIMPLE_MODIFY_STMT)
    return retval;

  rhs = GIMPLE_STMT_OPERAND (op_def, 1);

  if (COMPARISON_CLASS_P (rhs))
    {
      bool invert = (code == EQ_EXPR ? true : false);
      tree op0 = TREE_OPERAND (rhs, 0);
      tree op1 = TREE_OPERAND (rhs, 1);

      /* Conditionally register an assert for each SSA_NAME in the
	 comparison.  */
      if (TREE_CODE (op0) == SSA_NAME
	  && !has_single_use (op0)
	  && extract_code_and_val_from_cond (op0, rhs,
					     invert, &code, &val))
	{
	  register_new_assert_for (op0, code, val, NULL, e, bsi);
	  retval = true;
	}

      /* Similarly for the second operand of the comparison.  */
      if (TREE_CODE (op1) == SSA_NAME
	  && !has_single_use (op1)
	  && extract_code_and_val_from_cond (op1, rhs,
					     invert, &code, &val))
	{
	  register_new_assert_for (op1, code, val, NULL, e, bsi);
	  retval = true;
	}
    }
  else if ((code == NE_EXPR
	    && (TREE_CODE (rhs) == TRUTH_AND_EXPR
		|| TREE_CODE (rhs) == BIT_AND_EXPR))
	   || (code == EQ_EXPR
	       && (TREE_CODE (rhs) == TRUTH_OR_EXPR
		   || TREE_CODE (rhs) == BIT_IOR_EXPR)))
    {
      /* Recurse on each operand.  */
      retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 0),
					    code, e, bsi);
      retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 1),
					    code, e, bsi);
    }
  else if (TREE_CODE (rhs) == TRUTH_NOT_EXPR)
    {
      /* Recurse, flipping CODE.  */
      code = invert_tree_comparison (code, false);
      retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 0),
					    code, e, bsi);
    }
  else if (TREE_CODE (rhs) == SSA_NAME)
    {
      /* Recurse through the copy.  */
      retval |= register_edge_assert_for_1 (rhs, code, e, bsi);
    }
  else if (TREE_CODE (rhs) == NOP_EXPR
	   || TREE_CODE (rhs) == CONVERT_EXPR
	   || TREE_CODE (rhs) == NON_LVALUE_EXPR)
    { 
      /* Recurse through the type conversion.  */
      retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 0),
					    code, e, bsi);
    }

  return retval;
}

/* Try to register an edge assertion for SSA name NAME on edge E for
   the condition COND contributing to the conditional jump pointed to by SI.
   Return true if an assertion for NAME could be registered.  */

static bool
register_edge_assert_for (tree name, edge e, block_stmt_iterator si, tree cond)
{
  tree val;
  enum tree_code comp_code;
  bool retval = false;
  bool is_else_edge = (e->flags & EDGE_FALSE_VALUE) != 0;

  /* Do not attempt to infer anything in names that flow through
     abnormal edges.  */
  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
    return false;

  if (!extract_code_and_val_from_cond (name, cond, is_else_edge,
				       &comp_code, &val))
    return false;

  /* Only register an ASSERT_EXPR if NAME was found in the sub-graph
     reachable from E.  */
  if (TEST_BIT (found_in_subgraph, SSA_NAME_VERSION (name)))
    {
      register_new_assert_for (name, comp_code, val, NULL, e, si);
      retval = true;
    }

  /* If COND is effectively an equality test of an SSA_NAME against
     the value zero or one, then we may be able to assert values
     for SSA_NAMEs which flow into COND.  */

  /* In the case of NAME == 1 or NAME != 0, for TRUTH_AND_EXPR defining
     statement of NAME we can assert both operands of the TRUTH_AND_EXPR
     have nonzero value.  */
  if (((comp_code == EQ_EXPR && integer_onep (val))
       || (comp_code == NE_EXPR && integer_zerop (val))))
    {
      tree def_stmt = SSA_NAME_DEF_STMT (name);

      if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
	  && (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == TRUTH_AND_EXPR
	      || TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == BIT_AND_EXPR))
	{
	  tree op0 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
	  tree op1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 1);
	  retval |= register_edge_assert_for_1 (op0, NE_EXPR, e, si);
	  retval |= register_edge_assert_for_1 (op1, NE_EXPR, e, si);
	}
    }

  /* In the case of NAME == 0 or NAME != 1, for TRUTH_OR_EXPR defining
     statement of NAME we can assert both operands of the TRUTH_OR_EXPR
     have zero value.  */
  if (((comp_code == EQ_EXPR && integer_zerop (val))
       || (comp_code == NE_EXPR && integer_onep (val))))
    {
      tree def_stmt = SSA_NAME_DEF_STMT (name);

      if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
	  && (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == TRUTH_OR_EXPR
	      /* For BIT_IOR_EXPR only if NAME == 0 both operands have
		 necessarily zero value.  */
	      || (comp_code == EQ_EXPR
		  && (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1))
		        == BIT_IOR_EXPR))))
	{
	  tree op0 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
	  tree op1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 1);
	  retval |= register_edge_assert_for_1 (op0, EQ_EXPR, e, si);
	  retval |= register_edge_assert_for_1 (op1, EQ_EXPR, e, si);
	}
    }

  return retval;
}


static bool find_assert_locations (basic_block bb);

/* Determine whether the outgoing edges of BB should receive an
   ASSERT_EXPR for each of the operands of BB's LAST statement.
   The last statement of BB must be a COND_EXPR.

   If any of the sub-graphs rooted at BB have an interesting use of
   the predicate operands, an assert location node is added to the
   list of assertions for the corresponding operands.  */

static bool
find_conditional_asserts (basic_block bb, tree last)
{
  bool need_assert;
  block_stmt_iterator bsi;
  tree op;
  edge_iterator ei;
  edge e;
  ssa_op_iter iter;

  need_assert = false;
  bsi = bsi_for_stmt (last);

  /* Look for uses of the operands in each of the sub-graphs
     rooted at BB.  We need to check each of the outgoing edges
     separately, so that we know what kind of ASSERT_EXPR to
     insert.  */
  FOR_EACH_EDGE (e, ei, bb->succs)
    {
      if (e->dest == bb)
	continue;

      /* Remove the COND_EXPR operands from the FOUND_IN_SUBGRAPH bitmap.
	 Otherwise, when we finish traversing each of the sub-graphs, we
	 won't know whether the variables were found in the sub-graphs or
	 if they had been found in a block upstream from BB. 

	 This is actually a bad idea is some cases, particularly jump
	 threading.  Consider a CFG like the following:

                    0
                   /|
                  1 |
                   \|
                    2
                   / \
                  3   4

	 Assume that one or more operands in the conditional at the
	 end of block 0 are used in a conditional in block 2, but not
	 anywhere in block 1.  In this case we will not insert any
	 assert statements in block 1, which may cause us to miss
	 opportunities to optimize, particularly for jump threading.  */
      FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
	RESET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));

      /* Traverse the strictly dominated sub-graph rooted at E->DEST
	 to determine if any of the operands in the conditional
	 predicate are used.  */
      need_assert |= find_assert_locations (e->dest);

      /* Register the necessary assertions for each operand in the
	 conditional predicate.  */
      FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
	need_assert |= register_edge_assert_for (op, e, bsi,
						 COND_EXPR_COND (last));
    }

  /* Finally, indicate that we have found the operands in the
     conditional.  */
  FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
    SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));

  return need_assert;
}

/* Compare two case labels sorting first by the destination label uid
   and then by the case value.  */

static int
compare_case_labels (const void *p1, const void *p2)
{
  const_tree const case1 = *(const_tree const*)p1;
  const_tree const case2 = *(const_tree const*)p2;
  unsigned int uid1 = DECL_UID (CASE_LABEL (case1));
  unsigned int uid2 = DECL_UID (CASE_LABEL (case2));

  if (uid1 < uid2)
    return -1;
  else if (uid1 == uid2)
    {
      /* Make sure the default label is first in a group.  */
      if (!CASE_LOW (case1))
	return -1;
      else if (!CASE_LOW (case2))
	return 1;
      else
        return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
    }
  else
    return 1;
}

/* Determine whether the outgoing edges of BB should receive an
   ASSERT_EXPR for each of the operands of BB's LAST statement.
   The last statement of BB must be a SWITCH_EXPR.

   If any of the sub-graphs rooted at BB have an interesting use of
   the predicate operands, an assert location node is added to the
   list of assertions for the corresponding operands.  */

static bool
find_switch_asserts (basic_block bb, tree last)
{
  bool need_assert;
  block_stmt_iterator bsi;
  tree op, cond;
  edge e;
  tree vec = SWITCH_LABELS (last), vec2;
  size_t n = TREE_VEC_LENGTH (vec);
  unsigned int idx;

  need_assert = false;
  bsi = bsi_for_stmt (last);
  op = TREE_OPERAND (last, 0);
  if (TREE_CODE (op) != SSA_NAME)
    return false;

  /* Build a vector of case labels sorted by destination label.  */
  vec2 = make_tree_vec (n);
  for (idx = 0; idx < n; ++idx)
    TREE_VEC_ELT (vec2, idx) = TREE_VEC_ELT (vec, idx);
  qsort (&TREE_VEC_ELT (vec2, 0), n, sizeof (tree), compare_case_labels);

  for (idx = 0; idx < n; ++idx)
    {
      tree min, max;
      tree cl = TREE_VEC_ELT (vec2, idx);

      min = CASE_LOW (cl);
      max = CASE_HIGH (cl);

      /* If there are multiple case labels with the same destination
	 we need to combine them to a single value range for the edge.  */
      if (idx + 1 < n
	  && CASE_LABEL (cl) == CASE_LABEL (TREE_VEC_ELT (vec2, idx + 1)))
	{
	  /* Skip labels until the last of the group.  */
	  do {
	    ++idx;
	  } while (idx < n
		   && CASE_LABEL (cl) == CASE_LABEL (TREE_VEC_ELT (vec2, idx)));
	  --idx;

	  /* Pick up the maximum of the case label range.  */
	  if (CASE_HIGH (TREE_VEC_ELT (vec2, idx)))
	    max = CASE_HIGH (TREE_VEC_ELT (vec2, idx));
	  else
	    max = CASE_LOW (TREE_VEC_ELT (vec2, idx));
	}

      /* Nothing to do if the range includes the default label until we
	 can register anti-ranges.  */
      if (min == NULL_TREE)
	continue;

      /* Find the edge to register the assert expr on.  */
      e = find_edge (bb, label_to_block (CASE_LABEL (cl)));

      /* Remove the SWITCH_EXPR operand from the FOUND_IN_SUBGRAPH bitmap.
	 Otherwise, when we finish traversing each of the sub-graphs, we
	 won't know whether the variables were found in the sub-graphs or
	 if they had been found in a block upstream from BB.  */
      RESET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));

      /* Traverse the strictly dominated sub-graph rooted at E->DEST
	 to determine if any of the operands in the conditional
	 predicate are used.  */
      if (e->dest != bb)
	need_assert |= find_assert_locations (e->dest);

      /* Register the necessary assertions for the operand in the
	 SWITCH_EXPR.  */
      cond = build2 (max ? GE_EXPR : EQ_EXPR, boolean_type_node,
		     op, fold_convert (TREE_TYPE (op), min));
      need_assert |= register_edge_assert_for (op, e, bsi, cond);
      if (max)
	{
	  cond = build2 (LE_EXPR, boolean_type_node,
			 op, fold_convert (TREE_TYPE (op), max));
	  need_assert |= register_edge_assert_for (op, e, bsi, cond);
	}
    }

  /* Finally, indicate that we have found the operand in the
     SWITCH_EXPR.  */
  SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));

  return need_assert;
}


/* Traverse all the statements in block BB looking for statements that
   may generate useful assertions for the SSA names in their operand.
   If a statement produces a useful assertion A for name N_i, then the
   list of assertions already generated for N_i is scanned to
   determine if A is actually needed.
   
   If N_i already had the assertion A at a location dominating the
   current location, then nothing needs to be done.  Otherwise, the
   new location for A is recorded instead.

   1- For every statement S in BB, all the variables used by S are
      added to bitmap FOUND_IN_SUBGRAPH.

   2- If statement S uses an operand N in a way that exposes a known
      value range for N, then if N was not already generated by an
      ASSERT_EXPR, create a new assert location for N.  For instance,
      if N is a pointer and the statement dereferences it, we can
      assume that N is not NULL.

   3- COND_EXPRs are a special case of #2.  We can derive range
      information from the predicate but need to insert different
      ASSERT_EXPRs for each of the sub-graphs rooted at the
      conditional block.  If the last statement of BB is a conditional
      expression of the form 'X op Y', then

      a) Remove X and Y from the set FOUND_IN_SUBGRAPH.

      b) If the conditional is the only entry point to the sub-graph
	 corresponding to the THEN_CLAUSE, recurse into it.  On
	 return, if X and/or Y are marked in FOUND_IN_SUBGRAPH, then
	 an ASSERT_EXPR is added for the corresponding variable.

      c) Repeat step (b) on the ELSE_CLAUSE.

      d) Mark X and Y in FOUND_IN_SUBGRAPH.

      For instance,

	    if (a == 9)
	      b = a;
	    else
	      b = c + 1;

      In this case, an assertion on the THEN clause is useful to
      determine that 'a' is always 9 on that edge.  However, an assertion
      on the ELSE clause would be unnecessary.

   4- If BB does not end in a conditional expression, then we recurse
      into BB's dominator children.
   
   At the end of the recursive traversal, every SSA name will have a
   list of locations where ASSERT_EXPRs should be added.  When a new
   location for name N is found, it is registered by calling
   register_new_assert_for.  That function keeps track of all the
   registered assertions to prevent adding unnecessary assertions.
   For instance, if a pointer P_4 is dereferenced more than once in a
   dominator tree, only the location dominating all the dereference of
   P_4 will receive an ASSERT_EXPR.

   If this function returns true, then it means that there are names
   for which we need to generate ASSERT_EXPRs.  Those assertions are
   inserted by process_assert_insertions.  */

static bool
find_assert_locations (basic_block bb)
{
  block_stmt_iterator si;
  tree last, phi;
  bool need_assert;
  basic_block son;

  if (TEST_BIT (blocks_visited, bb->index))
    return false;

  SET_BIT (blocks_visited, bb->index);

  need_assert = false;

  /* Traverse all PHI nodes in BB marking used operands.  */
  for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
    {
      use_operand_p arg_p;
      ssa_op_iter i;

      FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
	{
	  tree arg = USE_FROM_PTR (arg_p);
	  if (TREE_CODE (arg) == SSA_NAME)
	    {
	      gcc_assert (is_gimple_reg (PHI_RESULT (phi)));
	      SET_BIT (found_in_subgraph, SSA_NAME_VERSION (arg));
	    }
	}
    }

  /* Traverse all the statements in BB marking used names and looking
     for statements that may infer assertions for their used operands.  */
  last = NULL_TREE;
  for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
    {
      tree stmt, op;
      ssa_op_iter i;

      stmt = bsi_stmt (si);

      /* See if we can derive an assertion for any of STMT's operands.  */
      FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
	{
	  tree value;
	  enum tree_code comp_code;

	  /* Mark OP in bitmap FOUND_IN_SUBGRAPH.  If STMT is inside
	     the sub-graph of a conditional block, when we return from
	     this recursive walk, our parent will use the
	     FOUND_IN_SUBGRAPH bitset to determine if one of the
	     operands it was looking for was present in the sub-graph.  */
	  SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));

	  /* If OP is used in such a way that we can infer a value
	     range for it, and we don't find a previous assertion for
	     it, create a new assertion location node for OP.  */
	  if (infer_value_range (stmt, op, &comp_code, &value))
	    {
	      /* If we are able to infer a nonzero value range for OP,
		 then walk backwards through the use-def chain to see if OP
		 was set via a typecast.

		 If so, then we can also infer a nonzero value range
		 for the operand of the NOP_EXPR.  */
	      if (comp_code == NE_EXPR && integer_zerop (value))
		{
		  tree t = op;
		  tree def_stmt = SSA_NAME_DEF_STMT (t);
	
		  while (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
			 && TREE_CODE
			     (GIMPLE_STMT_OPERAND (def_stmt, 1)) == NOP_EXPR
			 && TREE_CODE
			     (TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1),
					    0)) == SSA_NAME
			 && POINTER_TYPE_P
			     (TREE_TYPE (TREE_OPERAND
					  (GIMPLE_STMT_OPERAND (def_stmt,
								1), 0))))
		    {
		      t = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
		      def_stmt = SSA_NAME_DEF_STMT (t);

		      /* Note we want to register the assert for the
			 operand of the NOP_EXPR after SI, not after the
			 conversion.  */
		      if (! has_single_use (t))
			{
			  register_new_assert_for (t, comp_code, value,
						   bb, NULL, si);
			  need_assert = true;
			}
		    }
		}

	      /* If OP is used only once, namely in this STMT, don't
		 bother creating an ASSERT_EXPR for it.  Such an
		 ASSERT_EXPR would do nothing but increase compile time.  */
	      if (!has_single_use (op))
		{
		  register_new_assert_for (op, comp_code, value, bb, NULL, si);
		  need_assert = true;
		}
	    }
	}

      /* Remember the last statement of the block.  */
      last = stmt;
    }

  /* If BB's last statement is a conditional expression
     involving integer operands, recurse into each of the sub-graphs
     rooted at BB to determine if we need to add ASSERT_EXPRs.  */
  if (last
      && TREE_CODE (last) == COND_EXPR
      && !fp_predicate (COND_EXPR_COND (last))
      && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
    need_assert |= find_conditional_asserts (bb, last);

  if (last
      && TREE_CODE (last) == SWITCH_EXPR
      && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
    need_assert |= find_switch_asserts (bb, last);

  /* Recurse into the dominator children of BB.  */
  for (son = first_dom_son (CDI_DOMINATORS, bb);
       son;
       son = next_dom_son (CDI_DOMINATORS, son))
    need_assert |= find_assert_locations (son);

  return need_assert;
}


/* Create an ASSERT_EXPR for NAME and insert it in the location
   indicated by LOC.  Return true if we made any edge insertions.  */

static bool
process_assert_insertions_for (tree name, assert_locus_t loc)
{
  /* Build the comparison expression NAME_i COMP_CODE VAL.  */
  tree stmt, cond, assert_expr;
  edge_iterator ei;
  edge e;

  cond = build2 (loc->comp_code, boolean_type_node, name, loc->val);
  assert_expr = build_assert_expr_for (cond, name);

  if (loc->e)
    {
      /* We have been asked to insert the assertion on an edge.  This
	 is used only by COND_EXPR and SWITCH_EXPR assertions.  */
#if defined ENABLE_CHECKING
      gcc_assert (TREE_CODE (bsi_stmt (loc->si)) == COND_EXPR
	  || TREE_CODE (bsi_stmt (loc->si)) == SWITCH_EXPR);
#endif

      bsi_insert_on_edge (loc->e, assert_expr);
      return true;
    }

  /* Otherwise, we can insert right after LOC->SI iff the
     statement must not be the last statement in the block.  */
  stmt = bsi_stmt (loc->si);
  if (!stmt_ends_bb_p (stmt))
    {
      bsi_insert_after (&loc->si, assert_expr, BSI_SAME_STMT);
      return false;
    }

  /* If STMT must be the last statement in BB, we can only insert new
     assertions on the non-abnormal edge out of BB.  Note that since
     STMT is not control flow, there may only be one non-abnormal edge
     out of BB.  */
  FOR_EACH_EDGE (e, ei, loc->bb->succs)
    if (!(e->flags & EDGE_ABNORMAL))
      {
	bsi_insert_on_edge (e, assert_expr);
	return true;
      }

  gcc_unreachable ();
}


/* Process all the insertions registered for every name N_i registered
   in NEED_ASSERT_FOR.  The list of assertions to be inserted are
   found in ASSERTS_FOR[i].  */

static void
process_assert_insertions (void)
{
  unsigned i;
  bitmap_iterator bi;
  bool update_edges_p = false;
  int num_asserts = 0;

  if (dump_file && (dump_flags & TDF_DETAILS))
    dump_all_asserts (dump_file);

  EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
    {
      assert_locus_t loc = asserts_for[i];
      gcc_assert (loc);

      while (loc)
	{
	  assert_locus_t next = loc->next;
	  update_edges_p |= process_assert_insertions_for (ssa_name (i), loc);
	  free (loc);
	  loc = next;
	  num_asserts++;
	}
    }

  if (update_edges_p)
    bsi_commit_edge_inserts ();

  if (dump_file && (dump_flags & TDF_STATS))
    fprintf (dump_file, "\nNumber of ASSERT_EXPR expressions inserted: %d\n\n",
	     num_asserts);
}


/* Traverse the flowgraph looking for conditional jumps to insert range
   expressions.  These range expressions are meant to provide information
   to optimizations that need to reason in terms of value ranges.  They
   will not be expanded into RTL.  For instance, given:

   x = ...
   y = ...
   if (x < y)
     y = x - 2;
   else
     x = y + 3;

   this pass will transform the code into:

   x = ...
   y = ...
   if (x < y)
    {
      x = ASSERT_EXPR <x, x < y>
      y = x - 2
    }
   else
    {
      y = ASSERT_EXPR <y, x <= y>
      x = y + 3
    }

   The idea is that once copy and constant propagation have run, other
   optimizations will be able to determine what ranges of values can 'x'
   take in different paths of the code, simply by checking the reaching
   definition of 'x'.  */

static void
insert_range_assertions (void)
{
  edge e;
  edge_iterator ei;
  bool update_ssa_p;
  
  found_in_subgraph = sbitmap_alloc (num_ssa_names);
  sbitmap_zero (found_in_subgraph);

  blocks_visited = sbitmap_alloc (last_basic_block);
  sbitmap_zero (blocks_visited);

  need_assert_for = BITMAP_ALLOC (NULL);
  asserts_for = XCNEWVEC (assert_locus_t, num_ssa_names);

  calculate_dominance_info (CDI_DOMINATORS);

  update_ssa_p = false;
  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
    if (find_assert_locations (e->dest))
      update_ssa_p = true;

  if (update_ssa_p)
    {
      process_assert_insertions ();
      update_ssa (TODO_update_ssa_no_phi);
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nSSA form after inserting ASSERT_EXPRs\n");
      dump_function_to_file (current_function_decl, dump_file, dump_flags);
    }

  sbitmap_free (found_in_subgraph);
  free (asserts_for);
  BITMAP_FREE (need_assert_for);
}

/* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible arrays
   and "struct" hacks. If VRP can determine that the
   array subscript is a constant, check if it is outside valid
   range. If the array subscript is a RANGE, warn if it is
   non-overlapping with valid range.
   IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR.  */

static void
check_array_ref (tree ref, location_t* locus, bool ignore_off_by_one)
{
  value_range_t* vr = NULL;
  tree low_sub, up_sub;
  tree low_bound, up_bound = array_ref_up_bound (ref);

  low_sub = up_sub = TREE_OPERAND (ref, 1);

  if (!up_bound || TREE_NO_WARNING (ref)
      || TREE_CODE (up_bound) != INTEGER_CST
      /* Can not check flexible arrays.  */
      || (TYPE_SIZE (TREE_TYPE (ref)) == NULL_TREE
          && TYPE_DOMAIN (TREE_TYPE (ref)) != NULL_TREE
          && TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (ref))) == NULL_TREE)
      /* Accesses after the end of arrays of size 0 (gcc
         extension) and 1 are likely intentional ("struct
         hack").  */
      || compare_tree_int (up_bound, 1) <= 0)
    return;

  low_bound = array_ref_low_bound (ref);

  if (TREE_CODE (low_sub) == SSA_NAME)
    {
      vr = get_value_range (low_sub);
      if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
        {
          low_sub = vr->type == VR_RANGE ? vr->max : vr->min;
          up_sub = vr->type == VR_RANGE ? vr->min : vr->max;
        }
    }

  if (vr && vr->type == VR_ANTI_RANGE)
    {
      if (TREE_CODE (up_sub) == INTEGER_CST
          && tree_int_cst_lt (up_bound, up_sub)
          && TREE_CODE (low_sub) == INTEGER_CST
          && tree_int_cst_lt (low_sub, low_bound))
        {
          warning (OPT_Warray_bounds,
                   "%Harray subscript is outside array bounds", locus);
          TREE_NO_WARNING (ref) = 1;
        }
    }
  else if (TREE_CODE (up_sub) == INTEGER_CST
           && tree_int_cst_lt (up_bound, up_sub)
           && !tree_int_cst_equal (up_bound, up_sub)
           && (!ignore_off_by_one
               || !tree_int_cst_equal (int_const_binop (PLUS_EXPR,
                                                        up_bound,
                                                        integer_one_node,
                                                        0),
                                       up_sub)))
    {
      warning (OPT_Warray_bounds, "%Harray subscript is above array bounds",
               locus);
      TREE_NO_WARNING (ref) = 1;
    }
  else if (TREE_CODE (low_sub) == INTEGER_CST
           && tree_int_cst_lt (low_sub, low_bound))
    {
      warning (OPT_Warray_bounds, "%Harray subscript is below array bounds",
               locus);
      TREE_NO_WARNING (ref) = 1;
    }
}

/* Searches if the expr T, located at LOCATION computes
   address of an ARRAY_REF, and call check_array_ref on it.  */

static void
search_for_addr_array(tree t, location_t* location)
{
  while (TREE_CODE (t) == SSA_NAME)
    {
      t = SSA_NAME_DEF_STMT (t);
      if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
	return;
      t = GIMPLE_STMT_OPERAND (t, 1);
    }


  /* We are only interested in addresses of ARRAY_REF's.  */
  if (TREE_CODE (t) != ADDR_EXPR) 
    return;

  /* Check each ARRAY_REFs in the reference chain. */
  do 
    {
      if (TREE_CODE (t) == ARRAY_REF)
	check_array_ref (t, location, true /*ignore_off_by_one*/);

      t = TREE_OPERAND(t,0);
    }
  while (handled_component_p (t));
}

/* walk_tree() callback that checks if *TP is
   an ARRAY_REF inside an ADDR_EXPR (in which an array
   subscript one outside the valid range is allowed). Call
   check_array_ref for each ARRAY_REF found. The location is 
   passed in DATA.  */

static tree
check_array_bounds (tree *tp, int *walk_subtree, void *data)
{
  tree t = *tp;
  tree stmt = (tree)data;
  location_t *location = EXPR_LOCUS (stmt);

  if (!EXPR_HAS_LOCATION (stmt))
    {
      *walk_subtree = FALSE;
      return NULL_TREE;
    }

  *walk_subtree = TRUE;

  if (TREE_CODE (t) == ARRAY_REF)
    check_array_ref (t, location, false /*ignore_off_by_one*/);

  if (TREE_CODE (t) == INDIRECT_REF
      || (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0)))
    search_for_addr_array (TREE_OPERAND (t, 0), location);
  else if (TREE_CODE (t) == CALL_EXPR)
    {
      tree arg;
      call_expr_arg_iterator iter;

      FOR_EACH_CALL_EXPR_ARG (arg, iter, t) 
	search_for_addr_array (arg, location);
    }

  if (TREE_CODE (t) == ADDR_EXPR)
    *walk_subtree = FALSE;

  return NULL_TREE;
}

/* Walk over all statements of all reachable BBs and call check_array_bounds
   on them.  */

static void
check_all_array_refs (void)
{
  basic_block bb;
  block_stmt_iterator si;

  FOR_EACH_BB (bb)
    {
      /* Skip bb's that are clearly unreachable.  */
      if (single_pred_p (bb))
      {
	basic_block pred_bb = EDGE_PRED (bb, 0)->src;
	tree ls = NULL_TREE;

	if (!bsi_end_p (bsi_last (pred_bb)))
	  ls = bsi_stmt (bsi_last (pred_bb));

	if (ls && TREE_CODE (ls) == COND_EXPR
	    && ((COND_EXPR_COND (ls) == boolean_false_node
		 && (EDGE_PRED (bb, 0)->flags & EDGE_TRUE_VALUE))
		|| (COND_EXPR_COND (ls) == boolean_true_node
		    && (EDGE_PRED (bb, 0)->flags & EDGE_FALSE_VALUE))))
	  continue;
      }
      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
	walk_tree (bsi_stmt_ptr (si), check_array_bounds,
		   bsi_stmt (si), NULL);
    }
}

/* Convert range assertion expressions into the implied copies and
   copy propagate away the copies.  Doing the trivial copy propagation
   here avoids the need to run the full copy propagation pass after
   VRP. 
   
   FIXME, this will eventually lead to copy propagation removing the
   names that had useful range information attached to them.  For
   instance, if we had the assertion N_i = ASSERT_EXPR <N_j, N_j > 3>,
   then N_i will have the range [3, +INF].
   
   However, by converting the assertion into the implied copy
   operation N_i = N_j, we will then copy-propagate N_j into the uses
   of N_i and lose the range information.  We may want to hold on to
   ASSERT_EXPRs a little while longer as the ranges could be used in
   things like jump threading.
   
   The problem with keeping ASSERT_EXPRs around is that passes after
   VRP need to handle them appropriately. 

   Another approach would be to make the range information a first
   class property of the SSA_NAME so that it can be queried from
   any pass.  This is made somewhat more complex by the need for
   multiple ranges to be associated with one SSA_NAME.  */

static void
remove_range_assertions (void)
{
  basic_block bb;
  block_stmt_iterator si;

  /* Note that the BSI iterator bump happens at the bottom of the
     loop and no bump is necessary if we're removing the statement
     referenced by the current BSI.  */
  FOR_EACH_BB (bb)
    for (si = bsi_start (bb); !bsi_end_p (si);)
      {
	tree stmt = bsi_stmt (si);
	tree use_stmt;

	if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
	    && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ASSERT_EXPR)
	  {
	    tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), var;
	    tree cond = fold (ASSERT_EXPR_COND (rhs));
	    use_operand_p use_p;
	    imm_use_iterator iter;

	    gcc_assert (cond != boolean_false_node);

	    /* Propagate the RHS into every use of the LHS.  */
	    var = ASSERT_EXPR_VAR (rhs);
	    FOR_EACH_IMM_USE_STMT (use_stmt, iter,
				   GIMPLE_STMT_OPERAND (stmt, 0))
	      FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
		{
		  SET_USE (use_p, var);
		  gcc_assert (TREE_CODE (var) == SSA_NAME);
		}

	    /* And finally, remove the copy, it is not needed.  */
	    bsi_remove (&si, true);
	    release_defs (stmt); 
	  }
	else
	  bsi_next (&si);
      }

  sbitmap_free (blocks_visited);
}


/* Return true if STMT is interesting for VRP.  */

static bool
stmt_interesting_for_vrp (tree stmt)
{
  if (TREE_CODE (stmt) == PHI_NODE
      && is_gimple_reg (PHI_RESULT (stmt))
      && (INTEGRAL_TYPE_P (TREE_TYPE (PHI_RESULT (stmt)))
	  || POINTER_TYPE_P (TREE_TYPE (PHI_RESULT (stmt)))))
    return true;
  else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
    {
      tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
      tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);

      /* In general, assignments with virtual operands are not useful
	 for deriving ranges, with the obvious exception of calls to
	 builtin functions.  */
      if (TREE_CODE (lhs) == SSA_NAME
	  && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
	      || POINTER_TYPE_P (TREE_TYPE (lhs)))
	  && ((TREE_CODE (rhs) == CALL_EXPR
	       && TREE_CODE (CALL_EXPR_FN (rhs)) == ADDR_EXPR
	       && DECL_P (TREE_OPERAND (CALL_EXPR_FN (rhs), 0))
	       && DECL_IS_BUILTIN (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)))
	      || ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)))
	return true;
    }
  else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
    return true;

  return false;
}


/* Initialize local data structures for VRP.  */

static void
vrp_initialize (void)
{
  basic_block bb;

  vr_value = XCNEWVEC (value_range_t *, num_ssa_names);
  vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);

  FOR_EACH_BB (bb)
    {
      block_stmt_iterator si;
      tree phi;

      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
	{
	  if (!stmt_interesting_for_vrp (phi))
	    {
	      tree lhs = PHI_RESULT (phi);
	      set_value_range_to_varying (get_value_range (lhs));
	      DONT_SIMULATE_AGAIN (phi) = true;
	    }
	  else
	    DONT_SIMULATE_AGAIN (phi) = false;
	}

      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
        {
	  tree stmt = bsi_stmt (si);

	  if (!stmt_interesting_for_vrp (stmt))
	    {
	      ssa_op_iter i;
	      tree def;
	      FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
		set_value_range_to_varying (get_value_range (def));
	      DONT_SIMULATE_AGAIN (stmt) = true;
	    }
	  else
	    {
	      DONT_SIMULATE_AGAIN (stmt) = false;
	    }
	}
    }
}


/* Visit assignment STMT.  If it produces an interesting range, record
   the SSA name in *OUTPUT_P.  */

static enum ssa_prop_result
vrp_visit_assignment (tree stmt, tree *output_p)
{
  tree lhs, rhs, def;
  ssa_op_iter iter;

  lhs = GIMPLE_STMT_OPERAND (stmt, 0);
  rhs = GIMPLE_STMT_OPERAND (stmt, 1);

  /* We only keep track of ranges in integral and pointer types.  */
  if (TREE_CODE (lhs) == SSA_NAME
      && ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
	   /* It is valid to have NULL MIN/MAX values on a type.  See
	      build_range_type.  */
	   && TYPE_MIN_VALUE (TREE_TYPE (lhs))
	   && TYPE_MAX_VALUE (TREE_TYPE (lhs)))
	  || POINTER_TYPE_P (TREE_TYPE (lhs))))
    {
      struct loop *l;
      value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };

      extract_range_from_expr (&new_vr, rhs);

      /* If STMT is inside a loop, we may be able to know something
	 else about the range of LHS by examining scalar evolution
	 information.  */
      if (current_loops && (l = loop_containing_stmt (stmt)))
	adjust_range_with_scev (&new_vr, l, stmt, lhs);

      if (update_value_range (lhs, &new_vr))
	{
	  *output_p = lhs;

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "Found new range for ");
	      print_generic_expr (dump_file, lhs, 0);
	      fprintf (dump_file, ": ");
	      dump_value_range (dump_file, &new_vr);
	      fprintf (dump_file, "\n\n");
	    }

	  if (new_vr.type == VR_VARYING)
	    return SSA_PROP_VARYING;

	  return SSA_PROP_INTERESTING;
	}

      return SSA_PROP_NOT_INTERESTING;
    }
  
  /* Every other statement produces no useful ranges.  */
  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
    set_value_range_to_varying (get_value_range (def));

  return SSA_PROP_VARYING;
}

/* Helper that gets the value range of the SSA_NAME with version I
   or a symbolic range containing the SSA_NAME only if the value range
   is varying or undefined.  */

static inline value_range_t
get_vr_for_comparison (int i)
{
  value_range_t vr = *(vr_value[i]);

  /* If name N_i does not have a valid range, use N_i as its own
     range.  This allows us to compare against names that may
     have N_i in their ranges.  */
  if (vr.type == VR_VARYING || vr.type == VR_UNDEFINED)
    {
      vr.type = VR_RANGE;
      vr.min = ssa_name (i);
      vr.max = ssa_name (i);
    }

  return vr;
}

/* Compare all the value ranges for names equivalent to VAR with VAL
   using comparison code COMP.  Return the same value returned by
   compare_range_with_value, including the setting of
   *STRICT_OVERFLOW_P.  */

static tree
compare_name_with_value (enum tree_code comp, tree var, tree val,
			 bool *strict_overflow_p)
{
  bitmap_iterator bi;
  unsigned i;
  bitmap e;
  tree retval, t;
  int used_strict_overflow;
  bool sop;
  value_range_t equiv_vr;

  /* Get the set of equivalences for VAR.  */
  e = get_value_range (var)->equiv;

  /* Start at -1.  Set it to 0 if we do a comparison without relying
     on overflow, or 1 if all comparisons rely on overflow.  */
  used_strict_overflow = -1;

  /* Compare vars' value range with val.  */
  equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var));
  sop = false;
  retval = compare_range_with_value (comp, &equiv_vr, val, &sop);
  if (retval)
    used_strict_overflow = sop ? 1 : 0;

  /* If the equiv set is empty we have done all work we need to do.  */
  if (e == NULL)
    {
      if (retval
	  && used_strict_overflow > 0)
	*strict_overflow_p = true;
      return retval;
    }

  EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
    {
      equiv_vr = get_vr_for_comparison (i);
      sop = false;
      t = compare_range_with_value (comp, &equiv_vr, val, &sop);
      if (t)
	{
	  /* If we get different answers from different members
	     of the equivalence set this check must be in a dead
	     code region.  Folding it to a trap representation
	     would be correct here.  For now just return don't-know.  */
	  if (retval != NULL
	      && t != retval)
	    {
	      retval = NULL_TREE;
	      break;
	    }
	  retval = t;

	  if (!sop)
	    used_strict_overflow = 0;
	  else if (used_strict_overflow < 0)
	    used_strict_overflow = 1;
	}
    }

  if (retval
      && used_strict_overflow > 0)
    *strict_overflow_p = true;

  return retval;
}


/* Given a comparison code COMP and names N1 and N2, compare all the
   ranges equivalent to N1 against all the ranges equivalent to N2
   to determine the value of N1 COMP N2.  Return the same value
   returned by compare_ranges.  Set *STRICT_OVERFLOW_P to indicate
   whether we relied on an overflow infinity in the comparison.  */


static tree
compare_names (enum tree_code comp, tree n1, tree n2,
	       bool *strict_overflow_p)
{
  tree t, retval;
  bitmap e1, e2;
  bitmap_iterator bi1, bi2;
  unsigned i1, i2;
  int used_strict_overflow;
  static bitmap_obstack *s_obstack = NULL;
  static bitmap s_e1 = NULL, s_e2 = NULL;

  /* Compare the ranges of every name equivalent to N1 against the
     ranges of every name equivalent to N2.  */
  e1 = get_value_range (n1)->equiv;
  e2 = get_value_range (n2)->equiv;

  /* Use the fake bitmaps if e1 or e2 are not available.  */
  if (s_obstack == NULL)
    {
      s_obstack = XNEW (bitmap_obstack);
      bitmap_obstack_initialize (s_obstack);
      s_e1 = BITMAP_ALLOC (s_obstack);
      s_e2 = BITMAP_ALLOC (s_obstack);
    }
  if (e1 == NULL)
    e1 = s_e1;
  if (e2 == NULL)
    e2 = s_e2;

  /* Add N1 and N2 to their own set of equivalences to avoid
     duplicating the body of the loop just to check N1 and N2
     ranges.  */
  bitmap_set_bit (e1, SSA_NAME_VERSION (n1));
  bitmap_set_bit (e2, SSA_NAME_VERSION (n2));

  /* If the equivalence sets have a common intersection, then the two
     names can be compared without checking their ranges.  */
  if (bitmap_intersect_p (e1, e2))
    {
      bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
      bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));

      return (comp == EQ_EXPR || comp == GE_EXPR || comp == LE_EXPR)
	     ? boolean_true_node
	     : boolean_false_node;
    }

  /* Start at -1.  Set it to 0 if we do a comparison without relying
     on overflow, or 1 if all comparisons rely on overflow.  */
  used_strict_overflow = -1;

  /* Otherwise, compare all the equivalent ranges.  First, add N1 and
     N2 to their own set of equivalences to avoid duplicating the body
     of the loop just to check N1 and N2 ranges.  */
  EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
    {
      value_range_t vr1 = get_vr_for_comparison (i1);

      t = retval = NULL_TREE;
      EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
	{
	  bool sop = false;

	  value_range_t vr2 = get_vr_for_comparison (i2);

	  t = compare_ranges (comp, &vr1, &vr2, &sop);
	  if (t)
	    {
	      /* If we get different answers from different members
		 of the equivalence set this check must be in a dead
		 code region.  Folding it to a trap representation
		 would be correct here.  For now just return don't-know.  */
	      if (retval != NULL
		  && t != retval)
		{
		  bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
		  bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
		  return NULL_TREE;
		}
	      retval = t;

	      if (!sop)
		used_strict_overflow = 0;
	      else if (used_strict_overflow < 0)
		used_strict_overflow = 1;
	    }
	}

      if (retval)
	{
	  bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
	  bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
	  if (used_strict_overflow > 0)
	    *strict_overflow_p = true;
	  return retval;
	}
    }

  /* None of the equivalent ranges are useful in computing this
     comparison.  */
  bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
  bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
  return NULL_TREE;
}


/* Given a conditional predicate COND, try to determine if COND yields
   true or false based on the value ranges of its operands.  Return
   BOOLEAN_TRUE_NODE if the conditional always evaluates to true,
   BOOLEAN_FALSE_NODE if the conditional always evaluates to false, and,
   NULL if the conditional cannot be evaluated at compile time.

   If USE_EQUIV_P is true, the ranges of all the names equivalent with
   the operands in COND are used when trying to compute its value.
   This is only used during final substitution.  During propagation,
   we only check the range of each variable and not its equivalents.

   Set *STRICT_OVERFLOW_P to indicate whether we relied on an overflow
   infinity to produce the result.  */

static tree
vrp_evaluate_conditional_warnv (tree cond, bool use_equiv_p,
				bool *strict_overflow_p)
{
  gcc_assert (TREE_CODE (cond) == SSA_NAME
              || TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison);

  if (TREE_CODE (cond) == SSA_NAME)
    {
      value_range_t *vr;
      tree retval;

      if (use_equiv_p)
	retval = compare_name_with_value (NE_EXPR, cond, boolean_false_node,
					  strict_overflow_p);
      else
	{
	  value_range_t *vr = get_value_range (cond);
	  retval = compare_range_with_value (NE_EXPR, vr, boolean_false_node,
					     strict_overflow_p);
	}

      /* If COND has a known boolean range, return it.  */
      if (retval)
	return retval;

      /* Otherwise, if COND has a symbolic range of exactly one value,
	 return it.  */
      vr = get_value_range (cond);
      if (vr->type == VR_RANGE && vr->min == vr->max)
	return vr->min;
    }
  else
    {
      tree op0 = TREE_OPERAND (cond, 0);
      tree op1 = TREE_OPERAND (cond, 1);

      /* We only deal with integral and pointer types.  */
      if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
	  && !POINTER_TYPE_P (TREE_TYPE (op0)))
	return NULL_TREE;

      if (use_equiv_p)
	{
	  if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
	    return compare_names (TREE_CODE (cond), op0, op1,
				  strict_overflow_p);
	  else if (TREE_CODE (op0) == SSA_NAME)
	    return compare_name_with_value (TREE_CODE (cond), op0, op1,
					    strict_overflow_p);
	  else if (TREE_CODE (op1) == SSA_NAME)
	    return (compare_name_with_value
		    (swap_tree_comparison (TREE_CODE (cond)), op1, op0,
		     strict_overflow_p));
	}
      else
	{
	  value_range_t *vr0, *vr1;

	  vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
	  vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;

	  if (vr0 && vr1)
	    return compare_ranges (TREE_CODE (cond), vr0, vr1,
				   strict_overflow_p);
	  else if (vr0 && vr1 == NULL)
	    return compare_range_with_value (TREE_CODE (cond), vr0, op1,
					     strict_overflow_p);
	  else if (vr0 == NULL && vr1)
	    return (compare_range_with_value
		    (swap_tree_comparison (TREE_CODE (cond)), vr1, op0,
		     strict_overflow_p));
	}
    }

  /* Anything else cannot be computed statically.  */
  return NULL_TREE;
}

/* Given COND within STMT, try to simplify it based on value range
   information.  Return NULL if the conditional can not be evaluated.
   The ranges of all the names equivalent with the operands in COND
   will be used when trying to compute the value.  If the result is
   based on undefined signed overflow, issue a warning if
   appropriate.  */

tree
vrp_evaluate_conditional (tree cond, tree stmt)
{
  bool sop;
  tree ret;

  sop = false;
  ret = vrp_evaluate_conditional_warnv (cond, true, &sop);

  if (ret && sop)
    {
      enum warn_strict_overflow_code wc;
      const char* warnmsg;

      if (is_gimple_min_invariant (ret))
	{
	  wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
	  warnmsg = G_("assuming signed overflow does not occur when "
		       "simplifying conditional to constant");
	}
      else
	{
	  wc = WARN_STRICT_OVERFLOW_COMPARISON;
	  warnmsg = G_("assuming signed overflow does not occur when "
		       "simplifying conditional");
	}

      if (issue_strict_overflow_warning (wc))
	{
	  location_t locus;

	  if (!EXPR_HAS_LOCATION (stmt))
	    locus = input_location;
	  else
	    locus = EXPR_LOCATION (stmt);
	  warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
	}
    }

  return ret;
}


/* Visit conditional statement STMT.  If we can determine which edge
   will be taken out of STMT's basic block, record it in
   *TAKEN_EDGE_P and return SSA_PROP_INTERESTING.  Otherwise, return
   SSA_PROP_VARYING.  */

static enum ssa_prop_result
vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
{
  tree cond, val;
  bool sop;

  *taken_edge_p = NULL;

  /* FIXME.  Handle SWITCH_EXPRs.  */
  if (TREE_CODE (stmt) == SWITCH_EXPR)
    return SSA_PROP_VARYING;

  cond = COND_EXPR_COND (stmt);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      tree use;
      ssa_op_iter i;

      fprintf (dump_file, "\nVisiting conditional with predicate: ");
      print_generic_expr (dump_file, cond, 0);
      fprintf (dump_file, "\nWith known ranges\n");
      
      FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
	{
	  fprintf (dump_file, "\t");
	  print_generic_expr (dump_file, use, 0);
	  fprintf (dump_file, ": ");
	  dump_value_range (dump_file, vr_value[SSA_NAME_VERSION (use)]);
	}

      fprintf (dump_file, "\n");
    }

  /* Compute the value of the predicate COND by checking the known
     ranges of each of its operands.
     
     Note that we cannot evaluate all the equivalent ranges here
     because those ranges may not yet be final and with the current
     propagation strategy, we cannot determine when the value ranges
     of the names in the equivalence set have changed.

     For instance, given the following code fragment

        i_5 = PHI <8, i_13>
	...
     	i_14 = ASSERT_EXPR <i_5, i_5 != 0>
	if (i_14 == 1)
	  ...

     Assume that on the first visit to i_14, i_5 has the temporary
     range [8, 8] because the second argument to the PHI function is
     not yet executable.  We derive the range ~[0, 0] for i_14 and the
     equivalence set { i_5 }.  So, when we visit 'if (i_14 == 1)' for
     the first time, since i_14 is equivalent to the range [8, 8], we
     determine that the predicate is always false.

     On the next round of propagation, i_13 is determined to be
     VARYING, which causes i_5 to drop down to VARYING.  So, another
     visit to i_14 is scheduled.  In this second visit, we compute the
     exact same range and equivalence set for i_14, namely ~[0, 0] and
     { i_5 }.  But we did not have the previous range for i_5
     registered, so vrp_visit_assignment thinks that the range for
     i_14 has not changed.  Therefore, the predicate 'if (i_14 == 1)'
     is not visited again, which stops propagation from visiting
     statements in the THEN clause of that if().

     To properly fix this we would need to keep the previous range
     value for the names in the equivalence set.  This way we would've
     discovered that from one visit to the other i_5 changed from
     range [8, 8] to VR_VARYING.

     However, fixing this apparent limitation may not be worth the
     additional checking.  Testing on several code bases (GCC, DLV,
     MICO, TRAMP3D and SPEC2000) showed that doing this results in
     4 more predicates folded in SPEC.  */
  sop = false;
  val = vrp_evaluate_conditional_warnv (cond, false, &sop);
  if (val)
    {
      if (!sop)
	*taken_edge_p = find_taken_edge (bb_for_stmt (stmt), val);
      else
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file,
		     "\nIgnoring predicate evaluation because "
		     "it assumes that signed overflow is undefined");
	  val = NULL_TREE;
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nPredicate evaluates to: ");
      if (val == NULL_TREE)
	fprintf (dump_file, "DON'T KNOW\n");
      else
	print_generic_stmt (dump_file, val, 0);
    }

  return (*taken_edge_p) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
}


/* Evaluate statement STMT.  If the statement produces a useful range,
   return SSA_PROP_INTERESTING and record the SSA name with the
   interesting range into *OUTPUT_P.

   If STMT is a conditional branch and we can determine its truth
   value, the taken edge is recorded in *TAKEN_EDGE_P.

   If STMT produces a varying value, return SSA_PROP_VARYING.  */

static enum ssa_prop_result
vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
{
  tree def;
  ssa_op_iter iter;
  stmt_ann_t ann;

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nVisiting statement:\n");
      print_generic_stmt (dump_file, stmt, dump_flags);
      fprintf (dump_file, "\n");
    }

  ann = stmt_ann (stmt);
  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
    {
      tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);

      /* In general, assignments with virtual operands are not useful
	 for deriving ranges, with the obvious exception of calls to
	 builtin functions.  */
      if ((TREE_CODE (rhs) == CALL_EXPR
	   && TREE_CODE (CALL_EXPR_FN (rhs)) == ADDR_EXPR
	   && DECL_P (TREE_OPERAND (CALL_EXPR_FN (rhs), 0))
	   && DECL_IS_BUILTIN (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)))
	  || ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
	return vrp_visit_assignment (stmt, output_p);
    }
  else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
    return vrp_visit_cond_stmt (stmt, taken_edge_p);

  /* All other statements produce nothing of interest for VRP, so mark
     their outputs varying and prevent further simulation.  */
  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
    set_value_range_to_varying (get_value_range (def));

  return SSA_PROP_VARYING;
}


/* Meet operation for value ranges.  Given two value ranges VR0 and
   VR1, store in VR0 a range that contains both VR0 and VR1.  This
   may not be the smallest possible such range.  */

static void
vrp_meet (value_range_t *vr0, value_range_t *vr1)
{
  if (vr0->type == VR_UNDEFINED)
    {
      copy_value_range (vr0, vr1);
      return;
    }

  if (vr1->type == VR_UNDEFINED)
    {
      /* Nothing to do.  VR0 already has the resulting range.  */
      return;
    }

  if (vr0->type == VR_VARYING)
    {
      /* Nothing to do.  VR0 already has the resulting range.  */
      return;
    }

  if (vr1->type == VR_VARYING)
    {
      set_value_range_to_varying (vr0);
      return;
    }

  if (vr0->type == VR_RANGE && vr1->type == VR_RANGE)
    {
      int cmp;
      tree min, max;

      /* Compute the convex hull of the ranges.  The lower limit of
         the new range is the minimum of the two ranges.  If they
	 cannot be compared, then give up.  */
      cmp = compare_values (vr0->min, vr1->min);
      if (cmp == 0 || cmp == 1)
        min = vr1->min;
      else if (cmp == -1)
        min = vr0->min;
      else
	goto give_up;

      /* Similarly, the upper limit of the new range is the maximum
         of the two ranges.  If they cannot be compared, then
	 give up.  */
      cmp = compare_values (vr0->max, vr1->max);
      if (cmp == 0 || cmp == -1)
        max = vr1->max;
      else if (cmp == 1)
        max = vr0->max;
      else
	goto give_up;

      /* Check for useless ranges.  */
      if (INTEGRAL_TYPE_P (TREE_TYPE (min))
	  && ((vrp_val_is_min (min) || is_overflow_infinity (min))
	      && (vrp_val_is_max (max) || is_overflow_infinity (max))))
	goto give_up;

      /* The resulting set of equivalences is the intersection of
	 the two sets.  */
      if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
        bitmap_and_into (vr0->equiv, vr1->equiv);
      else if (vr0->equiv && !vr1->equiv)
        bitmap_clear (vr0->equiv);

      set_value_range (vr0, vr0->type, min, max, vr0->equiv);
    }
  else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
    {
      /* Two anti-ranges meet only if their complements intersect.
         Only handle the case of identical ranges.  */
      if (compare_values (vr0->min, vr1->min) == 0
	  && compare_values (vr0->max, vr1->max) == 0
	  && compare_values (vr0->min, vr0->max) == 0)
	{
	  /* The resulting set of equivalences is the intersection of
	     the two sets.  */
	  if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
	    bitmap_and_into (vr0->equiv, vr1->equiv);
	  else if (vr0->equiv && !vr1->equiv)
	    bitmap_clear (vr0->equiv);
	}
      else
	goto give_up;
    }
  else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
    {
      /* For a numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4],
         only handle the case where the ranges have an empty intersection.
	 The result of the meet operation is the anti-range.  */
      if (!symbolic_range_p (vr0)
	  && !symbolic_range_p (vr1)
	  && !value_ranges_intersect_p (vr0, vr1))
	{
	  /* Copy most of VR1 into VR0.  Don't copy VR1's equivalence
	     set.  We need to compute the intersection of the two
	     equivalence sets.  */
	  if (vr1->type == VR_ANTI_RANGE)
	    set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr0->equiv);

	  /* The resulting set of equivalences is the intersection of
	     the two sets.  */
	  if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
	    bitmap_and_into (vr0->equiv, vr1->equiv);
	  else if (vr0->equiv && !vr1->equiv)
	    bitmap_clear (vr0->equiv);
	}
      else
	goto give_up;
    }
  else
    gcc_unreachable ();

  return;

give_up:
  /* Failed to find an efficient meet.  Before giving up and setting
     the result to VARYING, see if we can at least derive a useful
     anti-range.  FIXME, all this nonsense about distinguishing
     anti-ranges from ranges is necessary because of the odd
     semantics of range_includes_zero_p and friends.  */
  if (!symbolic_range_p (vr0)
      && ((vr0->type == VR_RANGE && !range_includes_zero_p (vr0))
	  || (vr0->type == VR_ANTI_RANGE && range_includes_zero_p (vr0)))
      && !symbolic_range_p (vr1)
      && ((vr1->type == VR_RANGE && !range_includes_zero_p (vr1))
	  || (vr1->type == VR_ANTI_RANGE && range_includes_zero_p (vr1))))
    {
      set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min));

      /* Since this meet operation did not result from the meeting of
	 two equivalent names, VR0 cannot have any equivalences.  */
      if (vr0->equiv)
	bitmap_clear (vr0->equiv);
    }
  else
    set_value_range_to_varying (vr0);
}


/* Visit all arguments for PHI node PHI that flow through executable
   edges.  If a valid value range can be derived from all the incoming
   value ranges, set a new range for the LHS of PHI.  */

static enum ssa_prop_result
vrp_visit_phi_node (tree phi)
{
  int i;
  tree lhs = PHI_RESULT (phi);
  value_range_t *lhs_vr = get_value_range (lhs);
  value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
  int edges, old_edges;

  copy_value_range (&vr_result, lhs_vr);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "\nVisiting PHI node: ");
      print_generic_expr (dump_file, phi, dump_flags);
    }

  edges = 0;
  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
    {
      edge e = PHI_ARG_EDGE (phi, i);

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file,
	      "\n    Argument #%d (%d -> %d %sexecutable)\n",
	      i, e->src->index, e->dest->index,
	      (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
	}

      if (e->flags & EDGE_EXECUTABLE)
	{
	  tree arg = PHI_ARG_DEF (phi, i);
	  value_range_t vr_arg;

	  ++edges;

	  if (TREE_CODE (arg) == SSA_NAME)
	    {
	      vr_arg = *(get_value_range (arg));
	    }
	  else
	    {
	      if (is_overflow_infinity (arg))
		{
		  arg = copy_node (arg);
		  TREE_OVERFLOW (arg) = 0;
		}

	      vr_arg.type = VR_RANGE;
	      vr_arg.min = arg;
	      vr_arg.max = arg;
	      vr_arg.equiv = NULL;
	    }

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "\t");
	      print_generic_expr (dump_file, arg, dump_flags);
	      fprintf (dump_file, "\n\tValue: ");
	      dump_value_range (dump_file, &vr_arg);
	      fprintf (dump_file, "\n");
	    }

	  vrp_meet (&vr_result, &vr_arg);

	  if (vr_result.type == VR_VARYING)
	    break;
	}
    }

  if (vr_result.type == VR_VARYING)
    goto varying;

  old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
  vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges;

  /* To prevent infinite iterations in the algorithm, derive ranges
     when the new value is slightly bigger or smaller than the
     previous one.  We don't do this if we have seen a new executable
     edge; this helps us avoid an overflow infinity for conditionals
     which are not in a loop.  */
  if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE
      && edges <= old_edges)
    {
      if (!POINTER_TYPE_P (TREE_TYPE (lhs)))
	{
	  int cmp_min = compare_values (lhs_vr->min, vr_result.min);
	  int cmp_max = compare_values (lhs_vr->max, vr_result.max);

	  /* If the new minimum is smaller or larger than the previous
	     one, go all the way to -INF.  In the first case, to avoid
	     iterating millions of times to reach -INF, and in the
	     other case to avoid infinite bouncing between different
	     minimums.  */
	  if (cmp_min > 0 || cmp_min < 0)
	    {
	      /* If we will end up with a (-INF, +INF) range, set it
		 to VARYING.  */
	      if (vrp_val_is_max (vr_result.max))
		goto varying;

	      if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
		  || !vrp_var_may_overflow (lhs, phi))
		vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
	      else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
		vr_result.min =
		  negative_overflow_infinity (TREE_TYPE (vr_result.min));
	      else
		goto varying;
	    }

	  /* Similarly, if the new maximum is smaller or larger than
	     the previous one, go all the way to +INF.  */
	  if (cmp_max < 0 || cmp_max > 0)
	    {
	      /* If we will end up with a (-INF, +INF) range, set it
		 to VARYING.  */
	      if (vrp_val_is_min (vr_result.min))
		goto varying;

	      if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
		  || !vrp_var_may_overflow (lhs, phi))
		vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
	      else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
		vr_result.max =
		  positive_overflow_infinity (TREE_TYPE (vr_result.max));
	      else
		goto varying;
	    }
	}
    }

  /* If the new range is different than the previous value, keep
     iterating.  */
  if (update_value_range (lhs, &vr_result))
    return SSA_PROP_INTERESTING;

  /* Nothing changed, don't add outgoing edges.  */
  return SSA_PROP_NOT_INTERESTING;

  /* No match found.  Set the LHS to VARYING.  */
varying:
  set_value_range_to_varying (lhs_vr);
  return SSA_PROP_VARYING;
}

/* Simplify a division or modulo operator to a right shift or
   bitwise and if the first operand is unsigned or is greater
   than zero and the second operand is an exact power of two.  */

static void
simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
{
  tree val = NULL;
  tree op = TREE_OPERAND (rhs, 0);
  value_range_t *vr = get_value_range (TREE_OPERAND (rhs, 0));

  if (TYPE_UNSIGNED (TREE_TYPE (op)))
    {
      val = integer_one_node;
    }
  else
    {
      bool sop = false;

      val = compare_range_with_value (GE_EXPR, vr, integer_zero_node, &sop);

      if (val
	  && sop
	  && integer_onep (val)
	  && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
	{
	  location_t locus;

	  if (!EXPR_HAS_LOCATION (stmt))
	    locus = input_location;
	  else
	    locus = EXPR_LOCATION (stmt);
	  warning (OPT_Wstrict_overflow,
		   ("%Hassuming signed overflow does not occur when "
		    "simplifying / or %% to >> or &"),
		   &locus);
	}
    }

  if (val && integer_onep (val))
    {
      tree t;
      tree op0 = TREE_OPERAND (rhs, 0);
      tree op1 = TREE_OPERAND (rhs, 1);

      if (rhs_code == TRUNC_DIV_EXPR)
	{
	  t = build_int_cst (NULL_TREE, tree_log2 (op1));
	  t = build2 (RSHIFT_EXPR, TREE_TYPE (op0), op0, t);
	}
      else
	{
	  t = build_int_cst (TREE_TYPE (op1), 1);
	  t = int_const_binop (MINUS_EXPR, op1, t, 0);
	  t = fold_convert (TREE_TYPE (op0), t);
	  t = build2 (BIT_AND_EXPR, TREE_TYPE (op0), op0, t);
	}

      GIMPLE_STMT_OPERAND (stmt, 1) = t;
      update_stmt (stmt);
    }
}

/* If the operand to an ABS_EXPR is >= 0, then eliminate the
   ABS_EXPR.  If the operand is <= 0, then simplify the
   ABS_EXPR into a NEGATE_EXPR.  */

static void
simplify_abs_using_ranges (tree stmt, tree rhs)
{
  tree val = NULL;
  tree op = TREE_OPERAND (rhs, 0);
  tree type = TREE_TYPE (op);
  value_range_t *vr = get_value_range (TREE_OPERAND (rhs, 0));

  if (TYPE_UNSIGNED (type))
    {
      val = integer_zero_node;
    }
  else if (vr)
    {
      bool sop = false;

      val = compare_range_with_value (LE_EXPR, vr, integer_zero_node, &sop);
      if (!val)
	{
	  sop = false;
	  val = compare_range_with_value (GE_EXPR, vr, integer_zero_node,
					  &sop);

	  if (val)
	    {
	      if (integer_zerop (val))
		val = integer_one_node;
	      else if (integer_onep (val))
		val = integer_zero_node;
	    }
	}

      if (val
	  && (integer_onep (val) || integer_zerop (val)))
	{
	  tree t;

	  if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
	    {
	      location_t locus;

	      if (!EXPR_HAS_LOCATION (stmt))
		locus = input_location;
	      else
		locus = EXPR_LOCATION (stmt);
	      warning (OPT_Wstrict_overflow,
		       ("%Hassuming signed overflow does not occur when "
			"simplifying abs (X) to X or -X"),
		       &locus);
	    }

	  if (integer_onep (val))
	    t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
	  else
	    t = op;

	  GIMPLE_STMT_OPERAND (stmt, 1) = t;
	  update_stmt (stmt);
	}
    }
}

/* We are comparing trees OP0 and OP1 using COND_CODE.  OP0 has
   a known value range VR.

   If there is one and only one value which will satisfy the
   conditional, then return that value.  Else return NULL.  */

static tree
test_for_singularity (enum tree_code cond_code, tree op0,
		      tree op1, value_range_t *vr)
{
  tree min = NULL;
  tree max = NULL;

  /* Extract minimum/maximum values which satisfy the
     the conditional as it was written.  */
  if (cond_code == LE_EXPR || cond_code == LT_EXPR)
    {
      /* This should not be negative infinity; there is no overflow
	 here.  */
      min = TYPE_MIN_VALUE (TREE_TYPE (op0));

      max = op1;
      if (cond_code == LT_EXPR && !is_overflow_infinity (max))
	{
	  tree one = build_int_cst (TREE_TYPE (op0), 1);
	  max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
	  if (EXPR_P (max))
	    TREE_NO_WARNING (max) = 1;
	}
    }
  else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
    {
      /* This should not be positive infinity; there is no overflow
	 here.  */
      max = TYPE_MAX_VALUE (TREE_TYPE (op0));

      min = op1;
      if (cond_code == GT_EXPR && !is_overflow_infinity (min))
	{
	  tree one = build_int_cst (TREE_TYPE (op0), 1);
	  min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
	  if (EXPR_P (min))
	    TREE_NO_WARNING (min) = 1;
	}
    }

  /* Now refine the minimum and maximum values using any
     value range information we have for op0.  */
  if (min && max)
    {
      if (compare_values (vr->min, min) == -1)
	min = min;
      else
	min = vr->min;
      if (compare_values (vr->max, max) == 1)
	max = max;
      else
	max = vr->max;

      /* If the new min/max values have converged to a single value,
	 then there is only one value which can satisfy the condition,
	 return that value.  */
      if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
	return min;
    }
  return NULL;
}

/* Simplify a conditional using a relational operator to an equality
   test if the range information indicates only one value can satisfy
   the original conditional.  */

static void
simplify_cond_using_ranges (tree stmt)
{
  tree cond = COND_EXPR_COND (stmt);
  tree op0 = TREE_OPERAND (cond, 0);
  tree op1 = TREE_OPERAND (cond, 1);
  enum tree_code cond_code = TREE_CODE (cond);

  if (cond_code != NE_EXPR
      && cond_code != EQ_EXPR
      && TREE_CODE (op0) == SSA_NAME
      && INTEGRAL_TYPE_P (TREE_TYPE (op0))
      && is_gimple_min_invariant (op1))
    {
      value_range_t *vr = get_value_range (op0);
	  
      /* If we have range information for OP0, then we might be
	 able to simplify this conditional. */
      if (vr->type == VR_RANGE)
	{
	  tree new = test_for_singularity (cond_code, op0, op1, vr);

	  if (new)
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "Simplified relational ");
		  print_generic_expr (dump_file, cond, 0);
		  fprintf (dump_file, " into ");
		}

	      COND_EXPR_COND (stmt)
		= build2 (EQ_EXPR, boolean_type_node, op0, new);
	      update_stmt (stmt);

	      if (dump_file)
		{
		  print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
		  fprintf (dump_file, "\n");
		}
	      return;

	    }

	  /* Try again after inverting the condition.  We only deal
	     with integral types here, so no need to worry about
	     issues with inverting FP comparisons.  */
	  cond_code = invert_tree_comparison (cond_code, false);
	  new = test_for_singularity (cond_code, op0, op1, vr);

	  if (new)
	    {
	      if (dump_file)
		{
		  fprintf (dump_file, "Simplified relational ");
		  print_generic_expr (dump_file, cond, 0);
		  fprintf (dump_file, " into ");
		}

	      COND_EXPR_COND (stmt)
		= build2 (NE_EXPR, boolean_type_node, op0, new);
	      update_stmt (stmt);

	      if (dump_file)
		{
		  print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
		  fprintf (dump_file, "\n");
		}
	      return;

	    }
	}
    }
}

/* Simplify STMT using ranges if possible.  */

void
simplify_stmt_using_ranges (tree stmt)
{
  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
    {
      tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
      enum tree_code rhs_code = TREE_CODE (rhs);

      /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
	 and BIT_AND_EXPR respectively if the first operand is greater
	 than zero and the second operand is an exact power of two.  */
      if ((rhs_code == TRUNC_DIV_EXPR || rhs_code == TRUNC_MOD_EXPR)
	  && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
	  && integer_pow2p (TREE_OPERAND (rhs, 1)))
	simplify_div_or_mod_using_ranges (stmt, rhs, rhs_code);

      /* Transform ABS (X) into X or -X as appropriate.  */
      if (rhs_code == ABS_EXPR
	  && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
	  && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
	simplify_abs_using_ranges (stmt, rhs);
    }
  else if (TREE_CODE (stmt) == COND_EXPR
	   && COMPARISON_CLASS_P (COND_EXPR_COND (stmt)))
    {
      simplify_cond_using_ranges (stmt);
    }
}

/* Stack of dest,src equivalency pairs that need to be restored after
   each attempt to thread a block's incoming edge to an outgoing edge. 

   A NULL entry is used to mark the end of pairs which need to be
   restored.  */
static VEC(tree,heap) *stack;

/* A trivial wrapper so that we can present the generic jump threading
   code with a simple API for simplifying statements.  STMT is the
   statement we want to simplify, WITHIN_STMT provides the location
   for any overflow warnings.  */

static tree
simplify_stmt_for_jump_threading (tree stmt, tree within_stmt)
{
  /* We only use VRP information to simplify conditionals.  This is
     overly conservative, but it's unclear if doing more would be
     worth the compile time cost.  */
  if (TREE_CODE (stmt) != COND_EXPR)
    return NULL;

  return vrp_evaluate_conditional (COND_EXPR_COND (stmt), within_stmt);
}

/* Blocks which have more than one predecessor and more than
   one successor present jump threading opportunities.  ie,
   when the block is reached from a specific predecessor, we
   may be able to determine which of the outgoing edges will
   be traversed.  When this optimization applies, we are able
   to avoid conditionals at runtime and we may expose secondary
   optimization opportunities.

   This routine is effectively a driver for the generic jump
   threading code.  It basically just presents the generic code
   with edges that may be suitable for jump threading.

   Unlike DOM, we do not iterate VRP if jump threading was successful.
   While iterating may expose new opportunities for VRP, it is expected
   those opportunities would be very limited and the compile time cost
   to expose those opportunities would be significant. 

   As jump threading opportunities are discovered, they are registered
   for later realization.  */

static void
identify_jump_threads (void)
{
  basic_block bb;
  tree dummy;

  /* Ugh.  When substituting values earlier in this pass we can
     wipe the dominance information.  So rebuild the dominator
     information as we need it within the jump threading code.  */
  calculate_dominance_info (CDI_DOMINATORS);

  /* We do not allow VRP information to be used for jump threading
     across a back edge in the CFG.  Otherwise it becomes too
     difficult to avoid eliminating loop exit tests.  Of course
     EDGE_DFS_BACK is not accurate at this time so we have to
     recompute it.  */
  mark_dfs_back_edges ();

  /* Allocate our unwinder stack to unwind any temporary equivalences
     that might be recorded.  */
  stack = VEC_alloc (tree, heap, 20);

  /* To avoid lots of silly node creation, we create a single
     conditional and just modify it in-place when attempting to
     thread jumps.  */
  dummy = build2 (EQ_EXPR, boolean_type_node, NULL, NULL);
  dummy = build3 (COND_EXPR, void_type_node, dummy, NULL, NULL);

  /* Walk through all the blocks finding those which present a
     potential jump threading opportunity.  We could set this up
     as a dominator walker and record data during the walk, but
     I doubt it's worth the effort for the classes of jump
     threading opportunities we are trying to identify at this
     point in compilation.  */
  FOR_EACH_BB (bb)
    {
      tree last, cond;

      /* If the generic jump threading code does not find this block
	 interesting, then there is nothing to do.  */
      if (! potentially_threadable_block (bb))
	continue;

      /* We only care about blocks ending in a COND_EXPR.  While there
	 may be some value in handling SWITCH_EXPR here, I doubt it's
	 terribly important.  */
      last = bsi_stmt (bsi_last (bb));
      if (TREE_CODE (last) != COND_EXPR)
	continue;

      /* We're basically looking for any kind of conditional with
	 integral type arguments.  */
      cond = COND_EXPR_COND (last);
      if ((TREE_CODE (cond) == SSA_NAME
	   && INTEGRAL_TYPE_P (TREE_TYPE (cond)))
	  || (COMPARISON_CLASS_P (cond)
	      && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
	      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 0)))
	      && (TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME
		  || is_gimple_min_invariant (TREE_OPERAND (cond, 1)))
	      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
	{
	  edge_iterator ei;
	  edge e;

	  /* We've got a block with multiple predecessors and multiple
	     successors which also ends in a suitable conditional.  For
	     each predecessor, see if we can thread it to a specific
	     successor.  */
	  FOR_EACH_EDGE (e, ei, bb->preds)
	    {
	      /* Do not thread across back edges or abnormal edges
		 in the CFG.  */
	      if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
		continue;

	      thread_across_edge (dummy, e, true,
				  &stack,
				  simplify_stmt_for_jump_threading);
	    }
	}
    }

  /* We do not actually update the CFG or SSA graphs at this point as
     ASSERT_EXPRs are still in the IL and cfg cleanup code does not yet
     handle ASSERT_EXPRs gracefully.  */
}

/* We identified all the jump threading opportunities earlier, but could
   not transform the CFG at that time.  This routine transforms the
   CFG and arranges for the dominator tree to be rebuilt if necessary.

   Note the SSA graph update will occur during the normal TODO
   processing by the pass manager.  */
static void
finalize_jump_threads (void)
{
  thread_through_all_blocks (false);
  VEC_free (tree, heap, stack);
}


/* Traverse all the blocks folding conditionals with known ranges.  */

static void
vrp_finalize (void)
{
  size_t i;
  prop_value_t *single_val_range;
  bool do_value_subst_p;

  if (dump_file)
    {
      fprintf (dump_file, "\nValue ranges after VRP:\n\n");
      dump_all_value_ranges (dump_file);
      fprintf (dump_file, "\n");
    }

  /* We may have ended with ranges that have exactly one value.  Those
     values can be substituted as any other copy/const propagated
     value using substitute_and_fold.  */
  single_val_range = XCNEWVEC (prop_value_t, num_ssa_names);

  do_value_subst_p = false;
  for (i = 0; i < num_ssa_names; i++)
    if (vr_value[i]
	&& vr_value[i]->type == VR_RANGE
	&& vr_value[i]->min == vr_value[i]->max)
      {
	single_val_range[i].value = vr_value[i]->min;
	do_value_subst_p = true;
      }

  if (!do_value_subst_p)
    {
      /* We found no single-valued ranges, don't waste time trying to
	 do single value substitution in substitute_and_fold.  */
      free (single_val_range);
      single_val_range = NULL;
    }

  substitute_and_fold (single_val_range, true);

  if (warn_array_bounds)
      check_all_array_refs ();

  /* We must identify jump threading opportunities before we release
     the datastructures built by VRP.  */
  identify_jump_threads ();

  /* Free allocated memory.  */
  for (i = 0; i < num_ssa_names; i++)
    if (vr_value[i])
      {
	BITMAP_FREE (vr_value[i]->equiv);
	free (vr_value[i]);
      }

  free (single_val_range);
  free (vr_value);
  free (vr_phi_edge_counts);

  /* So that we can distinguish between VRP data being available
     and not available.  */
  vr_value = NULL;
  vr_phi_edge_counts = NULL;
}

/* Calculates number of iterations for all loops, to ensure that they are
   cached.  */

static void
record_numbers_of_iterations (void)
{
  loop_iterator li;
  struct loop *loop;

  FOR_EACH_LOOP (li, loop, 0)
    {
      number_of_latch_executions (loop);
    }
}

/* Main entry point to VRP (Value Range Propagation).  This pass is
   loosely based on J. R. C. Patterson, ``Accurate Static Branch
   Prediction by Value Range Propagation,'' in SIGPLAN Conference on
   Programming Language Design and Implementation, pp. 67-78, 1995.
   Also available at http://citeseer.ist.psu.edu/patterson95accurate.html

   This is essentially an SSA-CCP pass modified to deal with ranges
   instead of constants.

   While propagating ranges, we may find that two or more SSA name
   have equivalent, though distinct ranges.  For instance,

     1	x_9 = p_3->a;
     2	p_4 = ASSERT_EXPR <p_3, p_3 != 0>
     3	if (p_4 == q_2)
     4	  p_5 = ASSERT_EXPR <p_4, p_4 == q_2>;
     5	endif
     6	if (q_2)
	
   In the code above, pointer p_5 has range [q_2, q_2], but from the
   code we can also determine that p_5 cannot be NULL and, if q_2 had
   a non-varying range, p_5's range should also be compatible with it.

   These equivalences are created by two expressions: ASSERT_EXPR and
   copy operations.  Since p_5 is an assertion on p_4, and p_4 was the
   result of another assertion, then we can use the fact that p_5 and
   p_4 are equivalent when evaluating p_5's range.

   Together with value ranges, we also propagate these equivalences
   between names so that we can take advantage of information from
   multiple ranges when doing final replacement.  Note that this
   equivalency relation is transitive but not symmetric.
   
   In the example above, p_5 is equivalent to p_4, q_2 and p_3, but we
   cannot assert that q_2 is equivalent to p_5 because q_2 may be used
   in contexts where that assertion does not hold (e.g., in line 6).

   TODO, the main difference between this pass and Patterson's is that
   we do not propagate edge probabilities.  We only compute whether
   edges can be taken or not.  That is, instead of having a spectrum
   of jump probabilities between 0 and 1, we only deal with 0, 1 and
   DON'T KNOW.  In the future, it may be worthwhile to propagate
   probabilities to aid branch prediction.  */

static unsigned int
execute_vrp (void)
{
  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
  scev_initialize ();

  insert_range_assertions ();

  /* Compute the # of iterations for each loop before we start the VRP
     analysis.  The value ranges determined by VRP are used in expression
     simplification, that is also used by the # of iterations analysis.
     However, in the middle of the VRP analysis, the value ranges do not take
     all the possible paths in CFG into account, so they do not have to be
     correct, and the # of iterations analysis can obtain wrong results.
     This is a problem, since the results of the # of iterations analysis
     are cached, so these mistakes would not be corrected when the value
     ranges are corrected.  */
  record_numbers_of_iterations ();

  vrp_initialize ();
  ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
  vrp_finalize ();

  /* ASSERT_EXPRs must be removed before finalizing jump threads
     as finalizing jump threads calls the CFG cleanup code which
     does not properly handle ASSERT_EXPRs.  */
  remove_range_assertions ();

  /* If we exposed any new variables, go ahead and put them into
     SSA form now, before we handle jump threading.  This simplifies
     interactions between rewriting of _DECL nodes into SSA form
     and rewriting SSA_NAME nodes into SSA form after block
     duplication and CFG manipulation.  */
  update_ssa (TODO_update_ssa);

  finalize_jump_threads ();
  scev_finalize ();
  loop_optimizer_finalize ();

  return 0;
}

static bool
gate_vrp (void)
{
  return flag_tree_vrp != 0;
}

struct tree_opt_pass pass_vrp =
{
  "vrp",				/* name */
  gate_vrp,				/* gate */
  execute_vrp,				/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  TV_TREE_VRP,				/* tv_id */
  PROP_ssa | PROP_alias,		/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_cleanup_cfg
    | TODO_ggc_collect
    | TODO_verify_ssa
    | TODO_dump_func
    | TODO_update_ssa,			/* todo_flags_finish */
  0					/* letter */
};
