diff mbox

PR ipa/63909 ICE: SIGSEGV in ipa_icf_gimple::func_checker::compare_bb()

Message ID 546E1740.2060001@suse.cz
State New
Headers show

Commit Message

Martin Liška Nov. 20, 2014, 4:30 p.m. UTC
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  <mliska@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  <mliska@suse.cz>

	* gcc.dg/ipa/pr63909.c: New test.

Comments

Richard Biener Nov. 20, 2014, 4:41 p.m. UTC | #1
On Thu, Nov 20, 2014 at 5:30 PM, Martin Liška <mliska@suse.cz> wrote:
> 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.

Huh, so can it get different for both candidates?  I think the stmt compare
loop should be terminated on gsi_end_p of either iterator and return
false for any remaining non-debug-stmts on the other.

Thus, not walk all stmts twice here.

As IPA split is run early I don't see how it should affect a real IPA
pass though?

Thanks,
Richard.

> Patch can bootstrap on x86_64-linux-pc and no regression has been seen.
> Ready for trunk?
>
> Thanks,
> Martin
diff mbox

Patch

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;
+}