From: Richard Biener Date: Thu, 24 Nov 2016 12:25:22 +0000 (+0000) Subject: re PR tree-optimization/71595 (ICE on valid code at -O2 and -O3 on x86_64-linux-gnu... X-Git-Tag: upstream/12.2.0~43004 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eb2afa1a80613d37aa12fdd5a0624b45fdef9377;p=platform%2Fupstream%2Fgcc.git re PR tree-optimization/71595 (ICE on valid code at -O2 and -O3 on x86_64-linux-gnu: in check_loop_closed_ssa_use, at tree-ssa-loop-manip.c:704) 2016-11-24 Richard Biener PR tree-optimization/71595 * cfgloopmanip.h (remove_path): Add irred_invalidated and loop_closed_ssa_invalidated parameters, defaulted to NULL. * cfgloopmanip.c (remove_path): Likewise, pass them along to called functions. Only fix irred flags if the caller didn't request state. * tree-ssa-loop-ivcanon.c (unloop_loops): Use add_bb_to_loop. (unloop_loops): Pass irred_invalidated and loop_closed_ssa_invalidated to remove_path. * gcc.dg/torture/pr71595.c: New testcase. From-SVN: r242835 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d501ff6..1676fe1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2016-11-24 Richard Biener + + PR tree-optimization/71595 + * cfgloopmanip.h (remove_path): Add irred_invalidated and + loop_closed_ssa_invalidated parameters, defaulted to NULL. + * cfgloopmanip.c (remove_path): Likewise, pass them along to + called functions. Only fix irred flags if the caller didn't + request state. + * tree-ssa-loop-ivcanon.c (unloop_loops): Use add_bb_to_loop. + (unloop_loops): Pass irred_invalidated and loop_closed_ssa_invalidated + to remove_path. + 2016-11-24 Bernd Schmidt PR rtl-optimization/78120 diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index eb86839..84b6b01 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -298,16 +298,20 @@ fix_bb_placements (basic_block from, and update loop structures and dominators. Return true if we were able to remove the path, false otherwise (and nothing is affected then). */ bool -remove_path (edge e) +remove_path (edge e, bool *irred_invalidated, + bitmap loop_closed_ssa_invalidated) { edge ae; basic_block *rem_bbs, *bord_bbs, from, bb; vec dom_bbs; int i, nrem, n_bord_bbs; - bool irred_invalidated = false; + bool local_irred_invalidated = false; edge_iterator ei; struct loop *l, *f; + if (! irred_invalidated) + irred_invalidated = &local_irred_invalidated; + if (!can_remove_branch_p (e)) return false; @@ -317,7 +321,7 @@ remove_path (edge e) that is inside an irreducible region is changed, or if such a loop is removed. */ if (e->flags & EDGE_IRREDUCIBLE_LOOP) - irred_invalidated = true; + *irred_invalidated = true; /* We need to check whether basic blocks are dominated by the edge e, but we only have basic block dominators. This is easy to @@ -334,7 +338,7 @@ remove_path (edge e) { f = loop_outer (l); if (dominated_by_p (CDI_DOMINATORS, l->latch, e->dest)) - unloop (l, &irred_invalidated, NULL); + unloop (l, irred_invalidated, loop_closed_ssa_invalidated); } /* Identify the path. */ @@ -348,13 +352,13 @@ remove_path (edge e) /* Find "border" hexes -- i.e. those with predecessor in removed path. */ for (i = 0; i < nrem; i++) bitmap_set_bit (seen, rem_bbs[i]->index); - if (!irred_invalidated) + if (!*irred_invalidated) FOR_EACH_EDGE (ae, ei, e->src->succs) if (ae != e && ae->dest != EXIT_BLOCK_PTR_FOR_FN (cfun) && !bitmap_bit_p (seen, ae->dest->index) && ae->flags & EDGE_IRREDUCIBLE_LOOP) { - irred_invalidated = true; + *irred_invalidated = true; break; } @@ -369,7 +373,7 @@ remove_path (edge e) bord_bbs[n_bord_bbs++] = ae->dest; if (ae->flags & EDGE_IRREDUCIBLE_LOOP) - irred_invalidated = true; + *irred_invalidated = true; } } @@ -411,10 +415,10 @@ remove_path (edge e) /* Fix placements of basic blocks inside loops and the placement of loops in the loop tree. */ - fix_bb_placements (from, &irred_invalidated, NULL); - fix_loop_placements (from->loop_father, &irred_invalidated); + fix_bb_placements (from, irred_invalidated, loop_closed_ssa_invalidated); + fix_loop_placements (from->loop_father, irred_invalidated); - if (irred_invalidated + if (local_irred_invalidated && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)) mark_irreducible_loops (); diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h index 0e7dc7a..5c4552c 100644 --- a/gcc/cfgloopmanip.h +++ b/gcc/cfgloopmanip.h @@ -34,7 +34,7 @@ enum a complete peeling. */ extern edge mfb_kj_edge; -extern bool remove_path (edge); +extern bool remove_path (edge, bool * = NULL, bitmap = NULL); extern void place_new_loop (struct function *, struct loop *); extern void add_loop (struct loop *, struct loop *); extern void scale_loop_frequencies (struct loop *, int, int); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8a4332e..300106c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-24 Richard Biener + + PR tree-optimization/71595 + * gcc.dg/torture/pr71595.c: New testcase. + 2016-11-24 Bernd Schmidt PR rtl-optimization/78120 diff --git a/gcc/testsuite/gcc.dg/torture/pr71595.c b/gcc/testsuite/gcc.dg/torture/pr71595.c new file mode 100644 index 0000000..4202ad3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr71595.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +int a, d, e, f, g, h; +static int b[][6] = { {0}, {0}, {1, 1}, {1} }; + +void +fn1 () +{ + for (; f; f++) + if (g) + { + for (e = 0; e < 5; e++) + if (b[e + 2][1]) + { + h = b[2][e] ? 0 : a; + d |= 4; + } + else + return; + } +} diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index beb65b0..9061496 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -647,7 +647,7 @@ unloop_loops (bitmap loop_closed_ssa_invalidated, latch_edge->flags |= flags; latch_edge->goto_locus = locus; - latch_edge->dest->loop_father = current_loops->tree_root; + add_bb_to_loop (latch_edge->dest, current_loops->tree_root); latch_edge->dest->count = 0; latch_edge->dest->frequency = 0; set_immediate_dominator (CDI_DOMINATORS, latch_edge->dest, latch_edge->src); @@ -663,7 +663,7 @@ unloop_loops (bitmap loop_closed_ssa_invalidated, edge e; FOR_EACH_VEC_ELT (edges_to_remove, i, e) { - bool ok = remove_path (e); + bool ok = remove_path (e, irred_invalidated, loop_closed_ssa_invalidated); gcc_assert (ok); } edges_to_remove.release ();