From: jakub Date: Tue, 15 Dec 2015 07:46:23 +0000 (+0000) Subject: PR tree-optimization/66688 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f531aaf53debe0e2cfd4b4365e3daf492b24170;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231644 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c90899e4c0d3..e36f0ed603ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-12-15 Jakub Jelinek + + 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. + 2015-12-14 Steve Ellcey * config/mips/mips.c (mips_promote_function_mode): New function. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d2349b950b2c..8f6436025eeb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-15 Jakub Jelinek + + PR tree-optimization/66688 + * gcc.dg/pr66688.c: New test. + 2015-12-15 Patrick Palka PR c++/21802 diff --git a/gcc/testsuite/gcc.dg/pr66688.c b/gcc/testsuite/gcc.dg/pr66688.c new file mode 100644 index 000000000000..af6f8443a7c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr66688.c @@ -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; +} diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 40ad5ca33cd4..3f50c66af606 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -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; }