gcc/
	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.

testsuite/
	PR tree-optimization/55018
	* gcc.dg/torture/pr55018.c: New test.

Index: basic-block.h
===================================================================
--- basic-block.h	(revision 192893)
+++ basic-block.h	(working copy)
@@ -787,6 +787,7 @@ extern void remove_fake_exit_edges (void);
 extern void add_noreturn_fake_exit_edges (void);
 extern void connect_infinite_loops_to_exit (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,
Index: cfganal.c
===================================================================
--- cfganal.c	(revision 192893)
+++ cfganal.c	(working copy)
@@ -573,7 +573,9 @@ post_order_compute (int *post_order, bool include_
 }
 
 
-/* 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
@@ -593,19 +595,17 @@ post_order_compute (int *post_order, bool include_
    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;
         }
 
@@ -958,7 +958,7 @@ flow_dfs_compute_reverse_execute (depth_first_sear
   /* 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;
 }
Index: dominance.c
===================================================================
--- dominance.c	(revision 192893)
+++ dominance.c	(working copy)
@@ -377,14 +377,18 @@ calc_dfs_tree (struct dom_info *di, bool reverse)
 	{
 	  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]);
 	    }
 	}
     }
Index: testsuite/gcc.dg/torture/pr55018.c
===================================================================
--- testsuite/gcc.dg/torture/pr55018.c	(revision 0)
+++ testsuite/gcc.dg/torture/pr55018.c	(revision 0)
@@ -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" } } */
