aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <jlaw@localhost.localdomain>2021-08-27 15:27:38 -0400
committerJeff Law <jlaw@localhost.localdomain>2021-08-27 15:29:22 -0400
commitac6d5c9112bb78e47398e040c553ad216edf3ebb (patch)
treeff06d132ee7c198fda35e741aa3a8c6ad443fb02 /gcc
parent94a047359f84c7ea5ade378028852b19529a7495 (diff)
downloadgcc-ac6d5c9112bb78e47398e040c553ad216edf3ebb.zip
gcc-ac6d5c9112bb78e47398e040c553ad216edf3ebb.tar.gz
gcc-ac6d5c9112bb78e47398e040c553ad216edf3ebb.tar.bz2
Reduce vector comparison of uniform vectors to a scalar comparison
gcc/ * tree-ssa-dom.c (reduce_vector_comparison_to_scalar_comparison): New function. (dom_opt_dom_walker::optimize_stmt): Use it.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/tree-ssa-dom.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index a0df492..a5245b3 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1891,6 +1891,66 @@ dom_opt_dom_walker::test_for_singularity (gimple *stmt,
}
}
+/* If STMT is a comparison of two uniform vectors reduce it to a comparison
+ of scalar objects, otherwise leave STMT unchanged. */
+
+static void
+reduce_vector_comparison_to_scalar_comparison (gimple *stmt)
+{
+ if (gimple_code (stmt) == GIMPLE_COND)
+ {
+ tree lhs = gimple_cond_lhs (stmt);
+ tree rhs = gimple_cond_rhs (stmt);
+
+ /* We may have a vector comparison where both arms are uniform
+ vectors. If so, we can simplify the vector comparison down
+ to a scalar comparison. */
+ if (TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
+ {
+ /* If either operand is an SSA_NAME, then look back to its
+ defining statement to try and get at a suitable source. */
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
+ if (gimple_assign_single_p (def_stmt))
+ rhs = gimple_assign_rhs1 (def_stmt);
+ }
+
+ if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (lhs);
+ if (gimple_assign_single_p (def_stmt))
+ lhs = gimple_assign_rhs1 (def_stmt);
+ }
+
+ /* Now see if they are both uniform vectors and if so replace
+ the vector comparison with a scalar comparison. */
+ tree rhs_elem = rhs ? uniform_vector_p (rhs) : NULL_TREE;
+ tree lhs_elem = lhs ? uniform_vector_p (lhs) : NULL_TREE;
+ if (rhs_elem && lhs_elem)
+ {
+ if (dump_file && dump_flags & TDF_DETAILS)
+ {
+ fprintf (dump_file, "Reducing vector comparison: ");
+ print_gimple_stmt (dump_file, stmt, 0);
+ }
+
+ gimple_cond_set_rhs (as_a <gcond *>(stmt), rhs_elem);
+ gimple_cond_set_lhs (as_a <gcond *>(stmt), lhs_elem);
+ gimple_set_modified (stmt, true);
+
+ if (dump_file && dump_flags & TDF_DETAILS)
+ {
+ fprintf (dump_file, "To scalar equivalent: ");
+ print_gimple_stmt (dump_file, stmt, 0);
+ fprintf (dump_file, "\n");
+ }
+ }
+ }
+ }
+}
+
/* Optimize the statement in block BB pointed to by iterator SI.
We try to perform some simplistic global redundancy elimination and
@@ -1933,6 +1993,11 @@ dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator *si,
update_stmt_if_modified (stmt);
opt_stats.num_stmts++;
+ /* STMT may be a comparison of uniform vectors that we can simplify
+ down to a comparison of scalars. Do that transformation first
+ so that all the scalar optimizations from here onward apply. */
+ reduce_vector_comparison_to_scalar_comparison (stmt);
+
/* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */
cprop_into_stmt (stmt, m_evrp_range_analyzer);