aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.cc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2024-11-01 20:06:30 -0700
committerAndrew Pinski <quic_apinski@quicinc.com>2024-11-07 08:24:51 -0800
commit578002846620ed04192a4832e9f20b5c32816153 (patch)
tree452c131b3307f7ad8cd0bb7e926f7f64c1e1ed6c /gcc/tree-ssa-sccvn.cc
parentb38f8294e4f29132c8cf4c5d3f3beb64bb0c499d (diff)
downloadgcc-578002846620ed04192a4832e9f20b5c32816153.zip
gcc-578002846620ed04192a4832e9f20b5c32816153.tar.gz
gcc-578002846620ed04192a4832e9f20b5c32816153.tar.bz2
VN: Handle `(a | b) !=/== 0` for predicates [PR117414]
For `(a | b) == 0`, we can "assert" on the true edge that both `a == 0` and `b == 0` but nothing on the false edge. For `(a | b) != 0`, we can "assert" on the false edge that both `a == 0` and `b == 0` but nothing on the true edge. This adds that predicate and allows us to optimize f0, f1, and f2 in fre-predicated-[12].c. Changes since v1: * v2: Use vn_valueize. Also canonicalize the comparison at the begining of insert_predicates_for_cond for constants to be on the rhs. Return early for non-ssa names on the lhs (after canonicalization). Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/117414 gcc/ChangeLog: * tree-ssa-sccvn.cc (insert_predicates_for_cond): Canonicalize the comparison. Don't insert anything if lhs is not a SSA_NAME. Handle `(a | b) !=/== 0`. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/fre-predicated-1.c: New test. * gcc.dg/tree-ssa/fre-predicated-2.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc/tree-ssa-sccvn.cc')
-rw-r--r--gcc/tree-ssa-sccvn.cc36
1 files changed, 36 insertions, 0 deletions
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index a11bf96..c6dddd0 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -7901,6 +7901,21 @@ static void
insert_predicates_for_cond (tree_code code, tree lhs, tree rhs,
edge true_e, edge false_e)
{
+ /* If both edges are null, then there is nothing to be done. */
+ if (!true_e && !false_e)
+ return;
+
+ /* Canonicalize the comparison so the rhs are constants. */
+ if (CONSTANT_CLASS_P (lhs))
+ {
+ std::swap (lhs, rhs);
+ code = swap_tree_comparison (code);
+ }
+
+ /* If the lhs is not a ssa name, don't record anything. */
+ if (TREE_CODE (lhs) != SSA_NAME)
+ return;
+
tree_code icode = invert_tree_comparison (code, HONOR_NANS (lhs));
tree ops[2];
ops[0] = lhs;
@@ -7929,6 +7944,27 @@ insert_predicates_for_cond (tree_code code, tree lhs, tree rhs,
if (false_e)
insert_related_predicates_on_edge (icode, ops, false_e);
}
+ if (integer_zerop (rhs)
+ && (code == NE_EXPR || code == EQ_EXPR))
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
+ /* (a | b) == 0 ->
+ on true edge assert: a == 0 & b == 0. */
+ /* (a | b) != 0 ->
+ on false edge assert: a == 0 & b == 0. */
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
+ {
+ edge e = code == EQ_EXPR ? true_e : false_e;
+ tree nlhs;
+
+ nlhs = vn_valueize (gimple_assign_rhs1 (def_stmt));
+ insert_predicates_for_cond (EQ_EXPR, nlhs, rhs, e, nullptr);
+
+ nlhs = vn_valueize (gimple_assign_rhs2 (def_stmt));
+ insert_predicates_for_cond (EQ_EXPR, nlhs, rhs, e, nullptr);
+ }
+ }
}
/* Main stmt worker for RPO VN, process BB. */