[backport gcc-4.8/trunk r193047 ] gcc/ 2012-10-31 Steven Bosscher Jakub Jelinek PR tree-optimization/55018 * basic-block.h (dfs_find_deadend): New prototype. * cfganal.c (dfs_find_deadend): No longer static. Use bitmap instead of sbitmap for visited. (flow_dfs_compute_reverse_execute): Use dfs_find_deadend here, too. * dominance.c (calc_dfs_tree): If saw_unconnected, traverse from dfs_find_deadend of unconnected b instead of b directly. gcc/testsuite/ 2012-10-31 Steven Bosscher Jakub Jelinek PR tree-optimization/55018 * gcc.dg/torture/pr55018.c: New test. --- gcc-4.7.2/gcc/basic-block.h.~1~ 2012-08-06 16:34:27.000000000 +0200 +++ gcc-4.7.2/gcc/basic-block.h 2012-11-10 17:01:15.000000000 +0100 @@ -454,6 +454,7 @@ extern void redirect_edge_pred (edge, ba extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block); extern void clear_bb_flags (void); extern int post_order_compute (int *, bool, bool); +extern basic_block dfs_find_deadend (basic_block); extern int inverted_post_order_compute (int *); extern int pre_and_rev_post_order_compute (int *, int *, bool); extern int dfs_enumerate_from (basic_block, int, --- gcc-4.7.2/gcc/cfganal.c.~1~ 2011-04-10 20:46:45.000000000 +0200 +++ gcc-4.7.2/gcc/cfganal.c 2012-11-10 17:02:43.000000000 +0100 @@ -747,7 +747,9 @@ post_order_compute (int *post_order, boo } -/* Helper routine for inverted_post_order_compute. +/* Helper routine for inverted_post_order_compute + flow_dfs_compute_reverse_execute, and the reverse-CFG + deapth first search in dominance.c. BB has to belong to a region of CFG unreachable by inverted traversal from the exit. i.e. there's no control flow path from ENTRY to EXIT @@ -767,19 +769,17 @@ post_order_compute (int *post_order, boo that all blocks in the region are reachable by starting an inverted traversal from the returned block. */ -static basic_block +basic_block dfs_find_deadend (basic_block bb) { - sbitmap visited = sbitmap_alloc (last_basic_block); - sbitmap_zero (visited); + bitmap visited = BITMAP_ALLOC (NULL); for (;;) { - SET_BIT (visited, bb->index); if (EDGE_COUNT (bb->succs) == 0 - || TEST_BIT (visited, EDGE_SUCC (bb, 0)->dest->index)) + || ! bitmap_set_bit (visited, bb->index)) { - sbitmap_free (visited); + BITMAP_FREE (visited); return bb; } @@ -1132,7 +1132,7 @@ flow_dfs_compute_reverse_execute (depth_ /* Determine if there are unvisited basic blocks. */ FOR_BB_BETWEEN (bb, last_unvisited, NULL, prev_bb) if (!TEST_BIT (data->visited_blocks, bb->index)) - return bb; + return dfs_find_deadend (bb); return NULL; } --- gcc-4.7.2/gcc/dominance.c.~1~ 2010-11-30 12:41:24.000000000 +0100 +++ gcc-4.7.2/gcc/dominance.c 2012-11-10 17:01:15.000000000 +0100 @@ -377,14 +377,18 @@ calc_dfs_tree (struct dom_info *di, bool { FOR_EACH_BB_REVERSE (b) { + basic_block b2; if (di->dfs_order[b->index]) continue; - bitmap_set_bit (di->fake_exit_edge, b->index); - di->dfs_order[b->index] = di->dfsnum; - di->dfs_to_bb[di->dfsnum] = b; + b2 = dfs_find_deadend (b); + gcc_checking_assert (di->dfs_order[b2->index] == 0); + bitmap_set_bit (di->fake_exit_edge, b2->index); + di->dfs_order[b2->index] = di->dfsnum; + di->dfs_to_bb[di->dfsnum] = b2; di->dfs_parent[di->dfsnum] = di->dfs_order[last_basic_block]; di->dfsnum++; - calc_dfs_tree_nonrec (di, b, reverse); + calc_dfs_tree_nonrec (di, b2, reverse); + gcc_checking_assert (di->dfs_order[b->index]); } } } --- gcc-4.7.2/gcc/testsuite/gcc.dg/torture/pr55018.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.7.2/gcc/testsuite/gcc.dg/torture/pr55018.c 2012-11-10 17:01:15.000000000 +0100 @@ -0,0 +1,22 @@ +/* PR tree-optimization/55018 */ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-optimized" } */ + +void +foo (int x) +{ + unsigned int a = 0; + int b = 3; + if (x) + b = 0; +lab: + if (x) + goto lab; + a++; + if (b != 2) + __builtin_printf ("%u", a); + goto lab; +} + +/* { dg-final { scan-tree-dump "printf" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */