diff options
author | Richard Biener <rguenther@suse.de> | 2023-08-14 09:31:18 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2023-08-15 11:07:25 +0200 |
commit | bcdbedb3e6083ad01d844ed97cf19645c1ef6568 (patch) | |
tree | 64ead9d054f643f819784d23c8cc04a780e97ab7 /gcc | |
parent | ecb95399f43873e1f34119ac260bbea2ef358e53 (diff) | |
download | gcc-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.c | 17 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivcanon.cc | 46 |
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; } |