diff mbox

Fix pr58343

Message ID 522F125D.3050306@redhat.com
State New
Headers show

Commit Message

Jeff Law Sept. 10, 2013, 12:36 p.m. UTC
As mentioned in the PR, we have a jump threading request with a loop 
header in the middle of the jump threading path.  In the past this would 
have been rejected earlier but due to recent changes it gets registered.

The code to update the CFG didn't know how to detect this particular 
case and it broke catastrophically.  For this case the best thing to do 
is reject the threading request as it's going to create a loop with 
multiple entries.  That's precisely what this patch does.

I also noted a warning due to botched return value/type in 
thread_around_empty_blocks which this patch fixes.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu. 
Installed on the trunk.
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cd91607..4607dd6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@ 
+2013-09-10  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/58343
+	* tree-ssa-threadupdate.c (thread_block): Identify and disable
+	jump threading requests through loop headers buried in the middle
+	of a jump threading path.
+
+	* tree-ssa-threadedge.c (thread_around_empty_blocks): Fix thinko
+	in return value/type.
+
 2013-09-10  Jakub Jelinek  <jakub@redhat.com>
 
 	PR rtl-optimization/58365
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fe91b24..1e5f483 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@ 
+2013-09-10  Jeff Law  <law@redhat.com>
+
+	* gcc.c-torture/compile/pr58343.c: New test.
+
 2013-09-10  Jakub Jelinek  <jakub@redhat.com>
 
 	PR rtl-optimization/58365
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58343.c b/gcc/testsuite/gcc.c-torture/compile/pr58343.c
new file mode 100644
index 0000000..cdd2ce9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr58343.c
@@ -0,0 +1,15 @@ 
+int a;
+
+int main ()
+{
+  int b = a; 
+
+  for (a = 1; a > 0; a--)
+    ;
+
+ lbl:
+  if (b && a)
+    goto lbl; 
+
+  return 0;
+}
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index f2051d7..14bc4e3 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -764,7 +764,7 @@  thread_around_empty_blocks (edge taken_edge,
      when threading.  Thus they can not have visible side effects such
      as PHI nodes.  */
   if (!gsi_end_p (gsi_start_phis (bb)))
-    return NULL;
+    return false;
 
   /* Skip over DEBUG statements at the start of the block.  */
   gsi = gsi_start_nondebug_bb (bb);
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 8e40f66..3c3d3bc 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -640,14 +640,36 @@  thread_block (basic_block bb, bool noloop_only)
       else
 	e2 = THREAD_TARGET (e);
 
-      if (!e2
+      if (!e2 || noloop_only)
+	{
 	  /* If NOLOOP_ONLY is true, we only allow threading through the
-	     header of a loop to exit edges.  */
-	  || (noloop_only
-	      && bb == bb->loop_father->header
+	     header of a loop to exit edges. 
+
+	     There are two cases to consider.  The first when BB is the
+	     loop header.  We will attempt to thread this elsewhere, so
+	     we can just continue here.  */
+
+	  if (bb == bb->loop_father->header
 	      && (!loop_exit_edge_p (bb->loop_father, e2)
-		  || THREAD_TARGET2 (e))))
-	continue;
+		  || THREAD_TARGET2 (e)))
+	    continue;
+
+
+	  /* The second occurs when there was loop header buried in a jump
+	     threading path.  We do not try and thread this elsewhere, so
+	     just cancel the jump threading request by clearing the AUX
+	     field now.  */
+	  if (bb->loop_father != e2->src->loop_father
+	      && !loop_exit_edge_p (e2->src->loop_father, e2))
+	    {
+	      /* Since this case is not handled by our special code
+		 to thread through a loop header, we must explicitly
+		 cancel the threading request here.  */
+	      free (e->aux);
+	      e->aux = NULL;
+	      continue;
+	    }
+	}
 
       if (e->dest == e2->src)
 	update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e),