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); }