public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [COMMITTED] Remove compare_names* from legacy cond folding.
@ 2023-04-26  8:33 Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Refactor vrp_evaluate_conditional* and rename it Aldy Hernandez
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

In a test run I have asserted that the legacy conditional folding only
gets overflows, so this removal is safe.

gcc/ChangeLog:

	* vr-values.cc (get_vr_for_comparison): Remove.
	(compare_name_with_value): Same.
	(vrp_evaluate_conditional_warnv_with_ops): Remove calls to
	compare_name_with_value.
	* vr-values.h: Remove compare_name_with_value.
	Remove get_vr_for_comparison.
---
 gcc/vr-values.cc | 57 ------------------------------------------------
 gcc/vr-values.h  |  2 --
 2 files changed, 59 deletions(-)

diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 365f4976a39..1d757eeffc3 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -615,58 +615,6 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
   return true;
 }
 
-/* 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.  Uses TEM as storage for the alternate range.  */
-
-const value_range *
-simplify_using_ranges::get_vr_for_comparison (int i, value_range *tem,
-					      gimple *s)
-{
-  /* Shallow-copy equiv bitmap.  */
-  const value_range *vr = query->get_value_range (ssa_name (i), s);
-
-  /* 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->varying_p () || vr->undefined_p ())
-    {
-      tree ssa = ssa_name (i);
-      tem->set (ssa, ssa);
-      return tem;
-    }
-
-  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.  */
-
-tree
-simplify_using_ranges::compare_name_with_value
-				(enum tree_code comp, tree var, tree val,
-				 bool *strict_overflow_p, gimple *s)
-{
-  /* Start at -1.  Set it to 0 if we do a comparison without relying
-     on overflow, or 1 if all comparisons rely on overflow.  */
-  int used_strict_overflow = -1;
-
-  /* Compare vars' value range with val.  */
-  value_range tem_vr;
-  const value_range *equiv_vr
-    = get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr, s);
-  bool sop = false;
-  tree retval = compare_range_with_value (comp, equiv_vr, val, &sop);
-  if (retval)
-    used_strict_overflow = sop ? 1 : 0;
-
-  if (retval && used_strict_overflow > 0)
-    *strict_overflow_p = true;
-  return retval;
-}
-
 /* Helper function for vrp_evaluate_conditional_warnv & other
    optimizers.  */
 
@@ -780,11 +728,6 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
     return ret;
   if (only_ranges)
     *only_ranges = false;
-  if (TREE_CODE (op0) == SSA_NAME)
-    return compare_name_with_value (code, op0, op1, strict_overflow_p, stmt);
-  else if (TREE_CODE (op1) == SSA_NAME)
-    return compare_name_with_value (swap_tree_comparison (code), op1, op0,
-				    strict_overflow_p, stmt);
   return NULL_TREE;
 }
 
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 00fcf7702aa..a89902c9c51 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -52,8 +52,6 @@ private:
 
   bool two_valued_val_range_p (tree, tree *, tree *, gimple *);
   bool op_with_boolean_value_range_p (tree, gimple *);
-  tree compare_name_with_value (enum tree_code, tree, tree, bool *, gimple *);
-  const value_range *get_vr_for_comparison (int, value_range *, gimple *s);
   tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
 							     tree, tree,
 							     bool *, gimple *s);
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Refactor vrp_evaluate_conditional* and rename it.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Remove range_query::get_value_range Aldy Hernandez
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

gcc/ChangeLog:

	* vr-values.cc
	(simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops):
	Rename to...
	(simplify_using_ranges::legacy_fold_cond_overflow): ...this.
	(simplify_using_ranges::vrp_visit_cond_stmt): Rename to...
	(simplify_using_ranges::legacy_fold_cond): ...this.
	(simplify_using_ranges::fold_cond): Rename
	vrp_evaluate_conditional_warnv_with_ops to
	legacy_fold_cond_overflow.
	* vr-values.h (class vr_values): Replace vrp_visit_cond_stmt and
	vrp_evaluate_conditional_warnv_with_ops with legacy_fold_cond and
	legacy_fold_cond_overflow respectively.
---
 gcc/vr-values.cc | 25 +++++++++++--------------
 gcc/vr-values.h  |  5 ++---
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 1d757eeffc3..e8643ea321e 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -638,20 +638,21 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops_using_ranges
   return res;
 }
 
-/* Helper function for vrp_evaluate_conditional_warnv. */
+/* Helper function for legacy_fold_cond.  */
 
 tree
-simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
-						(gimple *stmt,
-						 enum tree_code code,
-						 tree op0, tree op1,
-						 bool *strict_overflow_p,
-						 bool *only_ranges)
+simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt,
+						  bool *strict_overflow_p,
+						  bool *only_ranges)
 {
   tree ret;
   if (only_ranges)
     *only_ranges = true;
 
+  tree_code code = gimple_cond_code (stmt);
+  tree op0 = gimple_cond_lhs (stmt);
+  tree op1 = gimple_cond_rhs (stmt);
+
   /* We only deal with integral and pointer types.  */
   if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
       && !POINTER_TYPE_P (TREE_TYPE (op0)))
@@ -736,7 +737,7 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops
    *TAKEN_EDGE_P.  Otherwise, set *TAKEN_EDGE_P to NULL.  */
 
 void
-simplify_using_ranges::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
+simplify_using_ranges::legacy_fold_cond (gcond *stmt, edge *taken_edge_p)
 {
   tree val;
 
@@ -765,11 +766,7 @@ simplify_using_ranges::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
     }
 
   bool sop;
-  val = vrp_evaluate_conditional_warnv_with_ops (stmt,
-						 gimple_cond_code (stmt),
-						 gimple_cond_lhs (stmt),
-						 gimple_cond_rhs (stmt),
-						 &sop, NULL);
+  val = legacy_fold_cond_overflow (stmt, &sop, NULL);
   if (val)
     *taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
 
@@ -1471,7 +1468,7 @@ simplify_using_ranges::fold_cond (gcond *cond)
 
   // FIXME: Audit the code below and make sure it never finds anything.
   edge taken_edge;
-  vrp_visit_cond_stmt (cond, &taken_edge);
+  legacy_fold_cond (cond, &taken_edge);
 
   if (taken_edge)
     {
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index a89902c9c51..ff814155881 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -35,9 +35,8 @@ public:
   bool simplify (gimple_stmt_iterator *);
   bool fold_cond (gcond *);
 private:
-  void vrp_visit_cond_stmt (gcond *, edge *);
-  tree vrp_evaluate_conditional_warnv_with_ops (gimple *stmt, enum tree_code,
-						tree, tree, bool *, bool *);
+  void legacy_fold_cond (gcond *, edge *);
+  tree legacy_fold_cond_overflow (gimple *stmt, bool *, bool *);
   bool simplify_casted_cond (gcond *);
   bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Remove range_query::get_value_range.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Refactor vrp_evaluate_conditional* and rename it Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Remove deprecated range_fold_{unary,binary}_expr uses from ipa-* Aldy Hernandez
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

gcc/ChangeLog:

	* gimple-array-bounds.cc (array_bounds_checker::get_value_range):
	Add irange argument.
	(check_out_of_bounds_and_warn): Remove check for vr.
	(array_bounds_checker::check_array_ref): Remove pointer qualifier
	for vr and adjust accordingly.
	* gimple-array-bounds.h (get_value_range): Add irange argument.
	* value-query.cc (class equiv_allocator): Delete.
	(range_query::get_value_range): Delete.
	(range_query::range_query): Remove allocator access.
	(range_query::~range_query): Same.
	* value-query.h (get_value_range): Delete.
	* vr-values.cc
	(simplify_using_ranges::op_with_boolean_value_range_p): Remove
	call to get_value_range.
	(check_for_binary_op_overflow): Same.
	(simplify_using_ranges::legacy_fold_cond_overflow): Same.
	(simplify_using_ranges::simplify_abs_using_ranges): Same.
	(simplify_using_ranges::simplify_cond_using_ranges_1): Same.
	(simplify_using_ranges::simplify_casted_cond): Same.
	(simplify_using_ranges::simplify_switch_using_ranges): Same.
	(simplify_using_ranges::two_valued_val_range_p): Same.
---
 gcc/gimple-array-bounds.cc |  22 +++---
 gcc/gimple-array-bounds.h  |   2 +-
 gcc/value-query.cc         |  21 ------
 gcc/value-query.h          |   6 --
 gcc/vr-values.cc           | 144 ++++++++++++++++++++++---------------
 5 files changed, 99 insertions(+), 96 deletions(-)

diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index 34e039adca7..775f0c13258 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -46,10 +46,12 @@ array_bounds_checker::array_bounds_checker (struct function *func,
   /* No-op.  */
 }
 
-const value_range *
-array_bounds_checker::get_value_range (const_tree op, gimple *stmt)
+void
+array_bounds_checker::get_value_range (irange &r, const_tree op, gimple *stmt)
 {
-  return m_ptr_qry.rvals->get_value_range (op, stmt);
+  if (m_ptr_qry.rvals->range_of_expr (r, const_cast<tree> (op), stmt))
+    return;
+  r.set_varying (TREE_TYPE (op));
 }
 
 /* Try to determine the DECL that REF refers to.  Return the DECL or
@@ -282,7 +284,7 @@ check_out_of_bounds_and_warn (location_t location, tree ref,
 
   if (warned)
     ; /* Do nothing.  */
-  else if (vr && vr->kind () == VR_ANTI_RANGE)
+  else if (vr->kind () == VR_ANTI_RANGE)
     {
       if (up_bound
 	  && TREE_CODE (up_sub) == INTEGER_CST
@@ -370,20 +372,20 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
   tree up_sub = low_sub_org;
   tree low_sub = low_sub_org;
 
-  const value_range *vr = NULL;
+  value_range vr;
   if (TREE_CODE (low_sub_org) == SSA_NAME)
     {
-      vr = get_value_range (low_sub_org, stmt);
-      if (!vr->undefined_p () && !vr->varying_p ())
+      get_value_range (vr, low_sub_org, stmt);
+      if (!vr.undefined_p () && !vr.varying_p ())
 	{
-	  low_sub = vr->kind () == VR_RANGE ? vr->max () : vr->min ();
-	  up_sub = vr->kind () == VR_RANGE ? vr->min () : vr->max ();
+	  low_sub = vr.kind () == VR_RANGE ? vr.max () : vr.min ();
+	  up_sub = vr.kind () == VR_RANGE ? vr.min () : vr.max ();
 	}
     }
 
   warned = check_out_of_bounds_and_warn (location, ref,
 					 low_sub_org, low_sub, up_sub,
-					 up_bound, up_bound_p1, vr,
+					 up_bound, up_bound_p1, &vr,
 					 ignore_off_by_one, warn_array_bounds,
 					 &out_of_bound);
 
diff --git a/gcc/gimple-array-bounds.h b/gcc/gimple-array-bounds.h
index 13e5f29dabf..5a0d3103edf 100644
--- a/gcc/gimple-array-bounds.h
+++ b/gcc/gimple-array-bounds.h
@@ -35,7 +35,7 @@ private:
   bool check_array_ref (location_t, tree, gimple *, bool ignore_off_by_one);
   bool check_mem_ref (location_t, tree, bool ignore_off_by_one);
   void check_addr_expr (location_t, tree, gimple *);
-  const value_range *get_value_range (const_tree op, gimple *);
+  void get_value_range (irange &r, const_tree op, gimple *);
 
   /* Current function.  */
   struct function *fun;
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 50128502102..538cfad19b1 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -142,34 +142,13 @@ range_query::dump (FILE *)
 {
 }
 
-// valuation_query support routines for value_range's.
-
-class equiv_allocator : public object_allocator<value_range>
-{
-public:
-  equiv_allocator ()
-    : object_allocator<value_range> ("equiv_allocator pool") { }
-};
-
-const value_range *
-range_query::get_value_range (const_tree expr, gimple *stmt)
-{
-  int_range_max r;
-  if (range_of_expr (r, const_cast<tree> (expr), stmt))
-    return new (equiv_alloc->allocate ()) value_range (r);
-  return new (equiv_alloc->allocate ()) value_range (TREE_TYPE (expr));
-}
-
 range_query::range_query ()
 {
-  equiv_alloc = new equiv_allocator;
   m_oracle = NULL;
 }
 
 range_query::~range_query ()
 {
-  equiv_alloc->release ();
-  delete equiv_alloc;
 }
 
 // Return a range in R for the tree EXPR.  Return true if a range is
diff --git a/gcc/value-query.h b/gcc/value-query.h
index 20a37118ce2..d10c3eac1e2 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -104,18 +104,12 @@ public:
   // If present, Access relation oracle for more advanced uses.
   inline relation_oracle *oracle () const  { return m_oracle; }
 
-  // DEPRECATED: This method is used from vr-values.  The plan is to
-  // rewrite all uses of it to the above API.
-  virtual const value_range *get_value_range (const_tree, gimple * = NULL);
   virtual void dump (FILE *);
 
 protected:
   bool get_tree_range (vrange &v, tree expr, gimple *stmt);
   bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt);
   relation_oracle *m_oracle;
-
-private:
-  class equiv_allocator *equiv_alloc;
 };
 
 // Global ranges for SSA names using SSA_NAME_RANGE_INFO.
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index e8643ea321e..41e12daf7f8 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -86,9 +86,10 @@ simplify_using_ranges::op_with_boolean_value_range_p (tree op, gimple *s)
 
   /* ?? Errr, this should probably check for [0,0] and [1,1] as well
      as [0,1].  */
-  const value_range *vr = query->get_value_range (op, s);
-  return *vr == value_range (build_zero_cst (TREE_TYPE (op)),
-			     build_one_cst (TREE_TYPE (op)));
+  value_range vr;
+  return (query->range_of_expr (vr, op, s)
+	  && vr == value_range (build_zero_cst (TREE_TYPE (op)),
+				build_one_cst (TREE_TYPE (op))));
 }
 
 /* Helper function for simplify_internal_call_using_ranges and
@@ -104,14 +105,20 @@ check_for_binary_op_overflow (range_query *query,
 {
   value_range vr0, vr1;
   if (TREE_CODE (op0) == SSA_NAME)
-    vr0 = *query->get_value_range (op0, s);
+    {
+      if (!query->range_of_expr (vr0, op0, s))
+	vr0.set_varying (TREE_TYPE (op0));
+    }
   else if (TREE_CODE (op0) == INTEGER_CST)
     vr0.set (op0, op0);
   else
     vr0.set_varying (TREE_TYPE (op0));
 
   if (TREE_CODE (op1) == SSA_NAME)
-    vr1 = *query->get_value_range (op1, s);
+    {
+      if (!query->range_of_expr (vr1, op1, s))
+	vr1.set_varying (TREE_TYPE (op1));
+    }
   else if (TREE_CODE (op1) == INTEGER_CST)
     vr1.set (op1, op1);
   else
@@ -623,18 +630,22 @@ simplify_using_ranges::vrp_evaluate_conditional_warnv_with_ops_using_ranges
     (enum tree_code code, tree op0, tree op1, bool * strict_overflow_p,
      gimple *s)
 {
-  const value_range *vr0, *vr1;
-  vr0 = (TREE_CODE (op0) == SSA_NAME) ? query->get_value_range (op0, s) : NULL;
-  vr1 = (TREE_CODE (op1) == SSA_NAME) ? query->get_value_range (op1, s) : NULL;
+  bool ssa0 = TREE_CODE (op0) == SSA_NAME;
+  bool ssa1 = TREE_CODE (op1) == SSA_NAME;
+  value_range vr0, vr1;
+  if (ssa0 && !query->range_of_expr (vr0, op0, s))
+    vr0.set_varying (TREE_TYPE (op0));
+  if (ssa1 && !query->range_of_expr (vr1, op1, s))
+    vr1.set_varying (TREE_TYPE (op1));
 
   tree res = NULL_TREE;
-  if (vr0 && vr1)
-    res = compare_ranges (code, vr0, vr1, strict_overflow_p);
-  if (!res && vr0)
-    res = compare_range_with_value (code, vr0, op1, strict_overflow_p);
-  if (!res && vr1)
+  if (ssa0 && ssa1)
+    res = compare_ranges (code, &vr0, &vr1, strict_overflow_p);
+  if (!res && ssa0)
+    res = compare_range_with_value (code, &vr0, op1, strict_overflow_p);
+  if (!res && ssa1)
     res = (compare_range_with_value
-	    (swap_tree_comparison (code), vr1, op0, strict_overflow_p));
+	    (swap_tree_comparison (code), &vr1, op0, strict_overflow_p));
   return res;
 }
 
@@ -704,7 +715,9 @@ simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt,
 	    }
 	  else
 	    gcc_unreachable ();
-	  const value_range *vr0 = query->get_value_range (op0, stmt);
+	  value_range vr0;
+	  if (!query->range_of_expr (vr0, op0, stmt))
+	    vr0.set_varying (TREE_TYPE (op0));
 	  /* If vro, the range for OP0 to pass the overflow test, has
 	     no intersection with *vr0, OP0's known range, then the
 	     overflow test can't pass, so return the node for false.
@@ -715,10 +728,10 @@ simplify_using_ranges::legacy_fold_cond_overflow (gimple *stmt,
 	     for previously LE_ or LT_EXPR and GT_EXPR otherwise, but
 	     the comments next to the enclosing if suggest it's not
 	     generally profitable to do so.  */
-	  vro.legacy_verbose_intersect (vr0);
+	  vro.legacy_verbose_intersect (&vr0);
 	  if (vro.undefined_p ())
 	    return boolean_false_node;
-	  vri.legacy_verbose_intersect (vr0);
+	  vri.legacy_verbose_intersect (&vr0);
 	  if (vri.undefined_p ())
 	    return boolean_true_node;
 	}
@@ -952,7 +965,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
   tree op1 = gimple_assign_rhs2 (stmt);
   tree op0min = NULL_TREE, op0max = NULL_TREE;
   tree op1min = op1;
-  const value_range *vr = NULL;
+  value_range vr;
 
   if (TREE_CODE (op0) == INTEGER_CST)
     {
@@ -961,20 +974,23 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
     }
   else
     {
-      vr = query->get_value_range (op0, stmt);
-      if (range_int_cst_p (vr))
+      if (!query->range_of_expr (vr, op0, stmt))
+	vr.set_varying (TREE_TYPE (op0));
+      if (range_int_cst_p (&vr))
 	{
-	  op0min = vr->min ();
-	  op0max = vr->max ();
+	  op0min = vr.min ();
+	  op0max = vr.max ();
 	}
     }
 
   if (rhs_code == TRUNC_MOD_EXPR
       && TREE_CODE (op1) == SSA_NAME)
     {
-      const value_range *vr1 = query->get_value_range (op1, stmt);
-      if (range_int_cst_p (vr1))
-	op1min = vr1->min ();
+      value_range vr1;
+      if (!query->range_of_expr (vr1, op1, stmt))
+	vr1.set_varying (TREE_TYPE (op1));
+      if (range_int_cst_p (&vr1))
+	op1min = vr1.min ();
     }
   if (rhs_code == TRUNC_MOD_EXPR
       && TREE_CODE (op1min) == INTEGER_CST
@@ -1015,7 +1031,7 @@ simplify_using_ranges::simplify_div_or_mod_using_ranges
     {
       bool sop = false;
 
-      val = compare_range_with_value (GE_EXPR, vr, integer_zero_node, &sop);
+      val = compare_range_with_value (GE_EXPR, &vr, integer_zero_node, &sop);
 
       if (val
 	  && sop
@@ -1121,20 +1137,23 @@ simplify_using_ranges::simplify_abs_using_ranges (gimple_stmt_iterator *gsi,
 						  gimple *stmt)
 {
   tree op = gimple_assign_rhs1 (stmt);
-  const value_range *vr = query->get_value_range (op, stmt);
+  value_range vr;
+
+  if (!query->range_of_expr (vr, op, stmt))
+    vr.set_undefined ();
 
-  if (vr)
+  if (!vr.undefined_p () && !vr.varying_p ())
     {
       tree val = NULL;
       bool sop = false;
 
-      val = compare_range_with_value (LE_EXPR, vr, integer_zero_node, &sop);
+      val = compare_range_with_value (LE_EXPR, &vr, integer_zero_node, &sop);
       if (!val)
 	{
 	  /* The range is neither <= 0 nor > 0.  Now see if it is
 	     either < 0 or >= 0.  */
 	  sop = false;
-	  val = compare_range_with_value (LT_EXPR, vr, integer_zero_node,
+	  val = compare_range_with_value (LT_EXPR, &vr, integer_zero_node,
 					  &sop);
 	}
 
@@ -1211,14 +1230,20 @@ simplify_using_ranges::simplify_bit_ops_using_ranges
   wide_int mask;
 
   if (TREE_CODE (op0) == SSA_NAME)
-    vr0 = *(query->get_value_range (op0, stmt));
+    {
+      if (!query->range_of_expr (vr0, op0, stmt))
+	vr0.set_varying (TREE_TYPE (op0));
+    }
   else if (is_gimple_min_invariant (op0))
     vr0.set (op0, op0);
   else
     return false;
 
   if (TREE_CODE (op1) == SSA_NAME)
-    vr1 = *(query->get_value_range (op1, stmt));
+    {
+      if (!query->range_of_expr (vr1, op1, stmt))
+	vr1.set_varying (TREE_TYPE (op1));
+    }
   else if (is_gimple_min_invariant (op1))
     vr1.set (op1, op1);
   else
@@ -1512,13 +1537,16 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
       && INTEGRAL_TYPE_P (TREE_TYPE (op0))
       && is_gimple_min_invariant (op1))
     {
-      const value_range *vr = query->get_value_range (op0, stmt);
+      value_range vr;
+
+      if (!query->range_of_expr (vr, op0, stmt))
+	vr.set_undefined ();
 
       /* If we have range information for OP0, then we might be
 	 able to simplify this conditional. */
-      if (!vr->undefined_p () && !vr->varying_p ())
+      if (!vr.undefined_p () && !vr.varying_p ())
 	{
-	  tree new_tree = test_for_singularity (cond_code, op0, op1, vr);
+	  tree new_tree = test_for_singularity (cond_code, op0, op1, &vr);
 	  if (new_tree)
 	    {
 	      if (dump_file)
@@ -1548,7 +1576,7 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
 	     issues with inverting FP comparisons.  */
 	  new_tree = test_for_singularity
 		       (invert_tree_comparison (cond_code, false),
-			op0, op1, vr);
+			op0, op1, &vr);
 	  if (new_tree)
 	    {
 	      if (dump_file)
@@ -1627,10 +1655,11 @@ simplify_using_ranges::simplify_casted_cond (gcond *stmt)
 	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
 	  && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
 	{
-	  const value_range *vr = query->get_value_range (innerop);
+	  value_range vr;
 
-	  if (range_int_cst_p (vr)
-	      && range_fits_type_p (vr,
+	  if (query->range_of_expr (vr, innerop)
+	      && range_int_cst_p (&vr)
+	      && range_fits_type_p (&vr,
 				    TYPE_PRECISION (TREE_TYPE (op0)),
 				    TYPE_SIGN (TREE_TYPE (op0)))
 	      && int_fits_type_p (op1, TREE_TYPE (innerop)))
@@ -1653,7 +1682,7 @@ bool
 simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
 {
   tree op = gimple_switch_index (stmt);
-  const value_range *vr = NULL;
+  value_range vr;
   bool take_default;
   edge e;
   edge_iterator ei;
@@ -1664,16 +1693,12 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
 
   if (TREE_CODE (op) == SSA_NAME)
     {
-      vr = query->get_value_range (op, stmt);
-
-      /* We can only handle integer ranges.  */
-      if (vr->varying_p ()
-	  || vr->undefined_p ()
-	  || vr->symbolic_p ())
+      if (!query->range_of_expr (vr, op, stmt)
+	  || vr.varying_p () || vr.undefined_p ())
 	return false;
 
       /* Find case label for min/max of the value range.  */
-      take_default = !find_case_label_ranges (stmt, vr, &i, &j, &k, &l);
+      take_default = !find_case_label_ranges (stmt, &vr, &i, &j, &k, &l);
     }
   else if (TREE_CODE (op) == INTEGER_CST)
     {
@@ -1696,8 +1721,8 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
   /* We can truncate the case label ranges that partially overlap with OP's
      value range.  */
   size_t min_idx = 1, max_idx = 0;
-  if (vr != NULL)
-    find_case_label_range (stmt, vr->min (), vr->max (), &min_idx, &max_idx);
+  if (!vr.undefined_p ())
+    find_case_label_range (stmt, vr.min (), vr.max (), &min_idx, &max_idx);
   if (min_idx <= max_idx)
     {
       tree min_label = gimple_switch_label (stmt, min_idx);
@@ -1705,10 +1730,10 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
 
       /* Avoid changing the type of the case labels when truncating.  */
       tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
-      tree vr_min = fold_convert (case_label_type, vr->min ());
-      tree vr_max = fold_convert (case_label_type, vr->max ());
+      tree vr_min = fold_convert (case_label_type, vr.min ());
+      tree vr_max = fold_convert (case_label_type, vr.max ());
 
-      if (vr->kind () == VR_RANGE)
+      if (vr.kind () == VR_RANGE)
 	{
 	  /* If OP's value range is [2,8] and the low label range is
 	     0 ... 3, truncate the label's range to 2 .. 3.  */
@@ -1724,7 +1749,7 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
 	      && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
 	    CASE_HIGH (max_label) = vr_max;
 	}
-      else if (vr->kind () == VR_ANTI_RANGE)
+      else if (vr.kind () == VR_ANTI_RANGE)
 	{
 	  tree one_cst = build_one_cst (case_label_type);
 
@@ -1964,7 +1989,7 @@ simplify_using_ranges::simplify_float_conversion_using_ranges
 					 gimple *stmt)
 {
   tree rhs1 = gimple_assign_rhs1 (stmt);
-  const value_range *vr = query->get_value_range (rhs1, stmt);
+  value_range vr;
   scalar_float_mode fltmode
     = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
   scalar_int_mode mode;
@@ -1972,14 +1997,15 @@ simplify_using_ranges::simplify_float_conversion_using_ranges
   gassign *conv;
 
   /* We can only handle constant ranges.  */
-  if (!range_int_cst_p (vr))
+  if (!query->range_of_expr (vr, rhs1, stmt)
+      || !range_int_cst_p (&vr))
     return false;
 
   /* First check if we can use a signed type in place of an unsigned.  */
   scalar_int_mode rhs_mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (rhs1));
   if (TYPE_UNSIGNED (TREE_TYPE (rhs1))
       && can_float_p (fltmode, rhs_mode, 0) != CODE_FOR_nothing
-      && range_fits_type_p (vr, TYPE_PRECISION (TREE_TYPE (rhs1)), SIGNED))
+      && range_fits_type_p (&vr, TYPE_PRECISION (TREE_TYPE (rhs1)), SIGNED))
     mode = rhs_mode;
   /* If we can do the conversion in the current input mode do nothing.  */
   else if (can_float_p (fltmode, rhs_mode,
@@ -1996,7 +2022,7 @@ simplify_using_ranges::simplify_float_conversion_using_ranges
 	     or if the value-range does not fit in the signed type
 	     try with a wider mode.  */
 	  if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing
-	      && range_fits_type_p (vr, GET_MODE_PRECISION (mode), SIGNED))
+	      && range_fits_type_p (&vr, GET_MODE_PRECISION (mode), SIGNED))
 	    break;
 
 	  /* But do not widen the input.  Instead leave that to the
@@ -2129,7 +2155,9 @@ bool
 simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b,
 					       gimple *s)
 {
-  value_range vr = *query->get_value_range (var, s);
+  value_range vr;
+  if (!query->range_of_expr (vr, var, s))
+    return false;
   vr.normalize_symbolics ();
   if (vr.varying_p () || vr.undefined_p ())
     return false;
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Remove deprecated range_fold_{unary,binary}_expr uses from ipa-*.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Refactor vrp_evaluate_conditional* and rename it Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Remove range_query::get_value_range Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  2023-05-05 15:10   ` [COMMITTED] Remove deprecated range_fold_{unary, binary}_expr " Martin Jambor
  2023-04-26  8:33 ` [COMMITTED] Remove range_fold_{unary,binary}_expr Aldy Hernandez
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

gcc/ChangeLog:

	* ipa-cp.cc (ipa_vr_operation_and_type_effects): Convert to ranger API.
	(ipa_value_range_from_jfunc): Same.
	(propagate_vr_across_jump_function): Same.
	* ipa-fnsummary.cc (evaluate_conditions_for_known_args): Same.
	* ipa-prop.cc (ipa_compute_jump_functions_for_edge): Same.
	* vr-values.cc (bounds_of_var_in_loop): Same.
---
 gcc/ipa-cp.cc        | 28 +++++++++++++++++++++------
 gcc/ipa-fnsummary.cc | 45 ++++++++++++++++++++++++++++----------------
 gcc/ipa-prop.cc      |  5 ++---
 gcc/vr-values.cc     |  6 ++++--
 4 files changed, 57 insertions(+), 27 deletions(-)

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 65c49558b58..6788883c40b 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -128,6 +128,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "dbgcnt.h"
 #include "symtab-clones.h"
+#include "gimple-range.h"
 
 template <typename valtype> class ipcp_value;
 
@@ -1900,10 +1901,15 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr,
 				   enum tree_code operation,
 				   tree dst_type, tree src_type)
 {
-  range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
-  if (dst_vr->varying_p () || dst_vr->undefined_p ())
+  if (!irange::supports_p (dst_type) || !irange::supports_p (src_type))
     return false;
-  return true;
+
+  range_op_handler handler (operation, dst_type);
+  return (handler
+	  && handler.fold_range (*dst_vr, dst_type,
+				 *src_vr, value_range (dst_type))
+	  && !dst_vr->varying_p ()
+	  && !dst_vr->undefined_p ());
 }
 
 /* Determine value_range of JFUNC given that INFO describes the caller node or
@@ -1958,8 +1964,13 @@ ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
 	  value_range op_res, res;
 	  tree op = ipa_get_jf_pass_through_operand (jfunc);
 	  value_range op_vr (op, op);
+	  range_op_handler handler (operation, vr_type);
+
+	  if (!handler
+	      || !op_res.supports_type_p (vr_type)
+	      || !handler.fold_range (op_res, vr_type, srcvr, op_vr))
+	    op_res.set_varying (vr_type);
 
-	  range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
 	  if (ipa_vr_operation_and_type_effects (&res,
 						 &op_res,
 						 NOP_EXPR, parm_type,
@@ -2748,9 +2759,14 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
 	  tree op = ipa_get_jf_pass_through_operand (jfunc);
 	  value_range op_vr (op, op);
 	  value_range op_res,res;
+	  range_op_handler handler (operation, operand_type);
+
+	  if (!handler
+	      || !op_res.supports_type_p (operand_type)
+	      || !handler.fold_range (op_res, operand_type,
+				      src_lats->m_value_range.m_vr, op_vr))
+	    op_res.set_varying (operand_type);
 
-	  range_fold_binary_expr (&op_res, operation, operand_type,
-				  &src_lats->m_value_range.m_vr, &op_vr);
 	  ipa_vr_operation_and_type_effects (&vr,
 					     &op_res,
 					     NOP_EXPR, param_type,
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index d4b2a073240..03142960e60 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -481,13 +481,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
 	      && (TYPE_SIZE (c->type) == TYPE_SIZE (vr.type ())))
 	    {
 	      if (!useless_type_conversion_p (c->type, vr.type ()))
-		{
-		  value_range res;
-		  range_fold_unary_expr (&res, NOP_EXPR,
-				     c->type, &vr, vr.type ());
-		  vr = res;
-		}
-	      tree type = c->type;
+		range_cast (vr, c->type);
 
 	      for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
 		{
@@ -496,26 +490,45 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
 
 		  value_range res;
 		  if (!op->val[0])
-		    range_fold_unary_expr (&res, op->code, op->type, &vr, type);
+		    {
+		      range_op_handler handler (op->code, op->type);
+		      if (!handler
+			  || !res.supports_type_p (op->type)
+			  || !handler.fold_range (res, op->type, vr,
+						  value_range (op->type)))
+			res.set_varying (op->type);
+		    }
 		  else if (!op->val[1])
 		    {
 		      value_range op0 (op->val[0], op->val[0]);
-		      range_fold_binary_expr (&res, op->code, op->type,
-					      op->index ? &op0 : &vr,
-					      op->index ? &vr : &op0);
+		      range_op_handler handler (op->code, op->type);
+
+		      if (!handler
+			  || !res.supports_type_p (op->type)
+			  || !handler.fold_range (res, op->type,
+						  op->index ? op0 : vr,
+						  op->index ? vr : op0))
+			res.set_varying (op->type);
 		    }
 		  else
 		    res.set_varying (op->type);
-		  type = op->type;
 		  vr = res;
 		}
 	      if (!vr.varying_p () && !vr.undefined_p ())
 		{
 		  value_range res;
-		  value_range val_vr (c->val, c->val);
-		  range_fold_binary_expr (&res, c->code, boolean_type_node,
-					  &vr,
-					  &val_vr);
+		  value_range val_vr;
+		  if (TREE_CODE (c->val) == INTEGER_CST)
+		    val_vr.set (c->val, c->val);
+		  else
+		    val_vr.set_varying (TREE_TYPE (c->val));
+		  range_op_handler handler (c->code, boolean_type_node);
+
+		  if (!handler
+		      || !res.supports_type_p (boolean_type_node)
+		      || !handler.fold_range (res, boolean_type_node, vr, val_vr))
+		    res.set_varying (boolean_type_node);
+
 		  if (res.zero_p ())
 		    continue;
 		}
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index a55cc72b0fd..f706f099f7a 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -2323,9 +2323,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	      && get_range_query (cfun)->range_of_expr (vr, arg)
 	      && !vr.undefined_p ())
 	    {
-	      value_range resvr;
-	      range_fold_unary_expr (&resvr, NOP_EXPR, param_type,
-				     &vr, TREE_TYPE (arg));
+	      value_range resvr = vr;
+	      range_cast (resvr, param_type);
 	      if (!resvr.undefined_p () && !resvr.varying_p ())
 		ipa_set_jfunc_vr (jfunc, &resvr);
 	      else
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 41e12daf7f8..ea4fbd7af67 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -579,8 +579,10 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
 		vr0.set_varying (TREE_TYPE (init));
 	      tree tem = wide_int_to_tree (TREE_TYPE (init), wtmp);
 	      vr1.set (tem, tem);
-	      range_fold_binary_expr (&maxvr, PLUS_EXPR,
-				      TREE_TYPE (init), &vr0, &vr1);
+
+	      range_op_handler handler (PLUS_EXPR, TREE_TYPE (init));
+	      if (!handler.fold_range (maxvr, TREE_TYPE (init), vr0, vr1))
+		maxvr.set_varying (TREE_TYPE (init));
 
 	      /* Likewise if the addition did.  */
 	      if (maxvr.kind () == VR_RANGE)
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Remove range_fold_{unary,binary}_expr.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
                   ` (2 preceding siblings ...)
  2023-04-26  8:33 ` [COMMITTED] Remove deprecated range_fold_{unary,binary}_expr uses from ipa-* Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Remove irange::may_contain_p Aldy Hernandez
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

gcc/ChangeLog:

	* tree-vrp.cc (supported_types_p): Remove.
	(defined_ranges_p): Remove.
	(range_fold_binary_expr): Remove.
	(range_fold_unary_expr): Remove.
	* tree-vrp.h (range_fold_unary_expr): Remove.
	(range_fold_binary_expr): Remove.
---
 gcc/tree-vrp.cc | 86 -------------------------------------------------
 gcc/tree-vrp.h  |  5 ---
 2 files changed, 91 deletions(-)

diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 9b870640e23..27126088708 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -587,92 +587,6 @@ compare_values (tree val1, tree val2)
   return compare_values_warnv (val1, val2, &sop);
 }
 
-/* If the types passed are supported, return TRUE, otherwise set VR to
-   VARYING and return FALSE.  */
-
-static bool
-supported_types_p (value_range *vr,
-		   tree type0,
-		   tree = NULL)
-{
-  if (!value_range::supports_p (type0))
-    {
-      vr->set_varying (type0);
-      return false;
-    }
-  return true;
-}
-
-/* If any of the ranges passed are defined, return TRUE, otherwise set
-   VR to UNDEFINED and return FALSE.  */
-
-static bool
-defined_ranges_p (value_range *vr,
-		  const value_range *vr0, const value_range *vr1 = NULL)
-{
-  if (vr0->undefined_p () && (!vr1 || vr1->undefined_p ()))
-    {
-      vr->set_undefined ();
-      return false;
-    }
-  return true;
-}
-
-/* Perform a binary operation on a pair of ranges.  */
-
-void
-range_fold_binary_expr (value_range *vr,
-			enum tree_code code,
-			tree expr_type,
-			const value_range *vr0_,
-			const value_range *vr1_)
-{
-  if (!supported_types_p (vr, expr_type)
-      || !defined_ranges_p (vr, vr0_, vr1_))
-    return;
-  range_op_handler op (code, expr_type);
-  if (!op)
-    {
-      vr->set_varying (expr_type);
-      return;
-    }
-
-  value_range vr0 (*vr0_);
-  value_range vr1 (*vr1_);
-  if (vr0.undefined_p ())
-    vr0.set_varying (expr_type);
-  if (vr1.undefined_p ())
-    vr1.set_varying (expr_type);
-  vr0.normalize_addresses ();
-  vr1.normalize_addresses ();
-  if (!op.fold_range (*vr, expr_type, vr0, vr1))
-    vr->set_varying (expr_type);
-}
-
-/* Perform a unary operation on a range.  */
-
-void
-range_fold_unary_expr (value_range *vr,
-		       enum tree_code code, tree expr_type,
-		       const value_range *vr0,
-		       tree vr0_type)
-{
-  if (!supported_types_p (vr, expr_type, vr0_type)
-      || !defined_ranges_p (vr, vr0))
-    return;
-  range_op_handler op (code, expr_type);
-  if (!op)
-    {
-      vr->set_varying (expr_type);
-      return;
-    }
-
-  value_range vr0_cst (*vr0);
-  vr0_cst.normalize_addresses ();
-  if (!op.fold_range (*vr, expr_type, vr0_cst, value_range (expr_type)))
-    vr->set_varying (expr_type);
-}
-
 /* Helper for overflow_comparison_p
 
    OP0 CODE OP1 is a comparison.  Examine the comparison and potentially
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index 3b1d6dc971e..bad50e31aad 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -28,11 +28,6 @@ extern int compare_values (tree, tree);
 extern int compare_values_warnv (tree, tree, bool *);
 extern int operand_less_p (tree, tree);
 
-void range_fold_unary_expr (value_range *, enum tree_code, tree type,
-			    const value_range *, tree op0_type);
-void range_fold_binary_expr (value_range *, enum tree_code, tree type,
-			     const value_range *, const value_range *);
-
 extern enum value_range_kind intersect_range_with_nonzero_bits
   (enum value_range_kind, wide_int *, wide_int *, const wide_int &, signop);
 
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Remove irange::may_contain_p.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
                   ` (3 preceding siblings ...)
  2023-04-26  8:33 ` [COMMITTED] Remove range_fold_{unary,binary}_expr Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Remove symbolics from irange Aldy Hernandez
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

The deprecated irange::may_contain_p method differed from contains_p
in that it could handle symbolics, which no longer exist in VRP.

gcc/ChangeLog:

	* value-range.cc (irange::may_contain_p): Remove.
	* value-range.h (range_includes_zero_p):  Rewrite may_contain_p
	usage with contains_p.
	* vr-values.cc (compare_range_with_value): Same.
---
 gcc/value-range.cc | 8 --------
 gcc/value-range.h  | 4 ++--
 gcc/vr-values.cc   | 3 ++-
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 26acba7b04b..6c61bcefd6e 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1475,14 +1475,6 @@ irange::value_inside_range (tree val) const
     return !!cmp2;
 }
 
-/* Return TRUE if it is possible that range contains VAL.  */
-
-bool
-irange::may_contain_p (tree val) const
-{
-  return value_inside_range (val) != 0;
-}
-
 /* Return TRUE if range contains INTEGER_CST.  */
 /* Return 1 if VAL is inside value range.
 	  0 if VAL is not inside value range.
diff --git a/gcc/value-range.h b/gcc/value-range.h
index d2a275958c8..929dc551aa2 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -173,7 +173,6 @@ public:
   bool constant_p () const;			// DEPRECATED
   void normalize_symbolics ();			// DEPRECATED
   void normalize_addresses ();			// DEPRECATED
-  bool may_contain_p (tree) const;		// DEPRECATED
   bool legacy_verbose_union_ (const class irange *);	// DEPRECATED
   bool legacy_verbose_intersect (const irange *);	// DEPRECATED
 
@@ -828,7 +827,8 @@ range_includes_zero_p (const irange *vr)
   if (vr->varying_p ())
     return true;
 
-  return vr->may_contain_p (build_zero_cst (vr->type ()));
+  tree zero = build_zero_cst (vr->type ());
+  return vr->contains_p (zero);
 }
 
 extern void gt_ggc_mx (vrange *);
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index ea4fbd7af67..841bcd1acb9 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -375,7 +375,8 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
 	return NULL_TREE;
 
       /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2.  */
-      if (!vr->may_contain_p (val))
+      bool contains_p = TREE_CODE (val) != INTEGER_CST || vr->contains_p (val);
+      if (!contains_p)
 	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
 
       return NULL_TREE;
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Remove symbolics from irange.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
                   ` (4 preceding siblings ...)
  2023-04-26  8:33 ` [COMMITTED] Remove irange::may_contain_p Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Remove irange::constant_p Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Convert users of legacy API to get_legacy_range() function Aldy Hernandez
  7 siblings, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

gcc/ChangeLog:

	* value-range.cc (irange::copy_legacy_to_multi_range): Remove
	symbolics support.
	(irange::set): Same.
	(irange::legacy_lower_bound): Same.
	(irange::legacy_upper_bound): Same.
	(irange::contains_p): Same.
	(range_tests_legacy): Same.
	(irange::normalize_addresses): Remove.
	(irange::normalize_symbolics): Remove.
	(irange::symbolic_p): Remove.
	* value-range.h (class irange): Remove symbolic_p,
	normalize_symbolics, and normalize_addresses.
	* vr-values.cc (simplify_using_ranges::two_valued_val_range_p):
	Remove symbolics support.
---
 gcc/value-range.cc | 139 ++-------------------------------------------
 gcc/value-range.h  |   3 -
 gcc/vr-values.cc   |   1 -
 3 files changed, 4 insertions(+), 139 deletions(-)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 6c61bcefd6e..ebadea8b917 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -945,7 +945,6 @@ irange::copy_legacy_to_multi_range (const irange &src)
       else
 	{
 	  value_range cst (src);
-	  cst.normalize_symbolics ();
 	  gcc_checking_assert (cst.varying_p () || cst.kind () == VR_RANGE);
 	  set (cst.min (), cst.max ());
 	}
@@ -1153,17 +1152,10 @@ irange::set (tree min, tree max, value_range_kind kind)
 	}
       return;
     }
-  // Nothing to canonicalize for symbolic ranges.
-  if (TREE_CODE (min) != INTEGER_CST
-      || TREE_CODE (max) != INTEGER_CST)
-    {
-      m_kind = kind;
-      m_base[0] = min;
-      m_base[1] = max;
-      m_num_ranges = 1;
-      m_nonzero_mask = NULL;
-      return;
-    }
+
+  // Symbolics are not allowed in an irange.
+  gcc_checking_assert (TREE_CODE (min) == INTEGER_CST
+		       && TREE_CODE (max) == INTEGER_CST);
 
   swap_out_of_order_endpoints (min, max, kind);
   if (kind == VR_VARYING)
@@ -1264,12 +1256,6 @@ wide_int
 irange::legacy_lower_bound (unsigned pair) const
 {
   gcc_checking_assert (legacy_mode_p ());
-  if (symbolic_p ())
-    {
-      value_range numeric_range (*this);
-      numeric_range.normalize_symbolics ();
-      return numeric_range.legacy_lower_bound (pair);
-    }
   gcc_checking_assert (m_num_ranges > 0);
   gcc_checking_assert (pair + 1 <= num_pairs ());
   if (m_kind == VR_ANTI_RANGE)
@@ -1291,12 +1277,6 @@ wide_int
 irange::legacy_upper_bound (unsigned pair) const
 {
   gcc_checking_assert (legacy_mode_p ());
-  if (symbolic_p ())
-    {
-      value_range numeric_range (*this);
-      numeric_range.normalize_symbolics ();
-      return numeric_range.legacy_upper_bound (pair);
-    }
   gcc_checking_assert (m_num_ranges > 0);
   gcc_checking_assert (pair + 1 <= num_pairs ());
   if (m_kind == VR_ANTI_RANGE)
@@ -1371,16 +1351,6 @@ irange::operator== (const irange &other) const
   return nz1 == nz2;
 }
 
-/* Return TRUE if this is a symbolic range.  */
-
-bool
-irange::symbolic_p () const
-{
-  return (m_num_ranges > 0
-	  && (!is_gimple_min_invariant (min ())
-	      || !is_gimple_min_invariant (max ())));
-}
-
 /* Return TRUE if this is a constant range.  */
 
 bool
@@ -1492,12 +1462,6 @@ irange::contains_p (tree cst) const
   if (legacy_mode_p ())
     {
       gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST);
-      if (symbolic_p ())
-	{
-	  value_range numeric_range (*this);
-	  numeric_range.normalize_symbolics ();
-	  return numeric_range.contains_p (cst);
-	}
       return value_inside_range (cst) == 1;
     }
 
@@ -1524,86 +1488,6 @@ irange::contains_p (tree cst) const
   return false;
 }
 
-
-/* Normalize addresses into constants.  */
-
-void
-irange::normalize_addresses ()
-{
-  if (undefined_p ())
-    return;
-
-  if (!POINTER_TYPE_P (type ()) || range_has_numeric_bounds_p (this))
-    return;
-
-  if (!range_includes_zero_p (this))
-    {
-      gcc_checking_assert (TREE_CODE (min ()) == ADDR_EXPR
-			   || TREE_CODE (max ()) == ADDR_EXPR);
-      set_nonzero (type ());
-      return;
-    }
-  set_varying (type ());
-}
-
-/* Normalize symbolics and addresses into constants.  */
-
-void
-irange::normalize_symbolics ()
-{
-  if (varying_p () || undefined_p ())
-    return;
-
-  tree ttype = type ();
-  bool min_symbolic = !is_gimple_min_invariant (min ());
-  bool max_symbolic = !is_gimple_min_invariant (max ());
-  if (!min_symbolic && !max_symbolic)
-    {
-      normalize_addresses ();
-      return;
-    }
-
-  // [SYM, SYM] -> VARYING
-  if (min_symbolic && max_symbolic)
-    {
-      set_varying (ttype);
-      return;
-    }
-  if (kind () == VR_RANGE)
-    {
-      // [SYM, NUM] -> [-MIN, NUM]
-      if (min_symbolic)
-	{
-	  set (vrp_val_min (ttype), max ());
-	  return;
-	}
-      // [NUM, SYM] -> [NUM, +MAX]
-      set (min (), vrp_val_max (ttype));
-      return;
-    }
-  gcc_checking_assert (kind () == VR_ANTI_RANGE);
-  // ~[SYM, NUM] -> [NUM + 1, +MAX]
-  if (min_symbolic)
-    {
-      if (!vrp_val_is_max (max ()))
-	{
-	  tree n = wide_int_to_tree (ttype, wi::to_wide (max ()) + 1);
-	  set (n, vrp_val_max (ttype));
-	  return;
-	}
-      set_varying (ttype);
-      return;
-    }
-  // ~[NUM, SYM] -> [-MIN, NUM - 1]
-  if (!vrp_val_is_min (min ()))
-    {
-      tree n = wide_int_to_tree (ttype, wi::to_wide (min ()) - 1);
-      set (vrp_val_min (ttype), n);
-      return;
-    }
-  set_varying (ttype);
-}
-
 /* Intersect the two value-ranges { *VR0TYPE, *VR0MIN, *VR0MAX } and
    { VR1TYPE, VR0MIN, VR0MAX } and store the result
    in { *VR0TYPE, *VR0MIN, *VR0MAX }.  This may not be the smallest
@@ -3525,21 +3409,6 @@ range_tests_legacy ()
   small = big;
   ASSERT_TRUE (small == int_range<1> (INT (21), INT (21), VR_ANTI_RANGE));
 
-  // Copying a legacy symbolic to an int_range should normalize the
-  // symbolic at copy time.
-  {
-    tree ssa = make_ssa_name (integer_type_node);
-    value_range legacy_range (ssa, INT (25));
-    int_range<2> copy = legacy_range;
-    ASSERT_TRUE (copy == int_range<2>  (vrp_val_min (integer_type_node),
-					INT (25)));
-
-    // Test that copying ~[abc_23, abc_23] to a multi-range yields varying.
-    legacy_range = value_range (ssa, ssa, VR_ANTI_RANGE);
-    copy = legacy_range;
-    ASSERT_TRUE (copy.varying_p ());
-  }
-
   // VARYING of different sizes should not be equal.
   tree big_type = build_nonstandard_integer_type (32, 1);
   tree small_type = build_nonstandard_integer_type (16, 1);
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 929dc551aa2..1012d007261 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -169,10 +169,7 @@ public:
   // Deprecated legacy public methods.
   tree min () const;				// DEPRECATED
   tree max () const;				// DEPRECATED
-  bool symbolic_p () const;			// DEPRECATED
   bool constant_p () const;			// DEPRECATED
-  void normalize_symbolics ();			// DEPRECATED
-  void normalize_addresses ();			// DEPRECATED
   bool legacy_verbose_union_ (const class irange *);	// DEPRECATED
   bool legacy_verbose_intersect (const irange *);	// DEPRECATED
 
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 841bcd1acb9..ba569b3f72f 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -2161,7 +2161,6 @@ simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b,
   value_range vr;
   if (!query->range_of_expr (vr, var, s))
     return false;
-  vr.normalize_symbolics ();
   if (vr.varying_p () || vr.undefined_p ())
     return false;
 
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Remove irange::constant_p.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
                   ` (5 preceding siblings ...)
  2023-04-26  8:33 ` [COMMITTED] Remove symbolics from irange Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  2023-04-26  8:33 ` [COMMITTED] Convert users of legacy API to get_legacy_range() function Aldy Hernandez
  7 siblings, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

gcc/ChangeLog:

	* value-range-pretty-print.cc (vrange_printer::visit): Remove
	constant_p use.
	* value-range.cc (irange::constant_p): Remove.
	(irange::get_nonzero_bits_from_range): Remove constant_p use.
	* value-range.h (class irange): Remove constant_p.
	(irange::num_pairs): Remove constant_p use.
---
 gcc/value-range-pretty-print.cc | 13 -------------
 gcc/value-range.cc              | 14 --------------
 gcc/value-range.h               |  8 ++++++--
 3 files changed, 6 insertions(+), 29 deletions(-)

diff --git a/gcc/value-range-pretty-print.cc b/gcc/value-range-pretty-print.cc
index d20e2562431..a11c5a621f8 100644
--- a/gcc/value-range-pretty-print.cc
+++ b/gcc/value-range-pretty-print.cc
@@ -63,19 +63,6 @@ vrange_printer::visit (const irange &r) const
       pp_string (pp, "VARYING");
       return;
     }
-  // Handle legacy symbolics.
-  if (!r.constant_p ())
-    {
-      if (r.kind () == VR_ANTI_RANGE)
-	pp_character (pp, '~');
-      pp_character (pp, '[');
-      dump_generic_node (pp, r.min (), 0, TDF_NONE, false);
-      pp_string (pp, ", ");
-      dump_generic_node (pp, r.max (), 0, TDF_NONE, false);
-      pp_character (pp, ']');
-      print_irange_bitmasks (r);
-      return;
-    }
   for (unsigned i = 0; i < r.num_pairs (); ++i)
     {
       pp_character (pp, '[');
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index ebadea8b917..58ae2c157db 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1351,16 +1351,6 @@ irange::operator== (const irange &other) const
   return nz1 == nz2;
 }
 
-/* Return TRUE if this is a constant range.  */
-
-bool
-irange::constant_p () const
-{
-  return (m_num_ranges > 0
-	  && TREE_CODE (min ()) == INTEGER_CST
-	  && TREE_CODE (max ()) == INTEGER_CST);
-}
-
 /* If range is a singleton, place it in RESULT and return TRUE.
    Note: A singleton can be any gimple invariant, not just constants.
    So, [&x, &x] counts as a singleton.  */
@@ -2835,10 +2825,6 @@ irange::invert ()
 wide_int
 irange::get_nonzero_bits_from_range () const
 {
-  // For legacy symbolics.
-  if (!constant_p ())
-    return wi::shwi (-1, TYPE_PRECISION (type ()));
-
   wide_int min = lower_bound ();
   wide_int max = upper_bound ();
   wide_int xorv = min ^ max;
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 1012d007261..2442f8eed70 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -169,7 +169,6 @@ public:
   // Deprecated legacy public methods.
   tree min () const;				// DEPRECATED
   tree max () const;				// DEPRECATED
-  bool constant_p () const;			// DEPRECATED
   bool legacy_verbose_union_ (const class irange *);	// DEPRECATED
   bool legacy_verbose_intersect (const irange *);	// DEPRECATED
 
@@ -692,7 +691,12 @@ inline unsigned
 irange::num_pairs () const
 {
   if (m_kind == VR_ANTI_RANGE)
-    return constant_p () ? 2 : 1;
+    {
+      bool constant_p = (TREE_CODE (min ()) == INTEGER_CST
+			 && TREE_CODE (max ()) == INTEGER_CST);
+      gcc_checking_assert (constant_p);
+      return 2;
+    }
   else
     return m_num_ranges;
 }
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [COMMITTED] Convert users of legacy API to get_legacy_range() function.
  2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
                   ` (6 preceding siblings ...)
  2023-04-26  8:33 ` [COMMITTED] Remove irange::constant_p Aldy Hernandez
@ 2023-04-26  8:33 ` Aldy Hernandez
  7 siblings, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-04-26  8:33 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

This patch converts the users of the legacy API to a function called
get_legacy_range() which will return the pieces of the soon to be
removed API (min, max, and kind).  This is a temporary measure while
these users are converted.

In upcoming patches I will convert most users, but most of the
middle-end warning uses will remain.  Naive attempts to remove them
showed that a lot of these uses are quite dependant on the anti-range
idiom, and converting them to the new API broke the tests, even when
the conversion was conceptually correct.  Perhaps someone who
understands these passes could take a stab at it.  In the meantime,
the legacy uses can be trivially found by grepping for
get_legacy_range.

gcc/ChangeLog:

	* builtins.cc (determine_block_size): Convert use of legacy API to
	get_legacy_range.
	* gimple-array-bounds.cc (check_out_of_bounds_and_warn): Same.
	(array_bounds_checker::check_array_ref): Same.
	* gimple-ssa-warn-restrict.cc
	(builtin_memref::extend_offset_range): Same.
	* ipa-cp.cc (ipcp_store_vr_results): Same.
	* ipa-fnsummary.cc (set_switch_stmt_execution_predicate): Same.
	* ipa-prop.cc (struct ipa_vr_ggc_hash_traits): Same.
	(ipa_write_jump_function): Same.
	* pointer-query.cc (get_size_range): Same.
	* tree-data-ref.cc (split_constant_offset): Same.
	* tree-ssa-strlen.cc (get_range): Same.
	(maybe_diag_stxncpy_trunc): Same.
	(strlen_pass::get_len_or_size): Same.
	(strlen_pass::count_nonzero_bytes_addr): Same.
	* tree-vect-patterns.cc (vect_get_range_info): Same.
	* value-range.cc (irange::maybe_anti_range): Remove.
	(get_legacy_range): New.
	(irange::copy_to_legacy):
	(ranges_from_anti_range): Use get_legacy_range.
	* value-range.h (class irange): Remove maybe_anti_range.
	(get_legacy_range): New.
	* vr-values.cc (check_for_binary_op_overflow): Convert use of
	legacy API to get_legacy_range.
	(compare_ranges): Same.
	(compare_range_with_value): Same.
	(bounds_of_var_in_loop): Same.
	(find_case_label_ranges): Same.
	(simplify_using_ranges::simplify_switch_using_ranges): Same.
---
 gcc/builtins.cc                 |   7 +-
 gcc/gimple-array-bounds.cc      |   9 ++-
 gcc/gimple-ssa-warn-restrict.cc |   7 +-
 gcc/ipa-cp.cc                   |   7 +-
 gcc/ipa-fnsummary.cc            |   7 +-
 gcc/ipa-prop.cc                 |  16 +++--
 gcc/pointer-query.cc            |   7 +-
 gcc/tree-data-ref.cc            |   7 +-
 gcc/tree-ssa-strlen.cc          |  29 ++++----
 gcc/tree-vect-patterns.cc       |   7 +-
 gcc/value-range.cc              |  89 ++++++++++++++++-------
 gcc/value-range.h               |   3 +-
 gcc/vr-values.cc                | 123 +++++++++++++++++++-------------
 13 files changed, 199 insertions(+), 119 deletions(-)

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 0e06fa5b2e0..bb931242c9c 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -3570,12 +3570,13 @@ determine_block_size (tree len, rtx len_rtx,
       if (TREE_CODE (len) == SSA_NAME)
 	{
 	  value_range r;
+	  tree tmin, tmax;
 	  get_global_range_query ()->range_of_expr (r, len);
-	  range_type = r.kind ();
+	  range_type = get_legacy_range (r, tmin, tmax);
 	  if (range_type != VR_UNDEFINED)
 	    {
-	      min = wi::to_wide (r.min ());
-	      max = wi::to_wide (r.max ());
+	      min = wi::to_wide (tmin);
+	      max = wi::to_wide (tmax);
 	    }
 	}
       if (range_type == VR_RANGE)
diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc
index 775f0c13258..e04c8e29d5a 100644
--- a/gcc/gimple-array-bounds.cc
+++ b/gcc/gimple-array-bounds.cc
@@ -266,6 +266,7 @@ check_out_of_bounds_and_warn (location_t location, tree ref,
 			      bool ignore_off_by_one, bool for_array_bound,
 			      bool *out_of_bound)
 {
+  tree min, max;
   tree low_bound = array_ref_low_bound (ref);
   tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
 
@@ -284,7 +285,7 @@ check_out_of_bounds_and_warn (location_t location, tree ref,
 
   if (warned)
     ; /* Do nothing.  */
-  else if (vr->kind () == VR_ANTI_RANGE)
+  else if (get_legacy_range (*vr, min, max) == VR_ANTI_RANGE)
     {
       if (up_bound
 	  && TREE_CODE (up_sub) == INTEGER_CST
@@ -378,8 +379,10 @@ array_bounds_checker::check_array_ref (location_t location, tree ref,
       get_value_range (vr, low_sub_org, stmt);
       if (!vr.undefined_p () && !vr.varying_p ())
 	{
-	  low_sub = vr.kind () == VR_RANGE ? vr.max () : vr.min ();
-	  up_sub = vr.kind () == VR_RANGE ? vr.min () : vr.max ();
+	  tree min, max;
+	  value_range_kind kind = get_legacy_range (vr, min, max);
+	  low_sub = kind == VR_RANGE ? max : min;
+	  up_sub = kind == VR_RANGE ? min : max;
 	}
     }
 
diff --git a/gcc/gimple-ssa-warn-restrict.cc b/gcc/gimple-ssa-warn-restrict.cc
index ee7040a881d..56aed519b6d 100644
--- a/gcc/gimple-ssa-warn-restrict.cc
+++ b/gcc/gimple-ssa-warn-restrict.cc
@@ -355,11 +355,12 @@ builtin_memref::extend_offset_range (tree offset)
       value_range vr;
       if (m_ptr_qry.rvals->range_of_expr (vr, offset, stmt))
 	{
-	  rng = vr.kind ();
+	  tree vr_min, vr_max;
+	  rng = get_legacy_range (vr, vr_min, vr_max);
 	  if (!vr.undefined_p ())
 	    {
-	      min = wi::to_wide (vr.min ());
-	      max = wi::to_wide (vr.max ());
+	      min = wi::to_wide (vr_min);
+	      max = wi::to_wide (vr_max);
 	    }
 	}
 
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 6788883c40b..9ec86d77992 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -6614,10 +6614,11 @@ ipcp_store_vr_results (void)
 	      && !plats->m_value_range.top_p ()
 	      && dbg_cnt (ipa_cp_vr))
 	    {
+	      tree min, max;
 	      vr.known = true;
-	      vr.type = plats->m_value_range.m_vr.kind ();
-	      vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
-	      vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
+	      vr.type = get_legacy_range (plats->m_value_range.m_vr, min, max);
+	      vr.min = wi::to_wide (min);
+	      vr.max = wi::to_wide (max);
 	    }
 	  else
 	    {
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index 03142960e60..48093a8b623 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -1692,9 +1692,10 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
   get_range_query (cfun)->range_of_expr (vr, op);
   if (vr.undefined_p ())
     vr.set_varying (TREE_TYPE (op));
-  value_range_kind vr_type = vr.kind ();
-  wide_int vr_wmin = wi::to_wide (vr.min ());
-  wide_int vr_wmax = wi::to_wide (vr.max ());
+  tree vr_min, vr_max;
+  value_range_kind vr_type = get_legacy_range (vr, vr_min, vr_max);
+  wide_int vr_wmin = wi::to_wide (vr_min);
+  wide_int vr_wmax = wi::to_wide (vr_max);
 
   FOR_EACH_EDGE (e, ei, bb->succs)
     {
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index f706f099f7a..1a8ff7ebb95 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -118,9 +118,11 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
   static hashval_t
   hash (const value_range *p)
     {
-      inchash::hash hstate (p->kind ());
-      inchash::add_expr (p->min (), hstate);
-      inchash::add_expr (p->max (), hstate);
+      tree min, max;
+      value_range_kind kind = get_legacy_range (*p, min, max);
+      inchash::hash hstate (kind);
+      inchash::add_expr (min, hstate);
+      inchash::add_expr (max, hstate);
       return hstate.end ();
     }
   static bool
@@ -4783,10 +4785,12 @@ ipa_write_jump_function (struct output_block *ob,
   streamer_write_bitpack (&bp);
   if (jump_func->m_vr)
     {
+      tree min, max;
+      value_range_kind kind = get_legacy_range (*jump_func->m_vr, min, max);
       streamer_write_enum (ob->main_stream, value_rang_type,
-			   VR_LAST, jump_func->m_vr->kind ());
-      stream_write_tree (ob, jump_func->m_vr->min (), true);
-      stream_write_tree (ob, jump_func->m_vr->max (), true);
+			   VR_LAST, kind);
+      stream_write_tree (ob, min, true);
+      stream_write_tree (ob, max, true);
     }
 }
 
diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index 5b05e9bedf8..9723358f965 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -317,14 +317,15 @@ get_size_range (range_query *query, tree exp, gimple *stmt, tree range[2],
   if (integral)
     {
       value_range vr;
+      tree tmin, tmax;
 
       query->range_of_expr (vr, exp, stmt);
 
       if (vr.undefined_p ())
 	vr.set_varying (TREE_TYPE (exp));
-      range_type = vr.kind ();
-      min = wi::to_wide (vr.min ());
-      max = wi::to_wide (vr.max ());
+      range_type = get_legacy_range (vr, tmin, tmax);
+      min = wi::to_wide (tmin);
+      max = wi::to_wide (tmax);
     }
   else
     range_type = VR_VARYING;
diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc
index 23602518665..4ebd839db15 100644
--- a/gcc/tree-data-ref.cc
+++ b/gcc/tree-data-ref.cc
@@ -1024,9 +1024,10 @@ split_constant_offset (tree exp, tree *var, tree *off, value_range *exp_range,
 	  get_range_query (cfun)->range_of_expr (vr, exp);
 	  if (vr.undefined_p ())
 	    vr.set_varying (TREE_TYPE (exp));
-	  wide_int var_min = wi::to_wide (vr.min ());
-	  wide_int var_max = wi::to_wide (vr.max ());
-	  value_range_kind vr_kind = vr.kind ();
+	  tree vr_min, vr_max;
+	  value_range_kind vr_kind = get_legacy_range (vr, vr_min, vr_max);
+	  wide_int var_min = wi::to_wide (vr_min);
+	  wide_int var_max = wi::to_wide (vr_max);
 	  wide_int var_nonzero = get_nonzero_bits (exp);
 	  vr_kind = intersect_range_with_nonzero_bits (vr_kind,
 						       &var_min, &var_max,
diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc
index 7508c1768a5..1d79034594b 100644
--- a/gcc/tree-ssa-strlen.cc
+++ b/gcc/tree-ssa-strlen.cc
@@ -219,12 +219,13 @@ get_range (tree val, gimple *stmt, wide_int minmax[2],
   if (!rvals->range_of_expr (vr, val, stmt))
     return NULL_TREE;
 
-  value_range_kind rng = vr.kind ();
+  tree vrmin, vrmax;
+  value_range_kind rng = get_legacy_range (vr, vrmin, vrmax);
   if (rng == VR_RANGE)
     {
       /* Only handle straight ranges.  */
-      minmax[0] = wi::to_wide (vr.min ());
-      minmax[1] = wi::to_wide (vr.max ());
+      minmax[0] = wi::to_wide (vrmin);
+      minmax[1] = wi::to_wide (vrmax);
       return val;
     }
 
@@ -2919,9 +2920,11 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
       || r.undefined_p ())
     return false;
 
-  cntrange[0] = wi::to_wide (r.min ());
-  cntrange[1] = wi::to_wide (r.max ());
-  if (r.kind () == VR_ANTI_RANGE)
+  tree min, max;
+  value_range_kind kind = get_legacy_range (r, min, max);
+  cntrange[0] = wi::to_wide (min);
+  cntrange[1] = wi::to_wide (max);
+  if (kind == VR_ANTI_RANGE)
     {
       wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));
 
@@ -4086,8 +4089,9 @@ strlen_pass::get_len_or_size (gimple *stmt, tree arg, int idx,
       else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
 	{
 	  value_range r;
-	  get_range_query (cfun)->range_of_expr (r, si->nonzero_chars);
-	  if (r.kind () == VR_RANGE)
+	  if (get_range_query (cfun)->range_of_expr (r, si->nonzero_chars)
+	      && !r.undefined_p ()
+	      && !r.varying_p ())
 	    {
 	      lenrng[0] = r.lower_bound ().to_uhwi ();
 	      lenrng[1] = r.upper_bound ().to_uhwi ();
@@ -4808,12 +4812,13 @@ strlen_pass::count_nonzero_bytes_addr (tree exp, gimple *stmt,
 	       && TREE_CODE (si->nonzero_chars) == SSA_NAME)
 	{
 	  value_range vr;
-	  ptr_qry.rvals->range_of_expr (vr, si->nonzero_chars, stmt);
-	  if (vr.kind () != VR_RANGE)
+	  if (!ptr_qry.rvals->range_of_expr (vr, si->nonzero_chars, stmt)
+	      || vr.undefined_p ()
+	      || vr.varying_p ())
 	    return false;
 
-	  minlen = tree_to_uhwi (vr.min ());
-	  maxlen = tree_to_uhwi (vr.max ());
+	  minlen = vr.lower_bound ().to_uhwi ();
+	  maxlen = vr.upper_bound ().to_uhwi ();
 	}
       else
 	return false;
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index a49b0953977..b964dcb8ad9 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -65,12 +65,13 @@ static bool
 vect_get_range_info (tree var, wide_int *min_value, wide_int *max_value)
 {
   value_range vr;
+  tree vr_min, vr_max;
   get_range_query (cfun)->range_of_expr (vr, var);
   if (vr.undefined_p ())
     vr.set_varying (TREE_TYPE (var));
-  *min_value = wi::to_wide (vr.min ());
-  *max_value = wi::to_wide (vr.max ());
-  value_range_kind vr_type = vr.kind ();
+  value_range_kind vr_type = get_legacy_range (vr, vr_min, vr_max);
+  *min_value = wi::to_wide (vr_min);
+  *max_value = wi::to_wide (vr_max);
   wide_int nonzero = get_nonzero_bits (var);
   signop sgn = TYPE_SIGN (TREE_TYPE (var));
   if (intersect_range_with_nonzero_bits (vr_type, min_value, max_value,
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 58ae2c157db..a50d1a63968 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -914,19 +914,58 @@ irange::operator= (const irange &src)
   return *this;
 }
 
-// Return TRUE if range is a multi-range that can be represented as a
-// VR_ANTI_RANGE.
-
-bool
-irange::maybe_anti_range () const
+value_range_kind
+get_legacy_range (const irange &r, tree &min, tree &max)
 {
-  tree ttype = type ();
-  unsigned int precision = TYPE_PRECISION (ttype);
-  signop sign = TYPE_SIGN (ttype);
-  return (num_pairs () > 1
-	  && precision > 1
-	  && lower_bound () == wi::min_value (precision, sign)
-	  && upper_bound () == wi::max_value (precision, sign));
+  value_range_kind old_kind = r.kind ();
+  tree old_min = r.min ();
+  tree old_max = r.max ();
+
+  if (r.undefined_p ())
+    {
+      min = NULL_TREE;
+      max = NULL_TREE;
+      gcc_checking_assert (old_kind == VR_UNDEFINED);
+      return VR_UNDEFINED;
+    }
+
+  tree type = r.type ();
+  if (r.varying_p ())
+    {
+      min = wide_int_to_tree (type, r.lower_bound ());
+      max = wide_int_to_tree (type, r.upper_bound ());
+      gcc_checking_assert (old_kind == VR_VARYING);
+      gcc_checking_assert (vrp_operand_equal_p (old_min, min));
+      gcc_checking_assert (vrp_operand_equal_p (old_max, max));
+      return VR_VARYING;
+    }
+
+  unsigned int precision = TYPE_PRECISION (type);
+  signop sign = TYPE_SIGN (type);
+  if (r.num_pairs () > 1
+      && precision > 1
+      && r.lower_bound () == wi::min_value (precision, sign)
+      && r.upper_bound () == wi::max_value (precision, sign))
+    {
+      int_range<3> inv (r);
+      inv.invert ();
+      min = wide_int_to_tree (type, inv.lower_bound (0));
+      max = wide_int_to_tree (type, inv.upper_bound (0));
+      if (r.legacy_mode_p ())
+	{
+	  gcc_checking_assert (old_kind == VR_ANTI_RANGE);
+	  gcc_checking_assert (vrp_operand_equal_p (old_min, min));
+	  gcc_checking_assert (vrp_operand_equal_p (old_max, max));
+	}
+      return VR_ANTI_RANGE;
+    }
+
+  min = wide_int_to_tree (type, r.lower_bound ());
+  max = wide_int_to_tree (type, r.upper_bound ());
+  gcc_checking_assert (old_kind == VR_RANGE);
+  gcc_checking_assert (vrp_operand_equal_p (old_min, min));
+  gcc_checking_assert (vrp_operand_equal_p (old_max, max));
+  return VR_RANGE;
 }
 
 void
@@ -968,13 +1007,9 @@ irange::copy_to_legacy (const irange &src)
       return;
     }
   // Copy multi-range to legacy.
-  if (src.maybe_anti_range ())
-    {
-      int_range<3> r (src);
-      r.invert ();
-      // Use tree variants to save on tree -> wi -> tree conversions.
-      set (r.tree_lower_bound (0), r.tree_upper_bound (0), VR_ANTI_RANGE);
-    }
+  tree min, max;
+  if (get_legacy_range (src, min, max) == VR_ANTI_RANGE)
+    set (min, max, VR_ANTI_RANGE);
   else
     set (src.tree_lower_bound (), src.tree_upper_bound ());
 }
@@ -3056,18 +3091,20 @@ ranges_from_anti_range (const value_range *ar,
   /* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U
      [A+1, +INF].  Not sure if this helps in practice, though.  */
 
-  if (ar->kind () != VR_ANTI_RANGE
-      || TREE_CODE (ar->min ()) != INTEGER_CST
-      || TREE_CODE (ar->max ()) != INTEGER_CST
+  tree ar_min, ar_max;
+  value_range_kind kind = get_legacy_range (*ar, ar_min, ar_max);
+  if (kind != VR_ANTI_RANGE
+      || TREE_CODE (ar_min) != INTEGER_CST
+      || TREE_CODE (ar_max) != INTEGER_CST
       || !vrp_val_min (type)
       || !vrp_val_max (type))
     return false;
 
-  if (tree_int_cst_lt (vrp_val_min (type), ar->min ()))
+  if (tree_int_cst_lt (vrp_val_min (type), ar_min))
     vr0->set (vrp_val_min (type),
-	      wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1));
-  if (tree_int_cst_lt (ar->max (), vrp_val_max (type)))
-    vr1->set (wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1),
+	      wide_int_to_tree (type, wi::to_wide (ar_min) - 1));
+  if (tree_int_cst_lt (ar_max, vrp_val_max (type)))
+    vr1->set (wide_int_to_tree (type, wi::to_wide (ar_max) + 1),
 	      vrp_val_max (type));
   if (vr0->undefined_p ())
     {
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 2442f8eed70..c1474a73eaf 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -118,6 +118,7 @@ namespace inchash
 
 class GTY((user)) irange : public vrange
 {
+  friend value_range_kind get_legacy_range (const irange &, tree &, tree &);
   friend class vrange_allocator;
   friend class irange_storage_slot; // For legacy_mode_p checks.
 public:
@@ -197,7 +198,6 @@ protected:
   wide_int legacy_lower_bound (unsigned = 0) const;
   wide_int legacy_upper_bound (unsigned) const;
   int value_inside_range (tree) const;
-  bool maybe_anti_range () const;
   void copy_to_legacy (const irange &);
   void copy_legacy_to_multi_range (const irange &);
 
@@ -672,6 +672,7 @@ irange::legacy_mode_p () const
 extern bool range_has_numeric_bounds_p (const irange *);
 extern bool ranges_from_anti_range (const value_range *,
 				    value_range *, value_range *);
+extern value_range_kind get_legacy_range (const irange &, tree &min, tree &max);
 extern void dump_value_range (FILE *, const vrange *);
 extern bool vrp_val_is_min (const_tree);
 extern bool vrp_val_is_max (const_tree);
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index ba569b3f72f..f43de63b4f4 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -124,8 +124,9 @@ check_for_binary_op_overflow (range_query *query,
   else
     vr1.set_varying (TREE_TYPE (op1));
 
-  tree vr0min = vr0.min (), vr0max = vr0.max ();
-  tree vr1min = vr1.min (), vr1max = vr1.max ();
+  tree vr0min, vr0max, vr1min, vr1max;
+  get_legacy_range (vr0, vr0min, vr0max);
+  get_legacy_range (vr1, vr1min, vr1max);
   if (!range_int_cst_p (&vr0)
       || TREE_OVERFLOW (vr0min)
       || TREE_OVERFLOW (vr0max))
@@ -233,11 +234,14 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
     return NULL_TREE;
 
   /* Anti-ranges need to be handled separately.  */
-  if (vr0->kind () == VR_ANTI_RANGE || vr1->kind () == VR_ANTI_RANGE)
+  tree vr0min, vr0max, vr1min, vr1max;
+  value_range_kind kind0 = get_legacy_range (*vr0, vr0min, vr0max);
+  value_range_kind kind1 = get_legacy_range (*vr1, vr1min, vr1max);
+  if (kind0 == VR_ANTI_RANGE || kind1 == VR_ANTI_RANGE)
     {
       /* If both are anti-ranges, then we cannot compute any
 	 comparison.  */
-      if (vr0->kind () == VR_ANTI_RANGE && vr1->kind () == VR_ANTI_RANGE)
+      if (kind0 == VR_ANTI_RANGE && kind1 == VR_ANTI_RANGE)
 	return NULL_TREE;
 
       /* These comparisons are never statically computable.  */
@@ -249,14 +253,19 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
 
       /* Equality can be computed only between a range and an
 	 anti-range.  ~[VAL1, VAL2] == [VAL1, VAL2] is always false.  */
-      if (vr0->kind () == VR_RANGE)
-	/* To simplify processing, make VR0 the anti-range.  */
-	std::swap (vr0, vr1);
+      if (kind0 == VR_RANGE)
+	{
+	  /* To simplify processing, make VR0 the anti-range.  */
+	  kind0 = kind1;
+	  vr0min = vr1min;
+	  vr0max = vr1max;
+	  kind1 = get_legacy_range (*vr0, vr1min, vr1max);
+	}
 
       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)
+      if (compare_values_warnv (vr0min, vr1min, strict_overflow_p) == 0
+	  && compare_values_warnv (vr0max, vr1max, strict_overflow_p) == 0)
 	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
 
       return NULL_TREE;
@@ -267,19 +276,22 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
   if (comp == GT_EXPR || comp == GE_EXPR)
     {
       comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
-      std::swap (vr0, vr1);
+      kind0 = kind1;
+      vr0min = vr1min;
+      vr0max = vr1max;
+      kind1 = get_legacy_range (*vr0, vr1min, vr1max);
     }
 
   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)
+      if (compare_values_warnv (vr0min, vr0max, strict_overflow_p) == 0
+	  && compare_values_warnv (vr1min, vr1max, strict_overflow_p) == 0)
 	{
-	  int cmp_min = compare_values_warnv (vr0->min (), vr1->min (),
+	  int cmp_min = compare_values_warnv (vr0min, vr1min,
 					      strict_overflow_p);
-	  int cmp_max = compare_values_warnv (vr0->max (), vr1->max (),
+	  int cmp_max = compare_values_warnv (vr0max, vr1max,
 					      strict_overflow_p);
 	  if (cmp_min == 0 && cmp_max == 0)
 	    return boolean_true_node;
@@ -287,9 +299,9 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
 	    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 (),
+      else if (compare_values_warnv (vr0min, vr1max,
 				     strict_overflow_p) == 1
-	       || compare_values_warnv (vr1->min (), vr0->max (),
+	       || compare_values_warnv (vr1min, vr0max,
 					strict_overflow_p) == 1)
 	return boolean_false_node;
 
@@ -304,20 +316,20 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
 	 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);
+      cmp1 = compare_values_warnv (vr0max, vr1min, strict_overflow_p);
+      cmp2 = compare_values_warnv (vr0min, vr1max, 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 (),
+      else if (compare_values_warnv (vr0min, vr0max,
 				     strict_overflow_p) == 0
-	       && compare_values_warnv (vr1->min (), vr1->max (),
+	       && compare_values_warnv (vr1min, vr1max,
 					strict_overflow_p) == 0
-	       && compare_values_warnv (vr0->min (), vr1->min (),
+	       && compare_values_warnv (vr0min, vr1min,
 					strict_overflow_p) == 0
-	       && compare_values_warnv (vr0->max (), vr1->max (),
+	       && compare_values_warnv (vr0max, vr1max,
 					strict_overflow_p) == 0)
 	return boolean_false_node;
 
@@ -330,13 +342,13 @@ compare_ranges (enum tree_code comp, const value_range *vr0,
       int tst;
 
       /* If VR0 is to the left of VR1, return true.  */
-      tst = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
+      tst = compare_values_warnv (vr0max, vr1min, strict_overflow_p);
       if ((comp == LT_EXPR && tst == -1)
 	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
 	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);
+      tst = compare_values_warnv (vr0min, vr1max, strict_overflow_p);
       if ((comp == LT_EXPR && (tst == 0 || tst == 1))
 	  || (comp == LE_EXPR && tst == 1))
 	return boolean_false_node;
@@ -364,7 +376,8 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
     return NULL_TREE;
 
   /* Anti-ranges need to be handled separately.  */
-  if (vr->kind () == VR_ANTI_RANGE)
+  tree min, max;
+  if (get_legacy_range (*vr, min, max) == VR_ANTI_RANGE)
     {
       /* For anti-ranges, the only predicates that we can compute at
 	 compile time are equality and inequality.  */
@@ -386,16 +399,16 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
     {
       /* EQ_EXPR may only be computed if VR represents exactly
 	 one value.  */
-      if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0)
+      if (compare_values_warnv (min, max, strict_overflow_p) == 0)
 	{
-	  int cmp = compare_values_warnv (vr->min (), val, strict_overflow_p);
+	  int cmp = compare_values_warnv (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)
+      else if (compare_values_warnv (val, min, strict_overflow_p) == -1
+	       || compare_values_warnv (max, val, strict_overflow_p) == -1)
 	return boolean_false_node;
 
       return NULL_TREE;
@@ -403,14 +416,14 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
   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)
+      if (compare_values_warnv (max, val, strict_overflow_p) == -1
+	  || compare_values_warnv (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)
+      if (compare_values_warnv (min, max, strict_overflow_p) == 0
+	  && compare_values_warnv (min, val, strict_overflow_p) == 0)
 	return boolean_false_node;
 
       /* Otherwise, they may or may not be different.  */
@@ -421,13 +434,13 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
       int tst;
 
       /* If VR is to the left of VAL, return true.  */
-      tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
+      tst = compare_values_warnv (max, val, strict_overflow_p);
       if ((comp == LT_EXPR && tst == -1)
 	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
 	return boolean_true_node;
 
       /* If VR is to the right of VAL, return false.  */
-      tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
+      tst = compare_values_warnv (min, val, strict_overflow_p);
       if ((comp == LT_EXPR && (tst == 0 || tst == 1))
 	  || (comp == LE_EXPR && tst == 1))
 	return boolean_false_node;
@@ -440,13 +453,13 @@ compare_range_with_value (enum tree_code comp, const value_range *vr,
       int tst;
 
       /* If VR is to the right of VAL, return true.  */
-      tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
+      tst = compare_values_warnv (min, val, strict_overflow_p);
       if ((comp == GT_EXPR && tst == 1)
 	  || (comp == GE_EXPR && (tst == 0 || tst == 1)))
 	return boolean_true_node;
 
       /* If VR is to the left of VAL, return false.  */
-      tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
+      tst = compare_values_warnv (max, val, strict_overflow_p);
       if ((comp == GT_EXPR && (tst == -1 || tst == 0))
 	  || (comp == GE_EXPR && tst == -1))
 	return boolean_false_node;
@@ -544,11 +557,12 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
 
   /* Try to use estimated number of iterations for the loop to constrain the
      final value in the evolution.  */
+  tree rmin, rmax;
   if (TREE_CODE (step) == INTEGER_CST
       && is_gimple_val (init)
       && (TREE_CODE (init) != SSA_NAME
 	  || (query->range_of_expr (r, init, stmt)
-	      && r.kind () == VR_RANGE)))
+	      && get_legacy_range (r, rmin, rmax) == VR_RANGE)))
     {
       widest_int nit;
 
@@ -584,9 +598,12 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
 	      range_op_handler handler (PLUS_EXPR, TREE_TYPE (init));
 	      if (!handler.fold_range (maxvr, TREE_TYPE (init), vr0, vr1))
 		maxvr.set_varying (TREE_TYPE (init));
+	      tree maxvr_min, maxvr_max;
+	      value_range_kind maxvr_kind
+		= get_legacy_range (maxvr, maxvr_min, maxvr_max);
 
 	      /* Likewise if the addition did.  */
-	      if (maxvr.kind () == VR_RANGE)
+	      if (maxvr_kind == VR_RANGE)
 		{
 		  int_range<2> initvr;
 
@@ -597,18 +614,21 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query,
 		  else
 		    return false;
 
+		  tree initvr_min, initvr_max;
+		  get_legacy_range (initvr, initvr_min, initvr_max);
+
 		  /* Check if init + nit * step overflows.  Though we checked
 		     scev {init, step}_loop doesn't wrap, it is not enough
 		     because the loop may exit immediately.  Overflow could
 		     happen in the plus expression in this case.  */
 		  if ((dir == EV_DIR_DECREASES
-		       && compare_values (maxvr.min (), initvr.min ()) != -1)
+		       && compare_values (maxvr_min, initvr_min) != -1)
 		      || (dir == EV_DIR_GROWS
-			  && compare_values (maxvr.max (), initvr.max ()) != 1))
+			  && compare_values (maxvr_max, initvr_max) != 1))
 		    return false;
 
-		  tmin = maxvr.min ();
-		  tmax = maxvr.max ();
+		  tmin = maxvr_min;
+		  tmax = maxvr_max;
 		}
 	    }
 	}
@@ -810,7 +830,8 @@ find_case_label_ranges (gswitch *stmt, const value_range *vr,
   unsigned int n = gimple_switch_num_labels (stmt);
   bool take_default;
   tree case_low, case_high;
-  tree min = vr->min (), max = vr->max ();
+  tree min, max;
+  value_range_kind kind = get_legacy_range (*vr, min, max);
 
   gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
 
@@ -820,7 +841,7 @@ find_case_label_ranges (gswitch *stmt, const value_range *vr,
   *min_idx2 = 1;
   *max_idx2 = 0;
 
-  if (vr->kind () == VR_RANGE)
+  if (kind == VR_RANGE)
     {
       *min_idx1 = i;
       *max_idx1 = j;
@@ -1724,8 +1745,10 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
   /* We can truncate the case label ranges that partially overlap with OP's
      value range.  */
   size_t min_idx = 1, max_idx = 0;
+  tree min, max;
+  value_range_kind kind = get_legacy_range (vr, min, max);
   if (!vr.undefined_p ())
-    find_case_label_range (stmt, vr.min (), vr.max (), &min_idx, &max_idx);
+    find_case_label_range (stmt, min, max, &min_idx, &max_idx);
   if (min_idx <= max_idx)
     {
       tree min_label = gimple_switch_label (stmt, min_idx);
@@ -1733,10 +1756,10 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
 
       /* Avoid changing the type of the case labels when truncating.  */
       tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
-      tree vr_min = fold_convert (case_label_type, vr.min ());
-      tree vr_max = fold_convert (case_label_type, vr.max ());
+      tree vr_min = fold_convert (case_label_type, min);
+      tree vr_max = fold_convert (case_label_type, max);
 
-      if (vr.kind () == VR_RANGE)
+      if (kind == VR_RANGE)
 	{
 	  /* If OP's value range is [2,8] and the low label range is
 	     0 ... 3, truncate the label's range to 2 .. 3.  */
@@ -1752,7 +1775,7 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
 	      && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
 	    CASE_HIGH (max_label) = vr_max;
 	}
-      else if (vr.kind () == VR_ANTI_RANGE)
+      else if (kind == VR_ANTI_RANGE)
 	{
 	  tree one_cst = build_one_cst (case_label_type);
 
-- 
2.40.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [COMMITTED] Remove deprecated range_fold_{unary, binary}_expr uses from ipa-*.
  2023-04-26  8:33 ` [COMMITTED] Remove deprecated range_fold_{unary,binary}_expr uses from ipa-* Aldy Hernandez
@ 2023-05-05 15:10   ` Martin Jambor
  2023-05-11  9:58     ` Aldy Hernandez
  2023-05-15 17:33     ` Aldy Hernandez
  0 siblings, 2 replies; 12+ messages in thread
From: Martin Jambor @ 2023-05-05 15:10 UTC (permalink / raw)
  To: GCC patches; +Cc: Andrew MacLeod, Aldy Hernandez

Hello,

On Wed, Apr 26 2023, Aldy Hernandez via Gcc-patches wrote:
> gcc/ChangeLog:
>
> 	* ipa-cp.cc (ipa_vr_operation_and_type_effects): Convert to ranger API.
> 	(ipa_value_range_from_jfunc): Same.
> 	(propagate_vr_across_jump_function): Same.
> 	* ipa-fnsummary.cc (evaluate_conditions_for_known_args): Same.
> 	* ipa-prop.cc (ipa_compute_jump_functions_for_edge): Same.
> 	* vr-values.cc (bounds_of_var_in_loop): Same.

thanks for taking care of the value range uses in IPA.

> ---
>  gcc/ipa-cp.cc        | 28 +++++++++++++++++++++------
>  gcc/ipa-fnsummary.cc | 45 ++++++++++++++++++++++++++++----------------
>  gcc/ipa-prop.cc      |  5 ++---
>  gcc/vr-values.cc     |  6 ++++--
>  4 files changed, 57 insertions(+), 27 deletions(-)
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index 65c49558b58..6788883c40b 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -128,6 +128,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "attribs.h"
>  #include "dbgcnt.h"
>  #include "symtab-clones.h"
> +#include "gimple-range.h"
>  
>  template <typename valtype> class ipcp_value;
>  
> @@ -1900,10 +1901,15 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr,
>  				   enum tree_code operation,
>  				   tree dst_type, tree src_type)
>  {
> -  range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
> -  if (dst_vr->varying_p () || dst_vr->undefined_p ())
> +  if (!irange::supports_p (dst_type) || !irange::supports_p (src_type))
>      return false;
> -  return true;
> +
> +  range_op_handler handler (operation, dst_type);

Would it be possible to document the range_op_handler class somewhat?

> +  return (handler
> +	  && handler.fold_range (*dst_vr, dst_type,
> +				 *src_vr, value_range (dst_type))
> +	  && !dst_vr->varying_p ()
> +	  && !dst_vr->undefined_p ());

It looks important but the class is not documented at all.  Although the
use of fold_range is probably hopefully mostly clear from its uses in
this patch, the meaning of the return value of this method and what
other methods do is less obvious.

For example, I am curious why (not in this patch, but in the code as it
is now in the repo), uses of fold_range seem to be always preceeded with
a check for supports_type_p, even though the type is then also fed into
fold_range itself.  Does the return value of fold_range mean something
slightly different from "could not deduce anything?"

Thanks!

Martin

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [COMMITTED] Remove deprecated range_fold_{unary, binary}_expr uses from ipa-*.
  2023-05-05 15:10   ` [COMMITTED] Remove deprecated range_fold_{unary, binary}_expr " Martin Jambor
@ 2023-05-11  9:58     ` Aldy Hernandez
  2023-05-15 17:33     ` Aldy Hernandez
  1 sibling, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-05-11  9:58 UTC (permalink / raw)
  To: Martin Jambor, GCC patches; +Cc: Andrew MacLeod



On 5/5/23 17:10, Martin Jambor wrote:
> Hello,
> 
> On Wed, Apr 26 2023, Aldy Hernandez via Gcc-patches wrote:
>> gcc/ChangeLog:
>>
>> 	* ipa-cp.cc (ipa_vr_operation_and_type_effects): Convert to ranger API.
>> 	(ipa_value_range_from_jfunc): Same.
>> 	(propagate_vr_across_jump_function): Same.
>> 	* ipa-fnsummary.cc (evaluate_conditions_for_known_args): Same.
>> 	* ipa-prop.cc (ipa_compute_jump_functions_for_edge): Same.
>> 	* vr-values.cc (bounds_of_var_in_loop): Same.
> 
> thanks for taking care of the value range uses in IPA.
> 
>> ---
>>   gcc/ipa-cp.cc        | 28 +++++++++++++++++++++------
>>   gcc/ipa-fnsummary.cc | 45 ++++++++++++++++++++++++++++----------------
>>   gcc/ipa-prop.cc      |  5 ++---
>>   gcc/vr-values.cc     |  6 ++++--
>>   4 files changed, 57 insertions(+), 27 deletions(-)
>>
>> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
>> index 65c49558b58..6788883c40b 100644
>> --- a/gcc/ipa-cp.cc
>> +++ b/gcc/ipa-cp.cc
>> @@ -128,6 +128,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "attribs.h"
>>   #include "dbgcnt.h"
>>   #include "symtab-clones.h"
>> +#include "gimple-range.h"
>>   
>>   template <typename valtype> class ipcp_value;
>>   
>> @@ -1900,10 +1901,15 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr,
>>   				   enum tree_code operation,
>>   				   tree dst_type, tree src_type)
>>   {
>> -  range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
>> -  if (dst_vr->varying_p () || dst_vr->undefined_p ())
>> +  if (!irange::supports_p (dst_type) || !irange::supports_p (src_type))
>>       return false;
>> -  return true;
>> +
>> +  range_op_handler handler (operation, dst_type);
> 
> Would it be possible to document the range_op_handler class somewhat?

Sorry for the late response, but you're totally right.  We're in dire 
need of documentation here.  I had planned to work on comments and 
actual documentation much later this cycle, but I may need to bump that 
up in priority.

> 
>> +  return (handler
>> +	  && handler.fold_range (*dst_vr, dst_type,
>> +				 *src_vr, value_range (dst_type))
>> +	  && !dst_vr->varying_p ()
>> +	  && !dst_vr->undefined_p ());
> 
> It looks important but the class is not documented at all.  Although the
> use of fold_range is probably hopefully mostly clear from its uses in
> this patch, the meaning of the return value of this method and what
> other methods do is less obvious.
> 
> For example, I am curious why (not in this patch, but in the code as it
> is now in the repo), uses of fold_range seem to be always preceeded with
> a check for supports_type_p, even though the type is then also fed into
> fold_range itself.  Does the return value of fold_range mean something
> slightly different from "could not deduce anything?"

Returning false from fold_range() is a shortcut for I don't know 
anything, which will be treated as VARYING upstream.

The other methods also need documentation.  The most important ones are 
documented in range-op.h:

// This class is implemented for each kind of operator supported by
// the range generator.  It serves various purposes.

particularly op1_range, and op2_range which can be confusing.  But yes, 
we need to revisit this, as those comments are pretty out of date.

Aldy


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [COMMITTED] Remove deprecated range_fold_{unary, binary}_expr uses from ipa-*.
  2023-05-05 15:10   ` [COMMITTED] Remove deprecated range_fold_{unary, binary}_expr " Martin Jambor
  2023-05-11  9:58     ` Aldy Hernandez
@ 2023-05-15 17:33     ` Aldy Hernandez
  1 sibling, 0 replies; 12+ messages in thread
From: Aldy Hernandez @ 2023-05-15 17:33 UTC (permalink / raw)
  To: Martin Jambor, GCC patches; +Cc: Andrew MacLeod



On 5/5/23 17:10, Martin Jambor wrote:
> Hello,
> 
> On Wed, Apr 26 2023, Aldy Hernandez via Gcc-patches wrote:
>> gcc/ChangeLog:
>>
>> 	* ipa-cp.cc (ipa_vr_operation_and_type_effects): Convert to ranger API.
>> 	(ipa_value_range_from_jfunc): Same.
>> 	(propagate_vr_across_jump_function): Same.
>> 	* ipa-fnsummary.cc (evaluate_conditions_for_known_args): Same.
>> 	* ipa-prop.cc (ipa_compute_jump_functions_for_edge): Same.
>> 	* vr-values.cc (bounds_of_var_in_loop): Same.
> 
> thanks for taking care of the value range uses in IPA.
> 
>> ---
>>   gcc/ipa-cp.cc        | 28 +++++++++++++++++++++------
>>   gcc/ipa-fnsummary.cc | 45 ++++++++++++++++++++++++++++----------------
>>   gcc/ipa-prop.cc      |  5 ++---
>>   gcc/vr-values.cc     |  6 ++++--
>>   4 files changed, 57 insertions(+), 27 deletions(-)
>>
>> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
>> index 65c49558b58..6788883c40b 100644
>> --- a/gcc/ipa-cp.cc
>> +++ b/gcc/ipa-cp.cc
>> @@ -128,6 +128,7 @@ along with GCC; see the file COPYING3.  If not see
>>   #include "attribs.h"
>>   #include "dbgcnt.h"
>>   #include "symtab-clones.h"
>> +#include "gimple-range.h"
>>   
>>   template <typename valtype> class ipcp_value;
>>   
>> @@ -1900,10 +1901,15 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr,
>>   				   enum tree_code operation,
>>   				   tree dst_type, tree src_type)
>>   {
>> -  range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
>> -  if (dst_vr->varying_p () || dst_vr->undefined_p ())
>> +  if (!irange::supports_p (dst_type) || !irange::supports_p (src_type))
>>       return false;
>> -  return true;
>> +
>> +  range_op_handler handler (operation, dst_type);
> 
> Would it be possible to document the range_op_handler class somewhat?
> 
>> +  return (handler
>> +	  && handler.fold_range (*dst_vr, dst_type,
>> +				 *src_vr, value_range (dst_type))
>> +	  && !dst_vr->varying_p ()
>> +	  && !dst_vr->undefined_p ());
> 
> It looks important but the class is not documented at all.  Although the
> use of fold_range is probably hopefully mostly clear from its uses in
> this patch, the meaning of the return value of this method and what
> other methods do is less obvious.
> 
> For example, I am curious why (not in this patch, but in the code as it
> is now in the repo), uses of fold_range seem to be always preceeded with
> a check for supports_type_p, even though the type is then also fed into
> fold_range itself.  Does the return value of fold_range mean something
> slightly different from "could not deduce anything?"

Oh, I see what you mean.

Take for instance this bit in ipa-cp:

   if (!irange::supports_p (dst_type) || !irange::supports_p (src_type))
     return false;

   range_op_handler handler (operation, dst_type);
   return (handler
	  && handler.fold_range (*dst_vr, dst_type,
				 *src_vr, value_range (dst_type))
	  && !dst_vr->varying_p ()
	  && !dst_vr->undefined_p ());

range_op_handler::fold_range() takes a type agnostic vrange (from which 
irange inherits).  If you pass it an irange, but the type is say a 
float, you'll get an ICE downstream.

Ranger itself is type agnostic and takes a vrange almost everywhere. 
It's up to the user to make sure the the range type and the type of the 
operation matches.

Eventually we should convert all those value_range arguments in IPA to 
vrange and have it work in a type agnostic manner.  I have patches for 
this, but I still have to flush out all this preliminary stuff :).

Aldy


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-05-15 17:33 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-26  8:33 [COMMITTED] Remove compare_names* from legacy cond folding Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Refactor vrp_evaluate_conditional* and rename it Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Remove range_query::get_value_range Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Remove deprecated range_fold_{unary,binary}_expr uses from ipa-* Aldy Hernandez
2023-05-05 15:10   ` [COMMITTED] Remove deprecated range_fold_{unary, binary}_expr " Martin Jambor
2023-05-11  9:58     ` Aldy Hernandez
2023-05-15 17:33     ` Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Remove range_fold_{unary,binary}_expr Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Remove irange::may_contain_p Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Remove symbolics from irange Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Remove irange::constant_p Aldy Hernandez
2023-04-26  8:33 ` [COMMITTED] Convert users of legacy API to get_legacy_range() function Aldy Hernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).