public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-438] Add relation between op1 & op2 to lhs_opN_relation API.
@ 2022-05-13 14:21 Andrew Macleod
  0 siblings, 0 replies; only message in thread
From: Andrew Macleod @ 2022-05-13 14:21 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:cf2141a0c640fc9b1c497db3f4d5b270f4b8252a

commit r13-438-gcf2141a0c640fc9b1c497db3f4d5b270f4b8252a
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Tue Feb 15 10:17:26 2022 -0500

    Add relation between op1 & op2 to lhs_opN_relation API.
    
    We use the relation between op1 and op2 to help fold a statement, but
    it was not provided to the lhs_op1_relation and lhs_op2_relation routines
    to determine if is also creates a relation between the LHS and either operand.
    
            gcc/
            PR tree-optimization/104547
            * gimple-range-fold.cc (fold_using_range::range_of_range_op): Add
            the op1/op2 relation to the relation call.
            * range-op.cc (*::lhs_op1_relation): Add param.
            (*::lhs_op2_relation): Ditto.
            (operator_minus::lhs_op1_relation): New.
            (range_relational_tests): Add relation param.
            * range-op.h (lhs_op1_relation, lhs_op2_relation): Adjust prototype.
    
            gcc/testsuite/
            * g++.dg/pr104547.C: New.

Diff:
---
 gcc/gimple-range-fold.cc        |  4 +--
 gcc/range-op.cc                 | 62 +++++++++++++++++++++++++++++++----------
 gcc/range-op.h                  |  7 +++--
 gcc/testsuite/g++.dg/pr104547.C | 13 +++++++++
 4 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 08d791a0418..bc8174e15e6 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -640,13 +640,13 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
 		}
 	      if (gimple_range_ssa_p (op1))
 		{
-		  rel = handler->lhs_op1_relation (r, range1, range2);
+		  rel = handler->lhs_op1_relation (r, range1, range2, rel);
 		  if (rel != VREL_NONE)
 		    src.register_relation (s, rel, lhs, op1);
 		}
 	      if (gimple_range_ssa_p (op2))
 		{
-		  rel= handler->lhs_op2_relation (r, range1, range2);
+		  rel= handler->lhs_op2_relation (r, range1, range2, rel);
 		  if (rel != VREL_NONE)
 		    src.register_relation (s, rel, lhs, op2);
 		}
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index eaa02309d70..d015b9f1363 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -249,7 +249,8 @@ range_operator::op2_range (irange &r ATTRIBUTE_UNUSED,
 enum tree_code
 range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
 				  const irange &op1 ATTRIBUTE_UNUSED,
-				  const irange &op2 ATTRIBUTE_UNUSED) const
+				  const irange &op2 ATTRIBUTE_UNUSED,
+				  relation_kind rel ATTRIBUTE_UNUSED) const
 {
   return VREL_NONE;
 }
@@ -257,7 +258,8 @@ range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
 enum tree_code
 range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
 				  const irange &op1 ATTRIBUTE_UNUSED,
-				  const irange &op2 ATTRIBUTE_UNUSED) const
+				  const irange &op2 ATTRIBUTE_UNUSED,
+				  relation_kind rel ATTRIBUTE_UNUSED) const
 {
   return VREL_NONE;
 }
@@ -1182,9 +1184,11 @@ public:
 		        const wide_int &rh_lb,
 		        const wide_int &rh_ub) const;
   virtual enum tree_code lhs_op1_relation (const irange &lhs, const irange &op1,
-					   const irange &op2) const;
+					   const irange &op2,
+					   relation_kind rel) const;
   virtual enum tree_code lhs_op2_relation (const irange &lhs, const irange &op1,
-					   const irange &op2) const;
+					   const irange &op2,
+					   relation_kind rel) const;
 } op_plus;
 
 // Check to see if the range of OP2 indicates anything about the relation
@@ -1193,7 +1197,8 @@ public:
 enum tree_code
 operator_plus::lhs_op1_relation (const irange &lhs,
 				 const irange &op1,
-				 const irange &op2) const
+				 const irange &op2,
+				 relation_kind) const
 {
   if (lhs.undefined_p () || op1.undefined_p () || op2.undefined_p ())
     return VREL_NONE;
@@ -1258,9 +1263,9 @@ operator_plus::lhs_op1_relation (const irange &lhs,
 
 enum tree_code
 operator_plus::lhs_op2_relation (const irange &lhs, const irange &op1,
-				 const irange &op2) const
+				 const irange &op2, relation_kind rel) const
 {
-  return lhs_op1_relation (lhs, op2, op1);
+  return lhs_op1_relation (lhs, op2, op1, rel);
 }
 
 void
@@ -1310,6 +1315,10 @@ public:
 		        const wide_int &lh_ub,
 		        const wide_int &rh_lb,
 		        const wide_int &rh_ub) const;
+  virtual enum tree_code lhs_op1_relation (const irange &lhs,
+					   const irange &op1,
+					   const irange &op2,
+					   relation_kind rel) const;
   virtual bool op1_op2_relation_effect (irange &lhs_range,
 					tree type,
 					const irange &op1_range,
@@ -1329,6 +1338,27 @@ operator_minus::wi_fold (irange &r, tree type,
   value_range_with_overflow (r, type, new_lb, new_ub, ov_lb, ov_ub);
 }
 
+
+// Return the relation between LHS and OP1 based on the relation between
+// OP1 and OP2.
+
+enum tree_code
+operator_minus::lhs_op1_relation (const irange &lhs, const irange &,
+				  const irange &, relation_kind rel) const
+{
+  if (TYPE_SIGN (lhs.type ()) == UNSIGNED)
+    switch (rel)
+      {
+      case GT_EXPR:
+	return LT_EXPR;
+      case GE_EXPR:
+	return LE_EXPR;
+      default:
+	break;
+      }
+  return VREL_NONE;
+}
+
 // Check to see if the relation REL between OP1 and OP2 has any effect on the
 // LHS of the expression.  If so, apply it to LHS_RANGE.  This is a helper
 // function for both MINUS_EXPR and POINTER_DIFF_EXPR.
@@ -1899,14 +1929,16 @@ public:
 			  relation_kind rel = VREL_NONE) const;
   virtual enum tree_code lhs_op1_relation (const irange &lhs,
 					   const irange &op1,
-					   const irange &op2) const;
+					   const irange &op2,
+					   relation_kind rel) const;
 } op_rshift;
 
 
 enum tree_code
 operator_rshift::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
 				   const irange &op1,
-				   const irange &op2) const
+				   const irange &op2,
+				   relation_kind) const
 {
   // If both operands range are >= 0, then the LHS <= op1.
   if (!op1.undefined_p () && !op2.undefined_p ()
@@ -3532,7 +3564,8 @@ public:
 			  relation_kind rel = VREL_NONE) const;
   virtual enum tree_code lhs_op1_relation (const irange &lhs,
 					   const irange &op1,
-					   const irange &op2) const;
+					   const irange &op2,
+					   relation_kind rel) const;
 } op_identity;
 
 // Determine if there is a relationship between LHS and OP1.
@@ -3540,7 +3573,8 @@ public:
 enum tree_code
 operator_identity::lhs_op1_relation (const irange &lhs,
 				     const irange &op1 ATTRIBUTE_UNUSED,
-				     const irange &op2 ATTRIBUTE_UNUSED) const
+				     const irange &op2 ATTRIBUTE_UNUSED,
+				     relation_kind) const
 {
   if (lhs.undefined_p ())
     return VREL_NONE;
@@ -4427,19 +4461,19 @@ range_relational_tests ()
   int_range<2> op2 (UCHAR (20), UCHAR (20));
 
   // Never wrapping additions mean LHS > OP1.
-  tree_code code = op_plus.lhs_op1_relation (lhs, op1, op2);
+  tree_code code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE);
   ASSERT_TRUE (code == GT_EXPR);
 
   // Most wrapping additions mean nothing...
   op1 = int_range<2> (UCHAR (8), UCHAR (10));
   op2 = int_range<2> (UCHAR (0), UCHAR (255));
-  code = op_plus.lhs_op1_relation (lhs, op1, op2);
+  code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE);
   ASSERT_TRUE (code == VREL_NONE);
 
   // However, always wrapping additions mean LHS < OP1.
   op1 = int_range<2> (UCHAR (1), UCHAR (255));
   op2 = int_range<2> (UCHAR (255), UCHAR (255));
-  code = op_plus.lhs_op1_relation (lhs, op1, op2);
+  code = op_plus.lhs_op1_relation (lhs, op1, op2, VREL_NONE);
   ASSERT_TRUE (code == LT_EXPR);
 }
 
diff --git a/gcc/range-op.h b/gcc/range-op.h
index c93eb844547..a1f98cd5226 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -78,12 +78,15 @@ public:
   // The following routines are used to represent relations between the
   // various operations.  If the caller knows where the symbolics are,
   // it can query for relationships between them given known ranges.
+  // the optional relation passed in is the relation between op1 and op2.
   virtual enum tree_code lhs_op1_relation (const irange &lhs,
 					   const irange &op1,
-					   const irange &op2) const;
+					   const irange &op2,
+					   relation_kind rel = VREL_NONE) const;
   virtual enum tree_code lhs_op2_relation (const irange &lhs,
 					   const irange &op1,
-					   const irange &op2) const;
+					   const irange &op2,
+					   relation_kind rel = VREL_NONE) const;
   virtual enum tree_code op1_op2_relation (const irange &lhs) const;
 protected:
   // Perform an integral operation between 2 sub-ranges and return it.
diff --git a/gcc/testsuite/g++.dg/pr104547.C b/gcc/testsuite/g++.dg/pr104547.C
new file mode 100644
index 00000000000..b6135ffe3a0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr104547.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-O3 -fdump-tree-vrp2"  }
+
+#include <vector>
+
+void shrink(std::vector<int>& v, unsigned n) {
+    if (v.size() < n)
+      __builtin_unreachable();
+    v.resize(v.size() - n);
+}
+
+// Verify that std::vector<T>::_M_default_append() has been removed by vrp2.
+// { dg-final { scan-tree-dump-not "_M_default_append"  vrp2 } }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-13 14:21 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-13 14:21 [gcc r13-438] Add relation between op1 & op2 to lhs_opN_relation API Andrew Macleod

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).