diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2023-03-20 16:11:12 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2023-03-21 09:56:02 -0400 |
commit | 0963cb5fde158cce986523a90fa9edc51c881f31 (patch) | |
tree | f2fcf612cfc29038ed6a7196ce31eb05c80ab094 | |
parent | 26adc870e3675591050f37edab46850b97a3c122 (diff) | |
download | gcc-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.cc | 36 | ||||
-rw-r--r-- | gcc/value-relation.h | 2 |
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; |