aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-06-07 11:48:53 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-06-07 11:48:53 +0200
commit308dc890dd4315560088e8e012d7ebddf0d887e7 (patch)
tree11da433f9003da60ec244aa6ae8f106e9d8f099e
parent34b6bcade4167c229808658e9fd8b59088b55c11 (diff)
downloadgcc-308dc890dd4315560088e8e012d7ebddf0d887e7.zip
gcc-308dc890dd4315560088e8e012d7ebddf0d887e7.tar.gz
gcc-308dc890dd4315560088e8e012d7ebddf0d887e7.tar.bz2
re PR gcov-profile/49299 (ICE in gimple_ic on profile feedback build)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr49299-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr49299-2.c34
-rw-r--r--gcc/value-prof.c34
5 files changed, 102 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 021a33a..eb60a74 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2ddc298..86d4954 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..dd45baf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr49299-1.c
@@ -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
index 0000000..220c8c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr49299-2.c
@@ -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;
+}
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 586a9b9..2b7a9d8 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -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)