re PR tree-optimization/71595 (ICE on valid code at -O2 and -O3 on x86_64-linux-gnu...
authorRichard Biener <rguenther@suse.de>
Thu, 24 Nov 2016 12:25:22 +0000 (12:25 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 24 Nov 2016 12:25:22 +0000 (12:25 +0000)
2016-11-24  Richard Biener  <rguenther@suse.de>

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

gcc/ChangeLog
gcc/cfgloopmanip.c
gcc/cfgloopmanip.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr71595.c [new file with mode: 0644]
gcc/tree-ssa-loop-ivcanon.c

index d501ff687a03f1a140a290f9bb48b11d90ae3c10..1676fe100d1017c0a1a78a73f72ba2cd0769eb0e 100644 (file)
@@ -1,3 +1,15 @@
+2016-11-24  Richard Biener  <rguenther@suse.de>
+
+       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  <bschmidt@redhat.com>
 
        PR rtl-optimization/78120
index eb868393fac8940d06f0d73d3f265b7f8d451957..84b6b019bc92a53136097af4353cec8e66f3445d 100644 (file)
@@ -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<basic_block> 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 ();
 
index 0e7dc7aa6172807010ad9b521f5fc1063660c781..5c4552c5c433bb94bdfac90f87c76b74fa0c947d 100644 (file)
@@ -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);
index 8a4332e769c863519b3371108085b288384657ad..300106c19ffb6468556cb6e74bde3f2eee48d6df 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-24  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/71595
+       * gcc.dg/torture/pr71595.c: New testcase.
+
 2016-11-24  Bernd Schmidt  <bschmidt@redhat.com>
 
        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 (file)
index 0000000..4202ad3
--- /dev/null
@@ -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;
+      }
+}
index beb65b04e29eb39df32cf6c0c51d4ad15bfb0692..906149602c990f4e80e6420d25014168d595e792 100644 (file)
@@ -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 ();