This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix -fcompare-debug failures caused by fixup_noreturn_call (PR debug/63284)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <rguenther at suse dot de>, Jeff Law <law at redhat dot com>, Alexandre Oliva <aoliva at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 17 Sep 2014 20:20:41 +0200
- Subject: [PATCH] Fix -fcompare-debug failures caused by fixup_noreturn_call (PR debug/63284)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following testcase fails on 4.9 branch (shows
undesirable difference in *.optimized dump on the trunk, but
doesn't report -fcompare-debug failure there, and in 4.8 is latent).
The problem is that if we have a noreturn stmt followed by only
debug stmt, fixup_noreturn_call will try to split_block after the
noreturn call, but with -g0 there are never debug stmts and thus
we would not split the block; that can lead to different order of bb
predecessors, different order of PHI args etc.
As nothing after noreturn call really matters, this patch if there are
only debug stmts after noreturn call removes the debug stmts instead of
the undesirable splitting of the block.
Bootstrapped/regtested on x86_64-linux and i686-linux on the trunk and on
the 4.9 branch, ok for trunk/4.9 and eventually 4.8 too?
2014-09-17 Jakub Jelinek <jakub@redhat.com>
PR debug/63284
* tree-cfgcleanup.c (fixup_noreturn_call): Don't split block
if there are only debug stmts after the noreturn call, instead
remove the debug stmts.
* gcc.dg/pr63284.c: New test.
--- gcc/tree-cfgcleanup.c.jj 2014-09-01 13:33:11.000000000 +0200
+++ gcc/tree-cfgcleanup.c 2014-09-17 11:01:53.448165423 +0200
@@ -565,7 +565,20 @@ fixup_noreturn_call (gimple stmt)
/* First split basic block if stmt is not last. */
if (stmt != gsi_stmt (gsi_last_bb (bb)))
- split_block (bb, stmt);
+ {
+ if (stmt == gsi_stmt (gsi_last_nondebug_bb (bb)))
+ {
+ /* Don't split if there are only debug stmts
+ after stmt, that can result in -fcompare-debug
+ failures. Remove the debug stmts instead,
+ they should be all unreachable anyway. */
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ for (gsi_next (&gsi); !gsi_end_p (gsi); )
+ gsi_remove (&gsi, true);
+ }
+ else
+ split_block (bb, stmt);
+ }
changed |= remove_fallthru_edge (bb->succs);
--- gcc/testsuite/gcc.dg/pr63284.c.jj 2014-09-17 10:56:59.699677715 +0200
+++ gcc/testsuite/gcc.dg/pr63284.c 2014-09-17 10:56:39.000000000 +0200
@@ -0,0 +1,42 @@
+/* PR debug/63284 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+int a[10], *b, *d, c, f;
+int fn2 (void);
+void fn3 (void);
+void fn4 (int);
+
+static int
+fn1 (int x)
+{
+ int e = a[0];
+ if (e)
+ return 1;
+ if (b)
+ switch (x)
+ {
+ case 1:
+ if (d)
+ e = fn2 ();
+ else
+ fn3 ();
+ break;
+ case 0:
+ if (d)
+ {
+ fn3 ();
+ if (c)
+ fn4 (1);
+ }
+ else
+ fn4 (0);
+ }
+ return e;
+}
+
+void
+fn6 (void)
+{
+ f = fn1 (0);
+}
Jakub