diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a1d333be0955463a14cb7efb7ec0b74c38d2982d..cac010800fc365ba1a9ef25f4c5f143fb3a30c48 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2012-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	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  <Andreas.Krebbel@de.ibm.com>
 
 	* config/s390/s390.md ("*cmp<mode>_ccs"): Fix comment mentioning
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 70a292b671b2bfe691ada8cf9b3d7bd89070dbb6..a75ef954a563e49a52c7bcfacad45fff8d24db38 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/51719
+	* g++.dg/tree-prof/pr51719.C: New test.
+
 2012-01-03  Richard Guenther  <rguenther@suse.de>
 
 	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 0000000000000000000000000000000000000000..01e81ff66eda0f46fafcb25ea69c4252bf4b03cb
--- /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 2df04f56813761811a976c276d3b496c162a67ad..a6afd5515b522fe0f028328af63857182dcf61ea 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);