The fix for this PR is to also schedule fixup of loops even if we're removing
an entry into an irreducible region -- that might scramble the loop structure
so we need to be careful.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2015-08-27  Marek Polacek  <pola...@redhat.com>

        PR middle-end/67005
        * tree-ssa-dce.c (remove_dead_stmt): Also schedule fixup if removing
        an entry into an irreducible region.

        * gcc.dg/torture/pr67005.c: New test.

diff --git gcc/testsuite/gcc.dg/torture/pr67005.c 
gcc/testsuite/gcc.dg/torture/pr67005.c
index e69de29..922c5c4 100644
--- gcc/testsuite/gcc.dg/torture/pr67005.c
+++ gcc/testsuite/gcc.dg/torture/pr67005.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+int a;
+void
+f (void)
+{
+  if (!a);
+  else
+  lbl:
+    a = a;
+
+  if (a)
+    a = 8;
+  goto lbl;
+}
diff --git gcc/tree-ssa-dce.c gcc/tree-ssa-dce.c
index 2d2edc8..b2cd23f 100644
--- gcc/tree-ssa-dce.c
+++ gcc/tree-ssa-dce.c
@@ -1125,10 +1125,12 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block 
bb)
        if (e != e2)
          {
            cfg_altered = true;
-           /* If we made a BB unconditionally exit a loop then this
-              transform alters the set of BBs in the loop.  Schedule
-              a fixup.  */
-           if (loop_exit_edge_p (bb->loop_father, e))
+           /* If we made a BB unconditionally exit a loop or removed
+              an entry into an irreducible region, then this transform
+              alters the set of BBs in the loop.  Schedule a fixup.  */
+           if (loop_exit_edge_p (bb->loop_father, e)
+               || (e2->flags & EDGE_IRREDUCIBLE_LOOP)
+               || (e2->dest->flags & BB_IRREDUCIBLE_LOOP))
              loops_state_set (LOOPS_NEED_FIXUP);
            remove_edge (e2);
          }

        Marek

Reply via email to