diff options
author | Richard Biener <rguenther@suse.de> | 2025-01-20 11:50:53 +0100 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2025-01-20 13:14:23 +0100 |
commit | 1265afa91d51606605f85e732344e86e4e4dae9b (patch) | |
tree | 2a656913d415895e55876e9f8e59dcff22917c60 /gcc | |
parent | 6c5937991bd744a4916e9cf65eb5d9c9b5706120 (diff) | |
download | gcc-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.cc | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr118552.c | 34 |
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; +} |