tree-optimization/112856 - fix LC SSA after loop header copying

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.

	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.
This commit is contained in:
Richard Biener 2023-12-05 08:50:57 +01:00
parent e0786ca9a1
commit 8ff02df629
5 changed files with 65 additions and 5 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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++)
;
}
}

View File

@ -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);

View File

@ -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 ();