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


Reply via email to