tree-optimization/124810 - ICE with loop fixup
Checks
Commit Message
The following fixes fix_loop_placements to properly consider
re-parenting only outer loops of a nest.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
PR tree-optimization/124810
* cfgloopmanip.cc (fix_loop_placements): Do not stop
iterating when an inner loop didn't get re-parented.
Compute the outermost loop we have to consider re-parenting.
* gcc.dg/torture/pr124810.c: New testcase.
---
gcc/cfgloopmanip.cc | 37 +++++++++++++++++--------
gcc/testsuite/gcc.dg/torture/pr124810.c | 23 +++++++++++++++
2 files changed, 48 insertions(+), 12 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr124810.c
@@ -1061,23 +1061,36 @@ static void
fix_loop_placements (class loop *loop, bool *irred_invalidated,
bitmap loop_closed_ssa_invalidated)
{
- class loop *outer;
+ if (!loop_outer (loop))
+ return;
+
+ auto_vec<edge> exits = get_loop_exit_edges (loop);
+ unsigned i;
+ edge e;
+ /* We might need to only re-parent an outer loop, but as the constraint
+ is that we removed an exit from LOOP, we have a limit for what level
+ of outer loop we eventually have to re-parent to. */
+ class loop *outermost = loop;
+ FOR_EACH_VEC_ELT (exits, i, e)
+ outermost = find_common_loop (outermost, e->dest->loop_father);
+
+ class loop *outer;
while (loop_outer (loop))
{
outer = loop_outer (loop);
- 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
- validity of condition 2) of the description of fix_bb_placement
- for its preheader, because the successor is the header and belongs
- to the loop. So call fix_bb_placements to fix up the placement
- of the preheader and (possibly) of its predecessors. */
- fix_bb_placements (loop_preheader_edge (loop)->src,
- irred_invalidated, loop_closed_ssa_invalidated);
+ if (fix_loop_placement (loop, irred_invalidated,
+ loop_closed_ssa_invalidated))
+ /* Changing the placement of a loop in the loop tree may alter the
+ validity of condition 2) of the description of fix_bb_placement
+ for its preheader, because the successor is the header and belongs
+ to the loop. So call fix_bb_placements to fix up the placement
+ of the preheader and (possibly) of its predecessors. */
+ fix_bb_placements (loop_preheader_edge (loop)->src,
+ irred_invalidated, loop_closed_ssa_invalidated);
loop = outer;
+ if (outer == outermost)
+ break;
}
}
new file mode 100644
@@ -0,0 +1,23 @@
+/* { dg-additional-options "-fno-tree-ch -fno-tree-dce -fno-tree-dominator-opts -fno-tree-vrp -fno-tree-dse" } */
+
+int a, b[9], c, d;
+static void e() {
+ int f[9];
+ unsigned char g;
+h:
+i:
+ if (a)
+ goto h;
+ g = 0;
+ for (; g < 9; g++) {
+ b[g] = f[8] ? 0 : g;
+ if (g)
+ goto i;
+ d ? c && d < 0 : c;
+ }
+}
+int main() {
+ while (c)
+ e();
+ return 0;
+}