On December 14, 2015 9:11:39 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >As the testcase used to show on ppc64le with slightly older trunk, >cleanup_control_flow_bb can be called on a bb with newly noreturn >call followed by debug stmts. With -g0, cleanup_control_flow_bb >removes the fallthru edge, so we need to do it even if followed by >debug >stmts. > >This patch is one possible way to fix this, another one is attached to >the >PR. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Thanks, Richard. >2015-12-14 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/66688 > * tree-cfgcleanup.c (cleanup_control_flow_bb): Handle > noreturn call followed only by debug stmts by removing > the debug stmts and handling it the same as if the noreturn > call is the last stmt. > > * gcc.dg/pr66688.c: New test. > >--- gcc/tree-cfgcleanup.c.jj 2015-12-02 20:26:59.000000000 +0100 >+++ gcc/tree-cfgcleanup.c 2015-12-14 17:34:10.748487811 +0100 >@@ -186,7 +186,7 @@ cleanup_control_flow_bb (basic_block bb) > we need to prune cfg. */ > retval |= gimple_purge_dead_eh_edges (bb); > >- gsi = gsi_last_bb (bb); >+ gsi = gsi_last_nondebug_bb (bb); > if (gsi_end_p (gsi)) > return retval; > >@@ -197,7 +197,10 @@ cleanup_control_flow_bb (basic_block bb) > > if (gimple_code (stmt) == GIMPLE_COND > || gimple_code (stmt) == GIMPLE_SWITCH) >- retval |= cleanup_control_expr_graph (bb, gsi); >+ { >+ gcc_checking_assert (gsi_stmt (gsi_last_bb (bb)) == stmt); >+ retval |= cleanup_control_expr_graph (bb, gsi); >+ } > else if (gimple_code (stmt) == GIMPLE_GOTO > && TREE_CODE (gimple_goto_dest (stmt)) == ADDR_EXPR > && (TREE_CODE (TREE_OPERAND (gimple_goto_dest (stmt), 0)) >@@ -210,6 +213,7 @@ cleanup_control_flow_bb (basic_block bb) > edge_iterator ei; > basic_block target_block; > >+ gcc_checking_assert (gsi_stmt (gsi_last_bb (bb)) == stmt); > /* First look at all the outgoing edges. Delete any outgoing > edges which do not go to the right block. For the one > edge which goes to the right block, fix up its flags. */ >@@ -242,9 +246,15 @@ cleanup_control_flow_bb (basic_block bb) > /* Check for indirect calls that have been turned into > noreturn calls. */ > else if (is_gimple_call (stmt) >- && gimple_call_noreturn_p (stmt) >- && remove_fallthru_edge (bb->succs)) >- retval = true; >+ && gimple_call_noreturn_p (stmt)) >+ { >+ /* If there are debug stmts after the noreturn call, remove them >+ now, they should be all unreachable anyway. */ >+ for (gsi_next (&gsi); !gsi_end_p (gsi); ) >+ gsi_remove (&gsi, true); >+ if (remove_fallthru_edge (bb->succs)) >+ retval = true; >+ } > > return retval; > } >--- gcc/testsuite/gcc.dg/pr66688.c.jj 2015-12-14 14:51:43.652481658 >+0100 >+++ gcc/testsuite/gcc.dg/pr66688.c 2015-12-14 14:51:05.000000000 +0100 >@@ -0,0 +1,39 @@ >+/* PR tree-optimization/66688 */ >+/* { dg-do compile } */ >+/* { dg-options "-O2 -fno-reorder-blocks -fcompare-debug" } */ >+ >+struct fdt_header { unsigned magic; } *a; >+ >+int d; >+ >+int >+__fswab32 (int p1) >+{ >+ return __builtin_bswap32 (p1); >+} >+ >+void >+fdt_set_magic (int p1) >+{ >+ struct fdt_header *b = a; >+ b->magic = __builtin_constant_p (p1) ? : __fswab32 (p1); >+} >+ >+int >+_fdt_sw_check_header () >+{ >+ int c = ((struct fdt_header *) 1)->magic; >+ if (c) >+ return 1; >+ return 0; >+} >+ >+int >+fdt_finish () >+{ >+ if (_fdt_sw_check_header ()) >+ if (d) >+ return 0; >+ fdt_set_magic (0); >+ return 0; >+} > > Jakub