From: Richard Biener Date: Mon, 20 Jan 2025 10:50:53 +0000 (+0100) Subject: tree-optimization/118552 - failed LC SSA update after unrolling X-Git-Tag: basepoints/gcc-16~2494 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1265afa91d51606605f85e732344e86e4e4dae9b;p=thirdparty%2Fgcc.git tree-optimization/118552 - failed LC SSA update after unrolling When unrolling changes nesting relationship of loops we fail to mark blocks as in need to change for LC SSA update. Specifically the LC SSA PHI on a former inner loop exit might be misplaced if that loop becomes a sibling of its outer loop. PR tree-optimization/118552 * cfgloopmanip.cc (fix_loop_placement): Properly mark exit source blocks as to be scanned for LC SSA update when the loops nesting relationship changed. (fix_loop_placements): Adjust. (fix_bb_placements): Likewise. * gcc.dg/torture/pr118552.c: New testcase. --- diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc index 17bcf9f4acc..573146b2e28 100644 --- a/gcc/cfgloopmanip.cc +++ b/gcc/cfgloopmanip.cc @@ -123,7 +123,8 @@ fix_bb_placement (basic_block bb) invalidate the information about irreducible regions. */ static bool -fix_loop_placement (class loop *loop, bool *irred_invalidated) +fix_loop_placement (class loop *loop, bool *irred_invalidated, + bitmap loop_closed_ssa_invalidated) { unsigned i; edge e; @@ -153,6 +154,10 @@ fix_loop_placement (class loop *loop, bool *irred_invalidated) if (e->flags & EDGE_IRREDUCIBLE_LOOP) *irred_invalidated = true; rescan_loop_exit (e, false, false); + /* Any LC SSA PHIs on e->dest might now be on the wrong edge + if their defs were in a former outer loop. */ + if (loop_closed_ssa_invalidated) + bitmap_set_bit (loop_closed_ssa_invalidated, e->src->index); } ret = true; @@ -224,7 +229,8 @@ fix_bb_placements (basic_block from, if (from->loop_father->header == from) { /* Subloop header, maybe move the loop upward. */ - if (!fix_loop_placement (from->loop_father, irred_invalidated)) + if (!fix_loop_placement (from->loop_father, irred_invalidated, + loop_closed_ssa_invalidated)) continue; target_loop = loop_outer (from->loop_father); if (loop_closed_ssa_invalidated) @@ -1057,7 +1063,8 @@ fix_loop_placements (class loop *loop, bool *irred_invalidated, while (loop_outer (loop)) { outer = loop_outer (loop); - if (!fix_loop_placement (loop, irred_invalidated)) + if (!fix_loop_placement (loop, irred_invalidated, + loop_closed_ssa_invalidated)) break; /* Changing the placement of a loop in the loop tree may alter the diff --git a/gcc/testsuite/gcc.dg/torture/pr118552.c b/gcc/testsuite/gcc.dg/torture/pr118552.c new file mode 100644 index 00000000000..03ee0d0ca3f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr118552.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fno-tree-ch -fno-tree-ccp -fno-tree-fre" } */ + +volatile int a; +int b, c, d, e; +int main() { + int f = 1, g = 1; +h: + if (!d) + ; + else { + int i = 1; + j: + e = 0; + for (; e < 3; e++) { + if (e) + for (; g < 2; g++) { + if (c) + return 0; + if (f) + goto j; + } + a; + if (i) + continue; + f = i = 0; + } + } + f = 2; + b++; + if (c) + goto h; + return 0; +}