]> git.ipfire.org Git - people/ms/gcc.git/commitdiff
Terminate GORI calculations if a relation is not relevant.
authorAndrew MacLeod <amacleod@redhat.com>
Mon, 20 Mar 2023 20:11:12 +0000 (16:11 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Tue, 21 Mar 2023 13:56:02 +0000 (09:56 -0400)
We currently allow VARYING lhs GORI calculations to continue if there is
a relation present in the hope it will eventually better refine a result.
This adds a check that the relation is relevant to the outgoing range
calculation first.  If it is not relevant, stop calculating.

PR tree-optimization/109192
* gimple-range-gori.cc (gori_compute::compute_operand_range):
Terminate gori calculations if a relation is not relevant.
* value-relation.h (value_relation::set_relation): Allow
equality between op1 and op2 if they are the same.

gcc/gimple-range-gori.cc
gcc/value-relation.h

index beb1c0064b9805ac541fccf57e20d01bbd351222..2f8d4704ea4c554f1bba0c41d96c6c26b47ddfe4 100644 (file)
@@ -653,12 +653,38 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt,
   if (!op1_in_chain && !op2_in_chain)
     return false;
 
-  // If the lhs doesn't tell us anything and there are no relations, there
-  // is nothing to be learned.
-  if (lhs.varying_p () && !vrel_ptr)
-    return false;
+  bool res = false;
+  // If the lhs doesn't tell us anything only a relation can possibly enhance
+  // the result.
+  if (lhs.varying_p ())
+    {
+      if (!vrel_ptr)
+       return false;
+      // If there is a relation (ie: x != y) , it can only be relevant if
+      // a) both elements are in the defchain
+      //    c = x > y   // (x and y are in c's defchain)
+      if (op1_in_chain)
+       res = in_chain_p (vrel_ptr->op1 (), op1)
+             && in_chain_p (vrel_ptr->op2 (), op1);
+      if (!res && op2_in_chain)
+       res = in_chain_p (vrel_ptr->op1 (), op2)
+             || in_chain_p (vrel_ptr->op2 (), op2);
+      if (!res)
+       {
+         // or b) one relation element is in the defchain of the other and the
+         //       other is the LHS of this stmt.
+         //  x = y + 2
+         if (vrel_ptr->op1 () == handler.lhs ()
+             && (vrel_ptr->op2 () == op1 || vrel_ptr->op2 () == op2))
+           res = true;
+         else if (vrel_ptr->op2 () == handler.lhs ()
+                  && (vrel_ptr->op1 () == op1 || vrel_ptr->op1 () == op2))
+           res = true;
+       }
+      if (!res)
+       return false;
+    }
 
-  bool res;
   // Process logicals as they have special handling.
   if (is_gimple_logical_p (stmt))
     {
index 340f9c42554098fbf044450b8e7f1797f7936ac9..897cf467dd33274243b8f79074fce62c8061f05a 100644 (file)
@@ -445,7 +445,7 @@ value_relation::set_relation (relation_kind r, tree n1, tree n2)
 {
   gcc_checking_assert (TREE_CODE (n1) == SSA_NAME
                       && TREE_CODE (n2) == SSA_NAME);
-  if (n1 == n2)
+  if (n1 == n2 && r != VREL_EQ)
     {
       related = VREL_VARYING;
       name1 = NULL_TREE;