This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR79088/79188


The following is a fix for jump-threading loop-assumption clearing
which was done only on the first header/irreducible crossing rather
than the one at the destination of the threading path.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

Thanks,
Richard.

2017-01-23  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/79088
	PR tree-optimization/79188
	* tree-ssa-threadupdate.c (mark_threaded_blocks): Move code
	resetting loop bounds after last path deletion.  Reset loop
	bounds of the target loop, make code match the comments.
	* tree-ssa-threadbackwards.c (pass_early_thread_jumps::execute):
	Make sure loops need no fixups.

	* gcc.dg/torture/pr79088.c: New testcase.
	* gcc.dg/torture/pr79188.c: Likewise.

Index: gcc/tree-ssa-threadupdate.c
===================================================================
--- gcc/tree-ssa-threadupdate.c	(revision 244771)
+++ gcc/tree-ssa-threadupdate.c	(working copy)
@@ -2086,42 +2086,6 @@ mark_threaded_blocks (bitmap threaded_bl
   else
     bitmap_copy (threaded_blocks, tmp);
 
-  /* Look for jump threading paths which cross multiple loop headers.
-
-     The code to thread through loop headers will change the CFG in ways
-     that invalidate the cached loop iteration information.  So we must
-     detect that case and wipe the cached information.  */
-  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
-    {
-      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
-      FOR_EACH_EDGE (e, ei, bb->preds)
-	{
-	  if (e->aux)
-	    {
-	      vec<jump_thread_edge *> *path = THREAD_PATH (e);
-
-	      for (unsigned int i = 0, crossed_headers = 0;
-		   i < path->length ();
-		   i++)
-		{
-		  basic_block dest = (*path)[i]->e->dest;
-		  basic_block src = (*path)[i]->e->src;
-		  crossed_headers += (dest == dest->loop_father->header);
-		  /* If we step from a block outside an irreducible region
-		     to a block inside an irreducible region, then we have
-		     crossed into a loop.  */
-		  crossed_headers += ((src->flags & BB_IRREDUCIBLE_LOOP)
-				      != (dest->flags & BB_IRREDUCIBLE_LOOP));
-		  if (crossed_headers > 1)
-		    {
-		      vect_free_loop_info_assumptions (dest->loop_father);
-		      break;
-		    }
-		}
-	    }
-	}
-    }
-
   /* If we have a joiner block (J) which has two successors S1 and S2 and
      we are threading though S1 and the final destination of the thread
      is S2, then we must verify that any PHI nodes in S2 have the same
@@ -2163,6 +2127,46 @@ mark_threaded_blocks (bitmap threaded_bl
 		    }
 		}
 	    }
+	}
+    }
+
+  /* Look for jump threading paths which cross multiple loop headers.
+
+     The code to thread through loop headers will change the CFG in ways
+     that invalidate the cached loop iteration information.  So we must
+     detect that case and wipe the cached information.  */
+  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
+    {
+      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
+      FOR_EACH_EDGE (e, ei, bb->preds)
+	{
+	  if (e->aux)
+	    {
+	      vec<jump_thread_edge *> *path = THREAD_PATH (e);
+
+	      for (unsigned int i = 0, crossed_headers = 0;
+		   i < path->length ();
+		   i++)
+		{
+		  basic_block dest = (*path)[i]->e->dest;
+		  basic_block src = (*path)[i]->e->src;
+		  /* If we enter a loop.  */
+		  if (flow_loop_nested_p (src->loop_father, dest->loop_father))
+		    ++crossed_headers;
+		  /* If we step from a block outside an irreducible region
+		     to a block inside an irreducible region, then we have
+		     crossed into a loop.  */
+		  else if (! (src->flags & BB_IRREDUCIBLE_LOOP)
+			   && (dest->flags & BB_IRREDUCIBLE_LOOP))
+		      ++crossed_headers;
+		  if (crossed_headers > 1)
+		    {
+		      vect_free_loop_info_assumptions
+			((*path)[path->length () - 1]->e->dest->loop_father);
+		      break;
+		    }
+		}
+	    }
 	}
     }
 
Index: gcc/tree-ssa-threadbackward.c
===================================================================
--- gcc/tree-ssa-threadbackward.c	(revision 244771)
+++ gcc/tree-ssa-threadbackward.c	(working copy)
@@ -865,6 +865,8 @@ pass_early_thread_jumps::gate (function
 unsigned int
 pass_early_thread_jumps::execute (function *fun)
 {
+  loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+
   /* Try to thread each block with more than one successor.  */
   basic_block bb;
   FOR_EACH_BB_FN (bb, fun)
@@ -873,6 +875,8 @@ pass_early_thread_jumps::execute (functi
 	find_jump_threads_backwards (bb, false);
     }
   thread_through_all_blocks (true);
+
+  loop_optimizer_finalize ();
   return 0;
 }
 
Index: gcc/testsuite/gcc.dg/torture/pr79088.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr79088.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr79088.c	(working copy)
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+
+int a, b, c, d, e = 1;
+
+int main ()
+{
+  int f;
+  if (a)
+    goto L;
+  for (f = 0; f < e; e++)
+    {
+L:
+      if (d)
+	continue;
+      if (c)
+	goto L;
+      for (a = 0; a < 6; a++)
+	for (f = 0; f < 3; f++)
+	  while (b)
+	    c++;
+    }
+  return 0;
+}
Index: gcc/testsuite/gcc.dg/torture/pr79188.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr79188.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr79188.c	(working copy)
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+int a, b, c, d, e, f, h, j, k;
+
+static void fn1 ()
+{
+  int g = 1, i;
+  if (!f)
+    {
+      for (; d < 1; d++)
+	for (i = 0, j = 1; i < 1; i = j)
+	  a = 2;
+      for (; e < 1; e++)
+	{
+	  for (; k; k++)
+	    L:
+		;
+	  for (c = 0; c < 2; c++)
+	    {
+	      for (i = 0; i < 4; i++)
+		{
+		  for (; h; h++)
+		    g = 0;
+		  b = 0;
+		}
+	      if (b)
+		goto L;
+	    }
+	  a = 0;
+	}
+      if (g < 0)
+	goto L;
+    }
+}
+
+int main ()
+{
+  fn1 ();
+
+  if (a != 0) 
+    __builtin_abort ();
+
+  return 0; 
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]