From a9730200523b035a4bb6db87b93811c170409443 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 3 Jan 2012 10:09:41 +0100 Subject: [PATCH] re PR tree-optimization/51719 (ICE: verify_gimple failed: LHS in noreturn call with -fpartial-inlining -fprofile-use and exceptions) PR tree-optimization/51719 * value-prof.c (gimple_ic): When indirect call isn't noreturn, but direct call is, clear direct call's lhs and don't add fallthrough edge from dcall_bb to join_bb and PHIs. * g++.dg/tree-prof/pr51719.C: New test. From-SVN: r182832 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/tree-prof/pr51719.C | 27 +++++++++++++++++++++++++++ gcc/value-prof.c | 23 ++++++++++++++++------- 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-prof/pr51719.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1d333b..cac0108 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-01-03 Jakub Jelinek + + PR tree-optimization/51719 + * value-prof.c (gimple_ic): When indirect call isn't noreturn, + but direct call is, clear direct call's lhs and don't add fallthrough + edge from dcall_bb to join_bb and PHIs. + 2012-01-03 Andreas Krebbel * config/s390/s390.md ("*cmp_ccs"): Fix comment mentioning diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 70a292b..a75ef95 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-01-03 Jakub Jelinek + + PR tree-optimization/51719 + * g++.dg/tree-prof/pr51719.C: New test. + 2012-01-03 Richard Guenther PR middle-end/51730 diff --git a/gcc/testsuite/g++.dg/tree-prof/pr51719.C b/gcc/testsuite/g++.dg/tree-prof/pr51719.C new file mode 100644 index 0000000..01e81ff --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-prof/pr51719.C @@ -0,0 +1,27 @@ +// PR tree-optimization/51719 +// { dg-options "-O -fpartial-inlining" } + +int +bar (void) +{ + throw 1; +} + +int __attribute__ ((noinline, noclone)) +foo (int (*f) (void)) +{ + try + { + return (*f) (); + } + catch (...) + { + } + return 0; +} + +int +main () +{ + return foo (bar); +} diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 2df04f5..a6afd55 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -1,5 +1,5 @@ /* Transformations based on profile information for values. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -1149,7 +1149,7 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, tree optype = build_pointer_type (void_type_node); edge e_cd, e_ci, e_di, e_dj = NULL, e_ij; gimple_stmt_iterator gsi; - int lp_nr; + int lp_nr, dflags; cond_bb = gimple_bb (icall_stmt); gsi = gsi_for_stmt (icall_stmt); @@ -1176,6 +1176,9 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, update_stmt (icall_stmt); dcall_stmt = gimple_copy (icall_stmt); gimple_call_set_fndecl (dcall_stmt, direct_call->decl); + dflags = flags_from_decl_or_type (direct_call->decl); + if ((dflags & ECF_NORETURN) != 0) + gimple_call_set_lhs (dcall_stmt, NULL_TREE); gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT); /* Fix CFG. */ @@ -1220,17 +1223,23 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, 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; + if ((dflags & ECF_NORETURN) != 0) + e_ij->count = all; + else + { + e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU); + e_dj->probability = REG_BR_PROB_BASE; + e_dj->count = count; + 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) - && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME) + && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME + && (dflags & ECF_NORETURN) == 0) { tree result = gimple_call_lhs (icall_stmt); gimple phi = create_phi_node (result, join_bb); -- 2.7.4