diff mbox series

[COMMITTED] Replace vrp_val* with wide_ints.

Message ID 20230501062906.564803-8-aldyh@redhat.com
State New
Headers show
Series [COMMITTED] Replace vrp_val* with wide_ints. | expand

Commit Message

Aldy Hernandez May 1, 2023, 6:29 a.m. UTC
This patch removes all uses of vrp_val_{min,max} in favor for a
irange_val_* which are wide_int based.  This will leave only one use
of vrp_val_* which returns trees in range_of_ssa_name_with_loop_info()
because it needs to work with non-integers (floats, etc).  In a
follow-up patch, this function will also be cleaned up such that
vrp_val_* can be deleted.

The functions min_limit and max_limit in range-op.cc are now useless
as they're basically irange_val*.  I didn't rename them yet to avoid
churn.  I'll do it in a later patch.

gcc/ChangeLog:

	* gimple-range-fold.cc (adjust_pointer_diff_expr): Rewrite with
	irange_val*.
	(vrp_val_max): New.
	(vrp_val_min): New.
	* gimple-range-op.cc (cfn_strlen::fold_range): Use irange_val_*.
	* range-op.cc (max_limit): Same.
	(min_limit): Same.
	(plus_minus_ranges): Same.
	(operator_rshift::op1_range): Same.
	(operator_cast::inside_domain_p): Same.
	* value-range.cc (vrp_val_is_max): Delete.
	(vrp_val_is_min): Delete.
	(range_tests_misc): Use irange_val_*.
	* value-range.h (vrp_val_is_min): Delete.
	(vrp_val_is_max): Delete.
	(vrp_val_max): Delete.
	(irange_val_min): New.
	(vrp_val_min): Delete.
	(irange_val_max): New.
	* vr-values.cc (check_for_binary_op_overflow): Use irange_val_*.
---
 gcc/gimple-range-fold.cc | 40 +++++++++++++++++++++++++++++----
 gcc/gimple-range-op.cc   |  8 +++----
 gcc/range-op.cc          | 19 +++++++---------
 gcc/value-range.cc       | 37 +++++--------------------------
 gcc/value-range.h        | 41 +++++++---------------------------
 gcc/vr-values.cc         | 48 ++++++++++++++--------------------------
 6 files changed, 78 insertions(+), 115 deletions(-)
diff mbox series

Patch

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 62875a35038..1b76e6e02a3 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -360,10 +360,10 @@  adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt)
       && vrp_operand_equal_p (op1, gimple_call_arg (call, 0))
       && integer_zerop (gimple_call_arg (call, 1)))
     {
-      tree max = vrp_val_max (ptrdiff_type_node);
-      unsigned prec = TYPE_PRECISION (TREE_TYPE (max));
-      wide_int wmaxm1 = wi::to_wide (max, prec) - 1;
-      res.intersect (int_range<2> (TREE_TYPE (max), wi::zero (prec), wmaxm1));
+      wide_int maxm1 = irange_val_max (ptrdiff_type_node) - 1;
+      res.intersect (int_range<2> (ptrdiff_type_node,
+				   wi::zero (TYPE_PRECISION (ptrdiff_type_node)),
+				   maxm1));
     }
 }
 
@@ -966,6 +966,38 @@  tree_upper_bound (const vrange &r, tree type)
   return NULL;
 }
 
+// Return the maximum value for TYPE.
+
+static inline tree
+vrp_val_max (const_tree type)
+{
+  if (INTEGRAL_TYPE_P (type)
+      || POINTER_TYPE_P (type))
+    return wide_int_to_tree (const_cast <tree> (type), irange_val_max (type));
+  if (frange::supports_p (type))
+    {
+      REAL_VALUE_TYPE r = frange_val_max (type);
+      return build_real (const_cast <tree> (type), r);
+    }
+  return NULL_TREE;
+}
+
+// Return the minimum value for TYPE.
+
+static inline tree
+vrp_val_min (const_tree type)
+{
+  if (INTEGRAL_TYPE_P (type)
+      || POINTER_TYPE_P (type))
+    return wide_int_to_tree (const_cast <tree> (type), irange_val_min (type));
+  if (frange::supports_p (type))
+    {
+      REAL_VALUE_TYPE r = frange_val_min (type);
+      return build_real (const_cast <tree> (type), r);
+    }
+  return NULL_TREE;
+}
+
 // If SCEV has any information about phi node NAME, return it as a range in R.
 
 void
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index 29c7c776a2c..3aef8357d8d 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -900,15 +900,13 @@  public:
   virtual bool fold_range (irange &r, tree type, const irange &,
 			   const irange &, relation_trio) const
   {
-    tree max = vrp_val_max (ptrdiff_type_node);
-    wide_int wmax
-      = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
+    wide_int max = irange_val_max (ptrdiff_type_node);
     // To account for the terminating NULL, the maximum length
     // is one less than the maximum array size, which in turn
     // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
     // smaller than the former type).
     // FIXME: Use max_object_size() - 1 here.
-    r.set (type, wi::zero (TYPE_PRECISION (type)), wmax - 2);
+    r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2);
     return true;
   }
 } op_cfn_strlen;
@@ -936,7 +934,7 @@  public:
 	   wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)),
 	   size
 	   ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type))
-	   : wi::to_wide (vrp_val_max (type)));
+	   : irange_val_max (type));
     return true;
   }
 private:
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 224a561c170..fc0eef998e4 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -97,7 +97,7 @@  update_known_bitmask (irange &r, tree_code code,
 static inline wide_int
 max_limit (const_tree type)
 {
-  return wi::max_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
+  return irange_val_max (type);
 }
 
 // Return the lower limit for a type.
@@ -105,7 +105,7 @@  max_limit (const_tree type)
 static inline wide_int
 min_limit (const_tree type)
 {
-  return wi::min_value (TYPE_PRECISION (type) , TYPE_SIGN (type));
+  return irange_val_min (type);
 }
 
 // Return false if shifting by OP is undefined behavior.  Otherwise, return
@@ -1463,14 +1463,14 @@  plus_minus_ranges (irange &r_ov, irange &r_normal, const irange &offset,
     {
       //  [ 0 , INF - OFF]
       lb = wi::zero (prec);
-      ub = wi::sub (wi::to_wide (vrp_val_max (type)), off, UNSIGNED, &ov);
+      ub = wi::sub (irange_val_max (type), off, UNSIGNED, &ov);
       kind = VREL_GT;
     }
   else
     {
       //  [ OFF, INF ]
       lb = off;
-      ub = wi::to_wide (vrp_val_max (type));
+      ub = irange_val_max (type);
       kind = VREL_LT;
     }
   int_range<2> normal_range (type, lb, ub);
@@ -2594,13 +2594,10 @@  operator_rshift::op1_range (irange &r,
       // OP1 is anything from 0011 1000 to 0011 1111.  That is, a
       // range from LHS<<3 plus a mask of the 3 bits we shifted on the
       // right hand side (0x07).
-      tree mask = fold_build1 (BIT_NOT_EXPR, type,
-			       fold_build2 (LSHIFT_EXPR, type,
-					    build_minus_one_cst (type),
-					    wide_int_to_tree (op2.type (), shift)));
+      wide_int mask = wi::bit_not (wi::lshift (wi::minus_one (prec), shift));
       int_range_max mask_range (type,
 				wi::zero (TYPE_PRECISION (type)),
-				wi::to_wide (mask));
+				mask);
       op_plus.fold_range (ub, type, lb, mask_range);
       r = lb;
       r.union_ (ub);
@@ -2731,8 +2728,8 @@  operator_cast::inside_domain_p (const wide_int &min,
 				const wide_int &max,
 				const irange &range) const
 {
-  wide_int domain_min = wi::to_wide (vrp_val_min (range.type ()));
-  wide_int domain_max = wi::to_wide (vrp_val_max (range.type ()));
+  wide_int domain_min = irange_val_min (range.type ());
+  wide_int domain_max = irange_val_max (range.type ());
   signop domain_sign = TYPE_SIGN (range.type ());
   return (wi::le_p (min, domain_max, domain_sign)
 	  && wi::le_p (max, domain_max, domain_sign)
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index f2148722a3a..cf694ccaa28 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1990,31 +1990,6 @@  debug (const value_range &vr)
   fprintf (stderr, "\n");
 }
 
-/* Return whether VAL is equal to the maximum value of its type.
-   We can't do a simple equality comparison with TYPE_MAX_VALUE because
-   C typedefs and Ada subtypes can produce types whose TYPE_MAX_VALUE
-   is not == to the integer constant with the same value in the type.  */
-
-bool
-vrp_val_is_max (const_tree val)
-{
-  tree type_max = vrp_val_max (TREE_TYPE (val));
-  return (val == type_max
-	  || (type_max != NULL_TREE
-	      && operand_equal_p (val, type_max, 0)));
-}
-
-/* Return whether VAL is equal to the minimum value of its type.  */
-
-bool
-vrp_val_is_min (const_tree val)
-{
-  tree type_min = vrp_val_min (TREE_TYPE (val));
-  return (val == type_min
-	  || (type_min != NULL_TREE
-	      && operand_equal_p (val, type_min, 0)));
-}
-
 /* Return true, if VAL1 and VAL2 are equal values for VRP purposes.  */
 
 bool
@@ -2369,11 +2344,11 @@  range_tests_misc ()
   // Test 1-bit signed integer union.
   // [-1,-1] U [0,0] = VARYING.
   tree one_bit_type = build_nonstandard_integer_type (1, 0);
-  tree one_bit_min = vrp_val_min (one_bit_type);
-  tree one_bit_max = vrp_val_max (one_bit_type);
+  wide_int one_bit_min = irange_val_min (one_bit_type);
+  wide_int one_bit_max = irange_val_max (one_bit_type);
   {
-    int_range<2> min = tree_range (one_bit_min, one_bit_min);
-    int_range<2> max = tree_range (one_bit_max, one_bit_max);
+    int_range<2> min = int_range<2> (one_bit_type, one_bit_min, one_bit_min);
+    int_range<2> max = int_range<2> (one_bit_type, one_bit_max, one_bit_max);
     max.union_ (min);
     ASSERT_TRUE (max.varying_p ());
   }
@@ -2382,8 +2357,8 @@  range_tests_misc ()
 
   // Test inversion of 1-bit signed integers.
   {
-    int_range<2> min = tree_range (one_bit_min, one_bit_min);
-    int_range<2> max = tree_range (one_bit_max, one_bit_max);
+    int_range<2> min = int_range<2> (one_bit_type, one_bit_min, one_bit_min);
+    int_range<2> max = int_range<2> (one_bit_type, one_bit_max, one_bit_max);
     int_range<2> t;
     t = min;
     t.invert ();
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 633a234d41f..b040e2f254f 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -635,8 +635,6 @@  Value_Range::supports_type_p (const_tree type)
 
 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);
 extern bool vrp_operand_equal_p (const_tree, const_tree);
 inline REAL_VALUE_TYPE frange_val_min (const_tree type);
 inline REAL_VALUE_TYPE frange_val_max (const_tree type);
@@ -952,41 +950,18 @@  contains_zero_p (const irange &r)
   return r.contains_p (zero);
 }
 
-// Return the maximum value for TYPE.
-
-inline tree
-vrp_val_max (const_tree type)
+inline wide_int
+irange_val_min (const_tree type)
 {
-  if (INTEGRAL_TYPE_P (type))
-    return TYPE_MAX_VALUE (type);
-  if (POINTER_TYPE_P (type))
-    {
-      wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
-      return wide_int_to_tree (const_cast<tree> (type), max);
-    }
-  if (frange::supports_p (type))
-    {
-      REAL_VALUE_TYPE r = frange_val_max (type);
-      return build_real (const_cast <tree> (type), r);
-    }
-  return NULL_TREE;
+  gcc_checking_assert (irange::supports_p (type));
+  return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
 }
 
-// Return the minimum value for TYPE.
-
-inline tree
-vrp_val_min (const_tree type)
+inline wide_int
+irange_val_max (const_tree type)
 {
-  if (INTEGRAL_TYPE_P (type))
-    return TYPE_MIN_VALUE (type);
-  if (POINTER_TYPE_P (type))
-    return build_zero_cst (const_cast<tree> (type));
-  if (frange::supports_p (type))
-    {
-      REAL_VALUE_TYPE r = frange_val_min (type);
-      return build_real (const_cast <tree> (type), r);
-    }
-  return NULL_TREE;
+  gcc_checking_assert (irange::supports_p (type));
+  return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
 }
 
 inline
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 49ae324419a..31df6b85ce6 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -103,34 +103,16 @@  check_for_binary_op_overflow (range_query *query,
 			      tree op0, tree op1, bool *ovf, gimple *s = NULL)
 {
   value_range vr0, vr1;
-  if (!query->range_of_expr (vr0, op0, s))
+  if (!query->range_of_expr (vr0, op0, s) || vr0.undefined_p ())
     vr0.set_varying (TREE_TYPE (op0));
-  if (!query->range_of_expr (vr1, op1, s))
+  if (!query->range_of_expr (vr1, op1, s) || vr1.undefined_p ())
     vr1.set_varying (TREE_TYPE (op1));
 
-  tree vr0min, vr0max, vr1min, vr1max;
-  if (vr0.undefined_p () || vr0.varying_p ())
-    {
-      vr0min = vrp_val_min (TREE_TYPE (op0));
-      vr0max = vrp_val_max (TREE_TYPE (op0));
-    }
-  else
-    {
-      tree type = vr0.type ();
-      vr0min = wide_int_to_tree (type, vr0.lower_bound ());
-      vr0max = wide_int_to_tree (type, vr0.upper_bound ());
-    }
-  if (vr1.undefined_p () || vr1.varying_p ())
-    {
-      vr1min = vrp_val_min (TREE_TYPE (op1));
-      vr1max = vrp_val_max (TREE_TYPE (op1));
-    }
-  else
-    {
-      tree type = vr1.type ();
-      vr1min = wide_int_to_tree (type, vr1.lower_bound ());
-      vr1max = wide_int_to_tree (type, vr1.upper_bound ());
-    }
+  tree vr0min = wide_int_to_tree (TREE_TYPE (op0), vr0.lower_bound ());
+  tree vr0max = wide_int_to_tree (TREE_TYPE (op0), vr0.upper_bound ());
+  tree vr1min = wide_int_to_tree (TREE_TYPE (op1), vr1.lower_bound ());
+  tree vr1max = wide_int_to_tree (TREE_TYPE (op1), vr1.upper_bound ());
+
   *ovf = arith_overflowed_p (subcode, type, vr0min,
 			     subcode == MINUS_EXPR ? vr1max : vr1min);
   if (arith_overflowed_p (subcode, type, vr0max,
@@ -152,10 +134,12 @@  check_for_binary_op_overflow (range_query *query,
       widest_int wmin, wmax;
       widest_int w[4];
       int i;
-      w[0] = wi::to_widest (vr0min);
-      w[1] = wi::to_widest (vr0max);
-      w[2] = wi::to_widest (vr1min);
-      w[3] = wi::to_widest (vr1max);
+      signop sign0 = TYPE_SIGN (TREE_TYPE (op0));
+      signop sign1 = TYPE_SIGN (TREE_TYPE (op1));
+      w[0] = widest_int::from (vr0.lower_bound (), sign0);
+      w[1] = widest_int::from (vr0.upper_bound (), sign0);
+      w[2] = widest_int::from (vr1.lower_bound (), sign1);
+      w[3] = widest_int::from (vr1.upper_bound (), sign1);
       for (i = 0; i < 4; i++)
 	{
 	  widest_int wt;
@@ -186,8 +170,10 @@  check_for_binary_op_overflow (range_query *query,
 	}
       /* The result of op0 CODE op1 is known to be in range
 	 [wmin, wmax].  */
-      widest_int wtmin = wi::to_widest (vrp_val_min (type));
-      widest_int wtmax = wi::to_widest (vrp_val_max (type));
+      widest_int wtmin
+	= widest_int::from (irange_val_min (type), TYPE_SIGN (type));
+      widest_int wtmax
+	= widest_int::from (irange_val_max (type), TYPE_SIGN (type));
       /* If all values in [wmin, wmax] are smaller than
 	 [wtmin, wtmax] or all are larger than [wtmin, wtmax],
 	 the arithmetic operation will always overflow.  */