aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-01-20 11:50:53 +0100
committerRichard Biener <rguenth@gcc.gnu.org>2025-01-20 13:14:23 +0100
commit1265afa91d51606605f85e732344e86e4e4dae9b (patch)
tree2a656913d415895e55876e9f8e59dcff22917c60 /gcc
parent6c5937991bd744a4916e9cf65eb5d9c9b5706120 (diff)
downloadgcc-1265afa91d51606605f85e732344e86e4e4dae9b.zip
gcc-1265afa91d51606605f85e732344e86e4e4dae9b.tar.gz
gcc-1265afa91d51606605f85e732344e86e4e4dae9b.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cfgloopmanip.cc13
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr118552.c34
2 files changed, 44 insertions, 3 deletions
diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc
index 17bcf9f..573146b 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 0000000..03ee0d0
--- /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;
+}