+2015-12-15 Jakub Jelinek <jakub@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.
+
2015-12-14 Steve Ellcey <sellcey@imgtec.com>
* config/mips/mips.c (mips_promote_function_mode): New function.
--- /dev/null
+/* 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;
+}
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;
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))
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. */
/* 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;
}