diff mbox

[PR,tree-optimization/59221] Fix temporary equivalence handling

Message ID 528E6556.4030808@redhat.com
State New
Headers show

Commit Message

Jeff Law Nov. 21, 2013, 7:56 p.m. UTC
A recent change to the thread discovery code was missing a small, but 
important hunk.  Namely management of the temporary equivalences. 
Amazingly, this didn't cause any bootstrapping problems on x86, but 
Zhendong has a good testcase and it may be causing problems on Sparc.

In a nutshell, we were failing to wipe temporary equivalences when 
processing the successors of a joiner block.  Egad.  It'd actually been 
like this for a while, but the new code makes the oversight more obvious 
and painful.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu. 
Obviously it fixes Zhendong's tesetcase as well.  Installed on the 
trunk.  Sorry for the breakage.

Jeff
PR tree-optimization/59221
	* tree-ssa-threadedge.c (thread_across_edge): Properly manage
	temporary equivalences when threading through joiner blocks.

	PR tree-optimization/59221
	* gcc.c-torture/execute/pr59221.c: New test.
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.c-torture/execute/pr59221.c b/gcc/testsuite/gcc.c-torture/execute/pr59221.c
new file mode 100644
index 0000000..0cd4259
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr59221.c
@@ -0,0 +1,19 @@ 
+
+
+int a = 1, b, d;
+short e;
+
+int
+main ()
+{
+  for (; b; b++)
+    ;
+  short f = a;
+  int g = 15;
+  e = f ? f : 1 << g;
+  int h = e;
+  d = h == 83647 ? 0 : h;
+  if (d != 1)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 7bb8829..a144875 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -1072,6 +1072,10 @@  thread_across_edge (gimple dummy_cond,
     /* Look at each successor of E->dest to see if we can thread through it.  */
     FOR_EACH_EDGE (taken_edge, ei, e->dest->succs)
       {
+	/* Push a fresh marker so we can unwind the equivalences created
+	   for each of E->dest's successors.  */
+	stack->safe_push (NULL_TREE);
+     
 	/* Avoid threading to any block we have already visited.  */
 	bitmap_clear (visited);
 	bitmap_set_bit (visited, taken_edge->dest->index);
@@ -1118,6 +1122,9 @@  thread_across_edge (gimple dummy_cond,
 	  {
 	    delete_jump_thread_path (path);
 	  }
+
+	/* And unwind the equivalence table.  */
+	remove_temporary_equivalences (stack);
       }
     BITMAP_FREE (visited);
   }