Hello.

Following patch fixes ICE in IPA ICF. Problem was that number of non-debug 
statements in a BB can
change (for instance by IPA split), so that the number is recomputed.

Patch can bootstrap on x86_64-linux-pc and no regression has been seen.
Ready for trunk?

Thanks,
Martin
gcc/ChangeLog:

2014-11-20  Martin Liska  <mli...@suse.cz>

        * gimple-iterator.h (gsi_nondebug_stmt_count): New function.
        * ipa-icf-gimple.c (func_checker::compare_bb): Number of BB
        is recomputed because it can be split.

gcc/testsuite/ChangeLog:

2014-11-20  Martin Liska  <mli...@suse.cz>

        * gcc.dg/ipa/pr63909.c: New test.
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
index fb6cc07..f73b1f6 100644
--- a/gcc/gimple-iterator.h
+++ b/gcc/gimple-iterator.h
@@ -331,4 +331,18 @@ gsi_seq (gimple_stmt_iterator i)
   return *i.seq;
 }
 
+/* Return number of nondebug statements in basic block BB.  */
+
+static inline unsigned
+gsi_nondebug_stmt_count (basic_block bb)
+{
+  unsigned c = 0;
+  for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+       gsi_next (&gsi))
+    if (!is_gimple_debug (gsi_stmt (gsi)))
+      c++;
+
+  return c;
+}
+
 #endif /* GCC_GIMPLE_ITERATOR_H */
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 8f2a438..83661ac 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -563,6 +563,9 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
   gimple_stmt_iterator gsi1, gsi2;
   gimple s1, s2;
 
+  bb1->nondbg_stmt_count = gsi_nondebug_stmt_count (bb1->bb);
+  bb2->nondbg_stmt_count = gsi_nondebug_stmt_count (bb2->bb);
+
   if (bb1->nondbg_stmt_count != bb2->nondbg_stmt_count
       || bb1->edge_count != bb2->edge_count)
     return return_false ();
diff --git a/gcc/testsuite/gcc.dg/ipa/pr63909.c b/gcc/testsuite/gcc.dg/ipa/pr63909.c
new file mode 100644
index 0000000..8538e21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr63909.c
@@ -0,0 +1,27 @@
+/* { dg-options "-O2 -fno-guess-branch-probability" } */
+
+int z;
+
+__attribute__((noinline))
+void g ()
+{
+  if (++z)
+    __builtin_exit (0);
+  g ();
+}
+
+__attribute__((noinline))
+void f ()
+{
+  if (++z)
+    __builtin_exit (0);
+  f ();
+}
+
+int main()
+{
+  f ();
+  g ();
+
+  return 0;
+}

Reply via email to