Patchwork PR middle-end/47530: tail call optimization corrupts stack (trans-mem)

login
register
mail settings
Submitter Aldy Hernandez
Date June 4, 2012, 4:04 p.m.
Message ID <4FCCDC9C.6060503@redhat.com>
Download mbox | patch
Permalink /patch/162827/
State New
Headers show

Comments

Aldy Hernandez - June 4, 2012, 4:04 p.m.
This PR was reopened because Luke Dalessandro found a testcase that was 
still causing the stack corruption.

The problem here is that we split the block and call gsi_start_bb() to 
start scanning the new block, but immediately after we call gsi_next() 
which essentially skips the first instruction.

OK for branch and mainline?  (Pending tests currently currently running 
for both 4.7 and trunk).
PR middle-end/47530
	* trans-mem.c (expand_block_edges): Do not skip the first
	statement when resetting the BB.
Richard Henderson - June 4, 2012, 4:06 p.m.
On 06/04/2012 09:04 AM, Aldy Hernandez wrote:
> 	PR middle-end/47530
> 	* trans-mem.c (expand_block_edges): Do not skip the first
> 	statement when resetting the BB.

Ok.


r~

Patch

Index: testsuite/g++.dg/tm/pr47530-2.C
===================================================================
--- testsuite/g++.dg/tm/pr47530-2.C	(revision 0)
+++ testsuite/g++.dg/tm/pr47530-2.C	(revision 0)
@@ -0,0 +1,34 @@ 
+// { dg-do compile }
+// { dg-options "-fgnu-tm -O2 -fno-inline" }
+
+class RBTree
+{
+    struct RBNode
+    {
+      RBNode* next;
+    };
+
+  public:
+    RBNode* sentinel;
+    __attribute__((transaction_safe)) bool lookup();
+};
+
+bool RBTree::lookup()
+{
+  RBNode* x = sentinel;
+  while (x)
+    x = x->next;
+  return false;
+}
+
+
+RBTree* SET;
+
+void bench_test()
+{
+  __transaction_atomic { 
+      SET->lookup();
+    }
+}
+
+// { dg-final { scan-assembler-not "jmp.*ITM_commitTransaction" } }
Index: trans-mem.c
===================================================================
--- trans-mem.c	(revision 188081)
+++ trans-mem.c	(working copy)
@@ -2591,6 +2591,7 @@  expand_block_edges (struct tm_region *re
 
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
     {
+      bool do_next = true;
       gimple stmt = gsi_stmt (gsi);
 
       /* ??? TM_COMMIT (and any other tm builtin function) in a nested
@@ -2612,6 +2613,7 @@  expand_block_edges (struct tm_region *re
 	      make_tm_edge (stmt, bb, region);
 	      bb = e->dest;
 	      gsi = gsi_start_bb (bb);
+	      do_next = false;
 	    }
 
 	  /* Delete any tail-call annotation that may have been added.
@@ -2620,7 +2622,8 @@  expand_block_edges (struct tm_region *re
 	  gimple_call_set_tail (stmt, false);
 	}
 
-      gsi_next (&gsi);
+      if (do_next)
+	gsi_next (&gsi);
     }
 }