[COMMITTED] Use range_compatible_p in check_operands_p.

Message ID 6899d17b-14c3-4ce4-b2bf-ed11afce1e01@redhat.com
State Committed
Headers
Series [COMMITTED] Use range_compatible_p in check_operands_p. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 warning Patch is already merged
linaro-tcwg-bot/tcwg_gcc_check--master-arm warning Patch is already merged

Commit Message

Andrew MacLeod Dec. 1, 2023, 7:13 p.m. UTC
  Comments in PR 112788 correctly brought up that the new 
check_operands_p() routine is directly checking precision rather than 
calling range_compatible_p().

Most earlier iterations of the original patch had ranges as arguments, 
and it wasn't primarily a CHECKING_P only call then...   Regardless, it 
makes total sense to call range_compatible_p so this patch does exactly 
that.  It required moving range_compatible_p() into value-range.h and 
then adjusting each check_operands_p() routine.

Now range type compatibility is centralized again :-P

Bootstraps on x86_64-pc-linux-gnu with no new regressions.

Andrew
  

Patch

From c6bb413eeb9d13412e8101e3029099d7fd746708 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Fri, 1 Dec 2023 11:15:33 -0500
Subject: [PATCH] Use range_compatible_p in check_operands_p.

Instead of directly checking type precision, check_operands_p should
invoke range_compatible_p to keep the range checking centralized.

	* gimple-range-fold.h (range_compatible_p): Relocate.
	* value-range.h (range_compatible_p): Here.
	* range-op-mixed.h (operand_equal::operand_check_p): Call
	range_compatible_p rather than comparing precision.
	(operand_not_equal::operand_check_p): Ditto.
	(operand_not_lt::operand_check_p): Ditto.
	(operand_not_le::operand_check_p): Ditto.
	(operand_not_gt::operand_check_p): Ditto.
	(operand_not_ge::operand_check_p): Ditto.
	(operand_plus::operand_check_p): Ditto.
	(operand_abs::operand_check_p): Ditto.
	(operand_minus::operand_check_p): Ditto.
	(operand_negate::operand_check_p): Ditto.
	(operand_mult::operand_check_p): Ditto.
	(operand_bitwise_not::operand_check_p): Ditto.
	(operand_bitwise_xor::operand_check_p): Ditto.
	(operand_bitwise_and::operand_check_p): Ditto.
	(operand_bitwise_or::operand_check_p): Ditto.
	(operand_min::operand_check_p): Ditto.
	(operand_max::operand_check_p): Ditto.
	* range-op.cc (operand_lshift::operand_check_p): Ditto.
	(operand_rshift::operand_check_p): Ditto.
	(operand_logical_and::operand_check_p): Ditto.
	(operand_logical_or::operand_check_p): Ditto.
	(operand_logical_not::operand_check_p): Ditto.
---
 gcc/gimple-range-fold.h | 12 ------------
 gcc/range-op-mixed.h    | 43 ++++++++++++++++-------------------------
 gcc/range-op.cc         | 12 +++++-------
 gcc/value-range.h       | 11 +++++++++++
 4 files changed, 33 insertions(+), 45 deletions(-)

diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index fcbe1626790..0094b4e3f35 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -89,18 +89,6 @@  gimple_range_ssa_p (tree exp)
   return NULL_TREE;
 }
 
-// Return true if TYPE1 and TYPE2 are compatible range types.
-
-inline bool
-range_compatible_p (tree type1, tree type2)
-{
-  // types_compatible_p requires conversion in both directions to be useless.
-  // GIMPLE only requires a cast one way in order to be compatible.
-  // Ranges really only need the sign and precision to be the same.
-  return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
-	  && TYPE_SIGN (type1) == TYPE_SIGN (type2));
-}
-
 // Source of all operands for fold_using_range and gori_compute.
 // It abstracts out the source of an operand so it can come from a stmt or
 // and edge or anywhere a derived class of fur_source wants.
diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h
index 4386a68e946..7e3ee17ccbd 100644
--- a/gcc/range-op-mixed.h
+++ b/gcc/range-op-mixed.h
@@ -140,7 +140,7 @@  public:
 		       const irange &rh) const final override;
   // Check op1 and op2 for compatibility.
   bool operand_check_p (tree, tree t1, tree t2) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 };
 
 class operator_not_equal : public range_operator
@@ -179,7 +179,7 @@  public:
 		       const irange &rh) const final override;
   // Check op1 and op2 for compatibility.
   bool operand_check_p (tree, tree t1, tree t2) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 };
 
 class operator_lt :  public range_operator
@@ -215,7 +215,7 @@  public:
 		       const irange &rh) const final override;
   // Check op1 and op2 for compatibility.
   bool operand_check_p (tree, tree t1, tree t2) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 };
 
 class operator_le :  public range_operator
@@ -254,7 +254,7 @@  public:
 		       const irange &rh) const final override;
   // Check op1 and op2 for compatibility.
   bool operand_check_p (tree, tree t1, tree t2) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 };
 
 class operator_gt :  public range_operator
@@ -292,7 +292,7 @@  public:
 		       const irange &rh) const final override;
   // Check op1 and op2 for compatibility.
   bool operand_check_p (tree, tree t1, tree t2) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 };
 
 class operator_ge :  public range_operator
@@ -331,7 +331,7 @@  public:
 		       const irange &rh) const final override;
   // Check op1 and op2 for compatibility.
   bool operand_check_p (tree, tree t1, tree t2) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 };
 
 class operator_identity : public range_operator
@@ -429,8 +429,7 @@  public:
 				relation_trio = TRIO_VARYING) const;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 private:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
@@ -459,7 +458,7 @@  class operator_abs : public range_operator
 		       const irange &rh) const final override;
   // Check compatibility of LHS and op1.
   bool operand_check_p (tree t1, tree t2, tree) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 private:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
@@ -503,8 +502,7 @@  public:
 				relation_trio = TRIO_VARYING) const;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 private:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
@@ -535,7 +533,7 @@  class operator_negate : public range_operator
 		  relation_trio rel = TRIO_VARYING) const final override;
   // Check compatibility of LHS and op1.
   bool operand_check_p (tree t1, tree t2, tree) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 };
 
 
@@ -589,8 +587,7 @@  public:
 				relation_trio = TRIO_VARYING) const;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 };
 
 class operator_addr_expr : public range_operator
@@ -621,8 +618,7 @@  public:
 		       const irange &rh) const final override;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 };
 
 class operator_bitwise_xor : public range_operator
@@ -645,8 +641,7 @@  public:
 		       const irange &rh) const final override;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 private:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
@@ -672,8 +667,7 @@  public:
 		       const irange &rh) const override;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 protected:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
@@ -698,8 +692,7 @@  public:
 		       const irange &rh) const override;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 protected:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
@@ -713,8 +706,7 @@  public:
 		       const irange &rh) const override;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 protected:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
@@ -728,8 +720,7 @@  public:
       const irange &rh) const override;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 protected:
   void wi_fold (irange &r, tree type, const wide_int &lh_lb,
 		const wide_int &lh_ub, const wide_int &rh_lb,
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index a091815997d..5dbc4bbb42e 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2493,7 +2493,7 @@  public:
     { update_known_bitmask (r, LSHIFT_EXPR, lh, rh); }
   // Check compatibility of LHS and op1.
   bool operand_check_p (tree t1, tree t2, tree) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 } op_lshift;
 
 class operator_rshift : public cross_product_operator
@@ -2525,7 +2525,7 @@  public:
     { update_known_bitmask (r, RSHIFT_EXPR, lh, rh); }
   // Check compatibility of LHS and op1.
   bool operand_check_p (tree t1, tree t2, tree) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 } op_rshift;
 
 
@@ -3103,8 +3103,7 @@  public:
 			  relation_trio rel = TRIO_VARYING) const;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 } op_logical_and;
 
 bool
@@ -3608,8 +3607,7 @@  public:
 			  relation_trio rel = TRIO_VARYING) const;
   // Check compatibility of all operands.
   bool operand_check_p (tree t1, tree t2, tree t3) const final override
-    { return (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
-	      && TYPE_PRECISION (t1) == TYPE_PRECISION (t3)); }
+    { return range_compatible_p (t1, t2) && range_compatible_p (t1, t3); }
 } op_logical_or;
 
 bool
@@ -4038,7 +4036,7 @@  public:
 			  relation_trio rel = TRIO_VARYING) const;
   // Check compatibility of LHS and op1.
   bool operand_check_p (tree t1, tree t2, tree) const final override
-    { return TYPE_PRECISION (t1) == TYPE_PRECISION (t2); }
+    { return range_compatible_p (t1, t2); }
 } op_logical_not;
 
 // Folding a logical NOT, oddly enough, involves doing nothing on the
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 330e6f70c6b..33f204a7171 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -1550,4 +1550,15 @@  void frange_arithmetic (enum tree_code, tree, REAL_VALUE_TYPE &,
 			const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
 			const REAL_VALUE_TYPE &);
 
+// Return true if TYPE1 and TYPE2 are compatible range types.
+
+inline bool
+range_compatible_p (tree type1, tree type2)
+{
+  // types_compatible_p requires conversion in both directions to be useless.
+  // GIMPLE only requires a cast one way in order to be compatible.
+  // Ranges really only need the sign and precision to be the same.
+  return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
+	  && TYPE_SIGN (type1) == TYPE_SIGN (type2));
+}
 #endif // GCC_VALUE_RANGE_H
-- 
2.41.0