[PATCH][PR tree-optimization/69999] Schedule loop fixups when duplicating certain blocks for path splitting

Jeff Law law@redhat.com
Mon Feb 29 22:45:00 GMT 2016



We've recently started looking at getting loop fixups scheduled when 
removing edges to address a regression.

This BZ is a closely related problem, namely that duplicating a block 
can turn an irreducible loop into a natural loop as well.  After the 
problems with tying into the low level CFG manipulation code for the 
edge removal code, I don't want to go down that path again for gcc-6 in 
the block duplication code.

Thus this patch targets the specific pass (path splitting) that is 
duplicating the blocks rather than doing something more general in the 
block duplication code.  Hence this only fixes the one known instance of 
this problem.  I wouldn't be terribly surprised if folks are able to 
coerce other passes that duplicate blocks into generating similar problems.

I suspect for gcc-7 and beyond we're going to want to look at how the 
CFG and loop codes need to communicate/cooperate better on this stuff.

Bootstrapped and regression tested on x86_64-linux-gnu.   Installing on 
the trunk momentarily.

Jeff
-------------- next part --------------
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 966e06d..653b51e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-02-28  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/69999
+	* gimple-ssa-split-paths.c (split_paths): When duplicating a block
+	with an outgoing edge marked with EDGE_IRREDUCIBLE_LOOP, schedule
+	loop cleanups.
+
 2016-02-29  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/69994
diff --git a/gcc/gimple-ssa-split-paths.c b/gcc/gimple-ssa-split-paths.c
index ac6de81..0a0bef8 100644
--- a/gcc/gimple-ssa-split-paths.c
+++ b/gcc/gimple-ssa-split-paths.c
@@ -294,6 +294,24 @@ split_paths ()
 	  basic_block pred0 = EDGE_PRED (bb, 0)->src;
 	  transform_duplicate (pred0, bb);
 	  changed = true;
+
+	  /* If BB has an outgoing edge marked as IRREDUCIBLE, then
+	     duplicating BB may result in an irreducible region turning
+	     into a natural loop.
+
+	     Long term we might want to hook this into the block
+	     duplication code, but as we've seen with similar changes
+	     for edge removal, that can be somewhat risky.  */
+	  if (EDGE_SUCC (bb, 0)->flags & EDGE_IRREDUCIBLE_LOOP
+	      || EDGE_SUCC (bb, 1)->flags & EDGE_IRREDUCIBLE_LOOP)
+	    {
+	      if (dump_file && (dump_flags & TDF_DETAILS))
+		  fprintf (dump_file,
+			   "Join block %d has EDGE_IRREDUCIBLE_LOOP set.  "
+			   "Scheduling loop fixups.\n",
+			   bb->index);
+	      loops_state_set (LOOPS_NEED_FIXUP);
+	    }
 	}
     }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a97af64..49577ee 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-02-29  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/69999
+	* gcc.c-torture/compile/pr69999.c: New test.
+
 2016-02-29  Yuri Rumyantsev  <ysrumyan@gmail.com>
 
 	PR tree-optimization/69652
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr69999.c b/gcc/testsuite/gcc.c-torture/compile/pr69999.c
new file mode 100644
index 0000000..5659ce4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr69999.c
@@ -0,0 +1,16 @@
+int uh;
+
+void
+ha(void)
+{
+  while (uh) {
+    for (uh = 0; uh < 1; ++uh) {
+      uh = 0;
+      if (uh != 0)
+ ts:
+        uh %= uh;
+    }
+    ++uh;
+  }
+  goto ts;
+}


More information about the Gcc-patches mailing list