When loop header copying unloops loops we have to possibly fixup LC SSA. I've take the opportunity to streamline the unloop_loops API, removing the use of a ivcanon local global variable.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/109689 PR tree-optimization/112856 * cfgloopmanip.h (unloop_loops): Adjust API. * tree-ssa-loop-ivcanon.cc (unloop_loops): Take edges_to_remove as parameter. (canonicalize_induction_variables): Adjust. (tree_unroll_loops_completely): Likewise. * tree-ssa-loop-ch.cc (ch_base::copy_headers): Rewrite into LC SSA if we unlooped some loops and we are in LC SSA. * gcc.dg/torture/pr109689.c: New testcase. * gcc.dg/torture/pr112856.c: Likewise. --- gcc/cfgloopmanip.h | 1 + gcc/testsuite/gcc.dg/torture/pr109689.c | 34 +++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr112856.c | 18 +++++++++++++ gcc/tree-ssa-loop-ch.cc | 9 ++++++- gcc/tree-ssa-loop-ivcanon.cc | 8 +++--- 5 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr109689.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr112856.c diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h index 2dda5040823..45aed0d04c2 100644 --- a/gcc/cfgloopmanip.h +++ b/gcc/cfgloopmanip.h @@ -47,6 +47,7 @@ extern class loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree, extern void unloop (class loop *, bool *, bitmap); extern void unloop_loops (vec<class loop *> &loops_to_unloop, vec<int> &loops_to_unloop_nunroll, + vec<edge> &edges_to_remove, bitmap loop_closed_ssa_invalidated, bool *irred_invalidated); extern void copy_loop_info (class loop *loop, class loop *target); diff --git a/gcc/testsuite/gcc.dg/torture/pr109689.c b/gcc/testsuite/gcc.dg/torture/pr109689.c new file mode 100644 index 00000000000..5d2ce7ed63d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr109689.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-vectorize" } */ + +int a, b, c, d, e; +int main() { + char f; + while (a) { + int g, h = 3; + if (b) + i: + if (d) + goto j; + k: + if (a) { + j: + if (!g) + goto k; + if (e) { + while (e) + e = f; + h = 0; + goto i; + } + if (!h) + for (; g < 1; g++) + ; + g = ~((~c & h & c) ^ ~g); + if (!g) + for (; a < 1; a++) + f++; + } + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr112856.c b/gcc/testsuite/gcc.dg/torture/pr112856.c new file mode 100644 index 00000000000..67ab4816be6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr112856.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +double *SVD_A_0; +int SVD_i, SVD_j, SVD_k, SVD_n; +double SVD_f; +void SVD() { + SVD_i = SVD_n - 1; + for (; SVD_i; SVD_i--) { + for (; SVD_j; SVD_j++) { + SVD_f = SVD_k = SVD_i; + for (; SVD_k < SVD_n; SVD_k++) + SVD_A_0[SVD_k] += SVD_f; + } + SVD_j = SVD_i; + for (; SVD_j < SVD_n; SVD_j++) + ; + } +} diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 461416e4086..dd9ee40a022 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-range-path.h" #include "gimple-pretty-print.h" #include "cfganal.h" +#include "tree-ssa-loop-manip.h" /* Return path query insteance for testing ranges of statements in headers of LOOP contained in basic block BB. @@ -1149,7 +1150,13 @@ ch_base::copy_headers (function *fun) if (!loops_to_unloop.is_empty ()) { bool irred_invalidated; - unloop_loops (loops_to_unloop, loops_to_unloop_nunroll, NULL, &irred_invalidated); + auto_bitmap lc_invalidated; + auto_vec<edge> edges_to_remove; + unloop_loops (loops_to_unloop, loops_to_unloop_nunroll, edges_to_remove, + lc_invalidated, &irred_invalidated); + if (loops_state_satisfies_p (fun, LOOP_CLOSED_SSA) + && !bitmap_empty_p (lc_invalidated)) + rewrite_into_loop_closed_ssa (NULL, 0); changed = true; } free (bbs); diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc index 5856f76c8ea..67f2318079b 100644 --- a/gcc/tree-ssa-loop-ivcanon.cc +++ b/gcc/tree-ssa-loop-ivcanon.cc @@ -667,6 +667,7 @@ static bitmap peeled_loops; void unloop_loops (vec<class loop *> &loops_to_unloop, vec<int> &loops_to_unloop_nunroll, + vec<edge> &edges_to_remove, bitmap loop_closed_ssa_invalidated, bool *irred_invalidated) { @@ -1361,7 +1362,7 @@ canonicalize_induction_variables (void) } gcc_assert (!need_ssa_update_p (cfun)); - unloop_loops (loops_to_unloop, loops_to_unloop_nunroll, + unloop_loops (loops_to_unloop, loops_to_unloop_nunroll, edges_to_remove, loop_closed_ssa_invalidated, &irred_invalidated); loops_to_unloop.release (); loops_to_unloop_nunroll.release (); @@ -1511,9 +1512,8 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) { unsigned i; - unloop_loops (loops_to_unloop, - loops_to_unloop_nunroll, - loop_closed_ssa_invalidated, + unloop_loops (loops_to_unloop, loops_to_unloop_nunroll, + edges_to_remove, loop_closed_ssa_invalidated, &irred_invalidated); loops_to_unloop.release (); loops_to_unloop_nunroll.release (); -- 2.35.3