aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2023-03-20 16:11:12 -0400
committerAndrew MacLeod <amacleod@redhat.com>2023-03-21 09:56:02 -0400
commit0963cb5fde158cce986523a90fa9edc51c881f31 (patch)
treef2fcf612cfc29038ed6a7196ce31eb05c80ab094
parent26adc870e3675591050f37edab46850b97a3c122 (diff)
downloadgcc-0963cb5fde158cce986523a90fa9edc51c881f31.zip
gcc-0963cb5fde158cce986523a90fa9edc51c881f31.tar.gz
gcc-0963cb5fde158cce986523a90fa9edc51c881f31.tar.bz2
Terminate GORI calculations if a relation is not relevant.
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.
-rw-r--r--gcc/gimple-range-gori.cc36
-rw-r--r--gcc/value-relation.h2
2 files changed, 32 insertions, 6 deletions
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index beb1c00..2f8d470 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -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))
{
diff --git a/gcc/value-relation.h b/gcc/value-relation.h
index 340f9c4..897cf46 100644
--- a/gcc/value-relation.h
+++ b/gcc/value-relation.h
@@ -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;