re PR gcov-profile/49299 (ICE in gimple_ic on profile feedback build)
authorJakub Jelinek <jakub@redhat.com>
Tue, 7 Jun 2011 09:48:53 +0000 (11:48 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 7 Jun 2011 09:48:53 +0000 (11:48 +0200)
PR gcov-profile/49299
* value-prof.c (gimple_ic): Don't assume icall has
a fallthru edge.

* gcc.dg/tree-prof/pr49299-1.c: New test.
* gcc.dg/tree-prof/pr49299-2.c: New test.

From-SVN: r174738

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-prof/pr49299-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-prof/pr49299-2.c [new file with mode: 0644]
gcc/value-prof.c

index 021a33a..eb60a74 100644 (file)
@@ -1,3 +1,9 @@
+2011-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR gcov-profile/49299
+       * value-prof.c (gimple_ic): Don't assume icall has
+       a fallthru edge.
+
 2011-06-07  Ira Rosen  <ira.rosen@linaro.org>
 
        * tree-vectorizer.h (vect_recog_func_ptr): Make last argument to be
index 2ddc298..86d4954 100644 (file)
@@ -1,3 +1,9 @@
+2011-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR gcov-profile/49299
+       * gcc.dg/tree-prof/pr49299-1.c: New test.
+       * gcc.dg/tree-prof/pr49299-2.c: New test.
+
 2011-06-07  Ira Rosen  <ira.rosen@linaro.org>
 
        * lib/target-supports.exp
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr49299-1.c b/gcc/testsuite/gcc.dg/tree-prof/pr49299-1.c
new file mode 100644 (file)
index 0000000..dd45baf
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-options "-O2" } */
+
+__attribute__((noreturn)) void (*fn) (void);
+
+volatile int v;
+
+__attribute__((noreturn)) void
+fn0 (void)
+{
+  __builtin_exit (0);
+}
+
+__attribute__((noreturn)) void
+fn1 (void)
+{
+  __builtin_exit (1);
+}
+
+__attribute__((noinline, noclone)) void
+setfn (__attribute__((noreturn)) void (*x) (void))
+{
+  fn = x;
+}
+
+int
+main ()
+{
+  int i;
+  if (v < 1)
+    setfn (fn0);
+  else
+    setfn (fn1);
+  fn ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr49299-2.c b/gcc/testsuite/gcc.dg/tree-prof/pr49299-2.c
new file mode 100644 (file)
index 0000000..220c8c8
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-options "-O2" } */
+
+void (*fn) (void);
+
+volatile int v;
+
+__attribute__((noreturn)) void
+fn0 (void)
+{
+  __builtin_exit (0);
+}
+
+void
+fn1 (void)
+{
+}
+
+__attribute__((noinline, noclone)) void
+setfn (void (*x) (void))
+{
+  fn = x;
+}
+
+int
+main ()
+{
+  int i;
+  if (v < 1)
+    setfn (fn0);
+  else
+    setfn (fn1);
+  fn ();
+  return 0;
+}
index 586a9b9..2b7a9d8 100644 (file)
@@ -1145,9 +1145,9 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
 {
   gimple dcall_stmt, load_stmt, cond_stmt;
   tree tmp0, tmp1, tmpv, tmp;
-  basic_block cond_bb, dcall_bb, icall_bb, join_bb;
+  basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL;
   tree optype = build_pointer_type (void_type_node);
-  edge e_cd, e_ci, e_di, e_dj, e_ij;
+  edge e_cd, e_ci, e_di, e_dj = NULL, e_ij;
   gimple_stmt_iterator gsi;
   int lp_nr;
 
@@ -1194,12 +1194,19 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
   else
     {
       e_ij = find_fallthru_edge (icall_bb->succs);
-      e_ij->probability = REG_BR_PROB_BASE;
-      e_ij->count = all - count;
-      e_ij = single_pred_edge (split_edge (e_ij));
+      /* The indirect call might be noreturn.  */
+      if (e_ij != NULL)
+       {
+         e_ij->probability = REG_BR_PROB_BASE;
+         e_ij->count = all - count;
+         e_ij = single_pred_edge (split_edge (e_ij));
+       }
+    }
+  if (e_ij != NULL)
+    {
+      join_bb = e_ij->dest;
+      join_bb->count = all;
     }
-  join_bb = e_ij->dest;
-  join_bb->count = all;
 
   e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
   e_cd->probability = prob;
@@ -1211,12 +1218,15 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
 
   remove_edge (e_di);
 
-  e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
-  e_dj->probability = REG_BR_PROB_BASE;
-  e_dj->count = count;
+  if (e_ij != NULL)
+    {
+      e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
+      e_dj->probability = REG_BR_PROB_BASE;
+      e_dj->count = count;
 
-  e_ij->probability = REG_BR_PROB_BASE;
-  e_ij->count = all - count;
+      e_ij->probability = REG_BR_PROB_BASE;
+      e_ij->count = all - count;
+    }
 
   /* Insert PHI node for the call result if necessary.  */
   if (gimple_call_lhs (icall_stmt)