Fix PR84057

Message ID alpine.LSU.2.20.1801261559330.18265@zhemvz.fhfr.qr
State New
Headers show
Series
  • Fix PR84057
Related show

Commit Message

Richard Biener Jan. 26, 2018, 3 p.m.
There's another latent bug in loop unrolling edge/region removal code
which doesn't deal with removing edges in already removed regions.

The following fixes this.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2018-01-26  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/84057
	* tree-ssa-loop-ivcanon.c (unloop_loops): Deal with already
	removed paths when removing edges.

	* gcc.dg/graphite/pr84057.c: New testcase.

Patch

Index: gcc/tree-ssa-loop-ivcanon.c
===================================================================
--- gcc/tree-ssa-loop-ivcanon.c	(revision 257077)
+++ gcc/tree-ssa-loop-ivcanon.c	(working copy)
@@ -660,14 +660,21 @@  unloop_loops (bitmap loop_closed_ssa_inv
   loops_to_unloop.release ();
   loops_to_unloop_nunroll.release ();
 
-  /* Remove edges in peeled copies.  */
+  /* Remove edges in peeled copies.  Given remove_path removes dominated
+     regions we need to cope with removal of already removed paths.  */
   unsigned i;
   edge e;
+  auto_vec<int, 20> src_bbs;
+  src_bbs.reserve_exact (edges_to_remove.length ());
   FOR_EACH_VEC_ELT (edges_to_remove, i, e)
-    {
-      bool ok = remove_path (e, irred_invalidated, loop_closed_ssa_invalidated);
-      gcc_assert (ok);
-    }
+    src_bbs.quick_push (e->src->index);
+  FOR_EACH_VEC_ELT (edges_to_remove, i, e)
+    if (BASIC_BLOCK_FOR_FN (cfun, src_bbs[i]))
+      {
+	bool ok = remove_path (e, irred_invalidated,
+			       loop_closed_ssa_invalidated);
+	gcc_assert (ok);
+      }
   edges_to_remove.release ();
 }
 
Index: gcc/testsuite/gcc.dg/graphite/pr84057.c
===================================================================
--- gcc/testsuite/gcc.dg/graphite/pr84057.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/graphite/pr84057.c	(working copy)
@@ -0,0 +1,31 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgraphite -funroll-loops -fno-tree-ccp -fno-tree-dce" } */
+
+int ue;
+
+void
+fr (int ct)
+{
+  int au = 0;
+  int *ra = &au;
+
+  while (au < 1)
+    {
+      au -= 0x7878788;
+      if (au != ct && ue != 0)
+	{
+	  while (au < 1)
+	    {
+	    }
+
+fc:
+	  while (ct != 0)
+	    {
+	    }
+	}
+    }
+
+  for (au = 0; au < 2; ++au)
+    if (ct != 0)
+      goto fc;
+}