http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52250

--- Comment #5 from Andrey Belevantsev <abel at gcc dot gnu.org> 2012-02-27 
13:03:58 UTC ---
When removing an empty block, we need to find its neighbour to stick the bb
note list to, and the code doing this now just picks some pred block from the
loop that redirects preds' edges around the block being removed.  Which happens
to be the wrong one for the test case.  Fixed by making the logic properly
consider preds and the only succ, if needed, as below.  I will test this
tomorrow and still can make it before the RC1, I think.

diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index a93cd68..03d135f 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -3658,7 +3658,7 @@ sel_recompute_toporder (void)
 static bool
 maybe_tidy_empty_bb (basic_block bb)
 {
-  basic_block succ_bb, pred_bb;
+  basic_block succ_bb, pred_bb, note_bb;
   VEC (basic_block, heap) *dom_bbs;
   edge e;
   edge_iterator ei;
@@ -3697,6 +3697,17 @@ maybe_tidy_empty_bb (basic_block bb)
   pred_bb = NULL;
   dom_bbs = NULL;

+  /* Save a pred/succ from the current region to attach the notes to.  */
+  note_bb = NULL;
+  FOR_EACH_EDGE (e, ei, bb->preds)
+    if (in_current_region_p (e->src))
+      {
+    note_bb = e->src;
+    break;
+      }
+  if (note_bb == NULL)
+    note_bb = succ_bb;
+
   /* Redirect all non-fallthru edges to the next bb.  */
   while (rescan_p)
     {
@@ -3746,10 +3757,8 @@ maybe_tidy_empty_bb (basic_block bb)
   else
     {
       /* This is a block without fallthru predecessor.  Just delete it.  */
-      gcc_assert (pred_bb != NULL);
-
-      if (in_current_region_p (pred_bb))
-    move_bb_info (pred_bb, bb);
+      gcc_assert (note_bb);
+      move_bb_info (note_bb, bb);
       remove_empty_bb (bb, true);
     }

Reply via email to