aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-08-14 09:31:18 +0200
committerRichard Biener <rguenther@suse.de>2023-08-15 11:07:25 +0200
commitbcdbedb3e6083ad01d844ed97cf19645c1ef6568 (patch)
tree64ead9d054f643f819784d23c8cc04a780e97ab7 /gcc
parentecb95399f43873e1f34119ac260bbea2ef358e53 (diff)
downloadgcc-bcdbedb3e6083ad01d844ed97cf19645c1ef6568.zip
gcc-bcdbedb3e6083ad01d844ed97cf19645c1ef6568.tar.gz
gcc-bcdbedb3e6083ad01d844ed97cf19645c1ef6568.tar.bz2
tree-optimization/110991 - unroll size estimate after vectorization
The following testcase shows that we are bad at identifying inductions that will be optimized away after vectorizing them because SCEV doesn't handle vectorized defs. The following rolls a simpler identification of SSA cycles covering a PHI and an assignment with a binary operator with a constant second operand. PR tree-optimization/110991 * tree-ssa-loop-ivcanon.cc (constant_after_peeling): Handle VIEW_CONVERT_EXPR <op>, handle more simple IV-like SSA cycles that will end up constant. * gcc.dg/tree-ssa/cunroll-16.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-16.c17
-rw-r--r--gcc/tree-ssa-loop-ivcanon.cc46
2 files changed, 62 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-16.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-16.c
new file mode 100644
index 0000000..9bb66ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-16.c
@@ -0,0 +1,17 @@
+/* PR/110991 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cunroll-details -fdump-tree-optimized" } */
+
+static unsigned char a;
+static signed char b;
+void foo(void);
+int main() {
+ a = 25;
+ for (; a > 13; --a)
+ b = a > 127 ?: a << 3;
+ if (!b)
+ foo();
+}
+
+/* { dg-final { scan-tree-dump "optimized: loop with \[0-9\]\+ iterations completely unrolled" "cunroll" } } */
+/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */
diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc
index a895e8e..99e50ee 100644
--- a/gcc/tree-ssa-loop-ivcanon.cc
+++ b/gcc/tree-ssa-loop-ivcanon.cc
@@ -166,6 +166,11 @@ constant_after_peeling (tree op, gimple *stmt, class loop *loop)
if (CONSTANT_CLASS_P (op))
return true;
+ /* Get at the actual SSA operand. */
+ if (handled_component_p (op)
+ && TREE_CODE (TREE_OPERAND (op, 0)) == SSA_NAME)
+ op = TREE_OPERAND (op, 0);
+
/* We can still fold accesses to constant arrays when index is known. */
if (TREE_CODE (op) != SSA_NAME)
{
@@ -198,7 +203,46 @@ constant_after_peeling (tree op, gimple *stmt, class loop *loop)
tree ev = analyze_scalar_evolution (loop, op);
if (chrec_contains_undetermined (ev)
|| chrec_contains_symbols (ev))
- return false;
+ {
+ if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (op)))
+ {
+ gassign *ass = nullptr;
+ gphi *phi = nullptr;
+ if (is_a <gassign *> (SSA_NAME_DEF_STMT (op)))
+ {
+ ass = as_a <gassign *> (SSA_NAME_DEF_STMT (op));
+ if (TREE_CODE (gimple_assign_rhs1 (ass)) == SSA_NAME)
+ phi = dyn_cast <gphi *>
+ (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (ass)));
+ }
+ else if (is_a <gphi *> (SSA_NAME_DEF_STMT (op)))
+ {
+ phi = as_a <gphi *> (SSA_NAME_DEF_STMT (op));
+ if (gimple_bb (phi) == loop->header)
+ {
+ tree def = gimple_phi_arg_def_from_edge
+ (phi, loop_latch_edge (loop));
+ if (TREE_CODE (def) == SSA_NAME
+ && is_a <gassign *> (SSA_NAME_DEF_STMT (def)))
+ ass = as_a <gassign *> (SSA_NAME_DEF_STMT (def));
+ }
+ }
+ if (ass && phi)
+ {
+ tree rhs1 = gimple_assign_rhs1 (ass);
+ if (gimple_assign_rhs_class (ass) == GIMPLE_BINARY_RHS
+ && CONSTANT_CLASS_P (gimple_assign_rhs2 (ass))
+ && rhs1 == gimple_phi_result (phi)
+ && gimple_bb (phi) == loop->header
+ && (gimple_phi_arg_def_from_edge (phi, loop_latch_edge (loop))
+ == gimple_assign_lhs (ass))
+ && (CONSTANT_CLASS_P (gimple_phi_arg_def_from_edge
+ (phi, loop_preheader_edge (loop)))))
+ return true;
+ }
+ }
+ return false;
+ }
return true;
}