re PR debug/66688 (compare debug failure building Linux kernel on ppc64le)
authorJakub Jelinek <jakub@redhat.com>
Tue, 15 Dec 2015 07:46:23 +0000 (08:46 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 15 Dec 2015 07:46:23 +0000 (08:46 +0100)
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.

From-SVN: r231644

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr66688.c [new file with mode: 0644]
gcc/tree-cfgcleanup.c

index c90899e4c0d31fa4aee9e4f2314f1276978dac88..e36f0ed603ec0586d8371edad3126181fd45b083 100644 (file)
@@ -1,3 +1,11 @@
+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.
index d2349b950b2cb4727c1902c61f6bb166fd2dc98a..8f6436025eebff20dfcfd4763a73a29ebe523514 100644 (file)
@@ -1,3 +1,8 @@
+2015-12-15  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/66688
+       * gcc.dg/pr66688.c: New test.
+
 2015-12-15  Patrick Palka  <ppalka@gcc.gnu.org>
 
        PR c++/21802
diff --git a/gcc/testsuite/gcc.dg/pr66688.c b/gcc/testsuite/gcc.dg/pr66688.c
new file mode 100644 (file)
index 0000000..af6f844
--- /dev/null
@@ -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;
+}
index 40ad5ca33cd4d3867e646c31bc04942ef9b9b1ed..3f50c66af6060d29ea1072533b776028681a9f7d 100644 (file)
@@ -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;
 }