re PR ipa/63909 (ICE: SIGSEGV in ipa_icf_gimple::func_checker::compare_bb())
authorMartin Liska <mliska@suse.cz>
Wed, 10 Dec 2014 14:07:47 +0000 (15:07 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Wed, 10 Dec 2014 14:07:47 +0000 (14:07 +0000)
PR ipa/63909

        * gimple-iterator.h (gsi_start_bb_nondebug): New function.
* ipa-icf-gimple.c (func_checker::compare_bb): Correct iteration
replaces loop based on precomputed number of non-debug statements.
* gcc.dg/ipa/pr63909.c: New test.

From-SVN: r218578

gcc/ChangeLog
gcc/gimple-iterator.h
gcc/ipa-icf-gimple.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/pr63909.c [new file with mode: 0644]

index ccf4920..8d50258 100644 (file)
@@ -1,3 +1,9 @@
+2014-12-10  Martin Liska  <mliska@suse.cz>
+
+       * gimple-iterator.h (gsi_start_bb_nondebug): New function.
+       * ipa-icf-gimple.c (func_checker::compare_bb): Correct iteration
+       replaces loop based on precomputed number of non-debug statements.
+
 2014-12-08  Alexander Ivchenko  <alexander.ivchenko@intel.com>
 
        * config/linux.c (linux_has_ifunc_p): Remove.
index fb6cc07..e9602b3 100644 (file)
@@ -211,6 +211,19 @@ gsi_stmt (gimple_stmt_iterator i)
   return i.ptr;
 }
 
+/* Return a new iterator pointing to the first non-debug statement
+   in basic block BB.  */
+
+static inline gimple_stmt_iterator
+gsi_start_bb_nondebug (basic_block bb)
+{
+  gimple_stmt_iterator gsi = gsi_start_bb (bb);
+  while (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
+    gsi_next (&gsi);
+
+  return gsi;
+}
+
 /* Return a block statement iterator that points to the first non-label
    statement in block BB.  */
 
index 8f2a438..ec0290a 100644 (file)
@@ -559,24 +559,16 @@ func_checker::parse_labels (sem_bb *bb)
 bool
 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
 {
-  unsigned i;
   gimple_stmt_iterator gsi1, gsi2;
   gimple s1, s2;
 
-  if (bb1->nondbg_stmt_count != bb2->nondbg_stmt_count
-      || bb1->edge_count != bb2->edge_count)
-    return return_false ();
-
-  gsi1 = gsi_start_bb (bb1->bb);
-  gsi2 = gsi_start_bb (bb2->bb);
+  gsi1 = gsi_start_bb_nondebug (bb1->bb);
+  gsi2 = gsi_start_bb_nondebug (bb2->bb);
 
-  for (i = 0; i < bb1->nondbg_stmt_count; i++)
+  while (!gsi_end_p (gsi1))
     {
-      if (is_gimple_debug (gsi_stmt (gsi1)))
-       gsi_next_nondebug (&gsi1);
-
-      if (is_gimple_debug (gsi_stmt (gsi2)))
-       gsi_next_nondebug (&gsi2);
+      if (gsi_end_p (gsi2))
+       return return_false ();
 
       s1 = gsi_stmt (gsi1);
       s2 = gsi_stmt (gsi2);
@@ -646,10 +638,13 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
          return return_false_with_msg ("Unknown GIMPLE code reached");
        }
 
-      gsi_next (&gsi1);
-      gsi_next (&gsi2);
+      gsi_next_nondebug (&gsi1);
+      gsi_next_nondebug (&gsi2);
     }
 
+  if (!gsi_end_p (gsi2))
+    return return_false ();
+
   return true;
 }
 
index 3bbb497..0cac309 100644 (file)
@@ -1,3 +1,7 @@
+2014-12-10  Martin Liska  <mliska@suse.cz>
+
+       * gcc.dg/ipa/pr63909.c: New test.
+
 2014-12-10  Kai Tietz  <ktietz@redhat.com>
 
        PR c++/64127
diff --git a/gcc/testsuite/gcc.dg/ipa/pr63909.c b/gcc/testsuite/gcc.dg/ipa/pr63909.c
new file mode 100644 (file)
index 0000000..8538e21
--- /dev/null
@@ -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;
+}