This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix -fcompare-debug differences with __builtin_unreachable (PR bootstrap/41345)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Alexandre Oliva <aoliva at redhat dot com>
- Date: Mon, 26 Oct 2009 17:07:08 +0100
- Subject: [PATCH] Fix -fcompare-debug differences with __builtin_unreachable (PR bootstrap/41345)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As the following testcase shows, with -g gcc fails to remove unneeded code,
while with -g0 it optimizes out the function to just ret insn.
The problem is that the BB_HEAD (bb) == BB_END (bb) check doesn't account
with possible DEBUG_INSNs that might follow the BB note in an otherwise
empty basic block caused by __builtin_unreachable.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
2009-10-26 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/41345
* cfgcleanup.c (trivially_empty_bb_p): New function.
(try_optimize_bb): Use it instead of checking BB_HEAD == BB_END.
* gcc.dg/pr41345.c: New test.
--- gcc/cfgcleanup.c.jj 2009-09-03 09:59:40.000000000 +0200
+++ gcc/cfgcleanup.c 2009-10-26 13:33:07.000000000 +0100
@@ -958,7 +958,7 @@ old_insns_match_p (int mode ATTRIBUTE_UN
if (NOTE_INSN_BASIC_BLOCK_P (i1) && NOTE_INSN_BASIC_BLOCK_P (i2))
return true;
- p1 = PATTERN (i1);
+ p1 = PATTERN (i1);
p2 = PATTERN (i2);
if (GET_CODE (p1) != GET_CODE (p2))
@@ -1814,6 +1814,24 @@ try_crossjump_bb (int mode, basic_block
return changed;
}
+/* Return true if BB contains just bb note, or bb note followed
+ by only DEBUG_INSNs. */
+
+static bool
+trivially_empty_bb_p (basic_block bb)
+{
+ rtx insn = BB_END (bb);
+
+ while (1)
+ {
+ if (insn == BB_HEAD (bb))
+ return true;
+ if (!DEBUG_INSN_P (insn))
+ return false;
+ insn = PREV_INSN (insn);
+ }
+}
+
/* Do simple CFG optimizations - basic block merging, simplifying of jump
instructions etc. Return nonzero if changes were made. */
@@ -1865,14 +1883,10 @@ try_optimize_cfg (int mode)
__builtin_unreachable (). */
if (EDGE_COUNT (b->preds) == 0
|| (EDGE_COUNT (b->succs) == 0
- && BB_HEAD (b) == BB_END (b)
+ && trivially_empty_bb_p (b)
&& single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
{
c = b->prev_bb;
- if (dump_file)
- fprintf (dump_file, "Deleting block %i.\n",
- b->index);
-
delete_basic_block (b);
if (!(mode & CLEANUP_CFGLAYOUT))
changed = true;
--- gcc/testsuite/gcc.dg/pr41345.c.jj 2009-10-26 13:34:25.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr41345.c 2009-10-26 13:34:13.000000000 +0100
@@ -0,0 +1,14 @@
+/* PR bootstrap/41345 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -fcompare-debug" } */
+
+void
+foo (int *x)
+{
+ int a;
+ for (a = 0; a < 2; a++)
+ if (x[a])
+ goto lab;
+ __builtin_unreachable ();
+lab:;
+}
Jakub