diff mbox

Fix gimple-fold

Message ID 53283E3B.4050700@suse.cz
State New
Headers show

Commit Message

Martin Liška March 18, 2014, 12:38 p.m. UTC
Hello,
     I found ICE in Chromium compiled with LTO. There's a call that is 
proved by ipa-devirt as __builtin_unreachable; same decision is done by 
gimple-fold and this call is replaced by GIMPLE_CALL and GIMPLE_ASSIGN 
(in this order). After that condition for 
cgraph_update_edges_for_call_stmt_node is not satisfied and 
corresponding cgraph_edge is not updated. Thus a verifier reports a 
wrong edge.

Bootstrapped and tested on a x86_64 machine.


Changelog:
2014-03-18  Martin Liska  <mliska@suse.cz>

         * cgraph.c (cgraph_update_edges_for_call_stmt_node): added case when
         gimple call statement is updated.
         * gimple-fold.c (gimple_fold_call): changed order for GIMPLE_ASSIGN and
         GIMPLE_CALL, where gsi iterator still points to GIMPLE CALL.

OK for trunk?

Thank you,
Martin

Comments

Richard Biener March 18, 2014, 1:07 p.m. UTC | #1
On Tue, Mar 18, 2014 at 1:38 PM, Martin Liška <mliska@suse.cz> wrote:
> Hello,
>     I found ICE in Chromium compiled with LTO. There's a call that is proved
> by ipa-devirt as __builtin_unreachable; same decision is done by gimple-fold
> and this call is replaced by GIMPLE_CALL and GIMPLE_ASSIGN (in this order).
> After that condition for cgraph_update_edges_for_call_stmt_node is not
> satisfied and corresponding cgraph_edge is not updated. Thus a verifier
> reports a wrong edge.

You should be able to simply do

  update_call_from_tree (gsi, def);
  gsi_insert_before (gsi, new_stmt, GSI_NEW_STMT);

also cgraph_edge (node, old_stmt) is already computed in 'e' AFAICS.

Richard.

> Bootstrapped and tested on a x86_64 machine.
>
>
> Changelog:
> 2014-03-18  Martin Liska  <mliska@suse.cz>
>
>         * cgraph.c (cgraph_update_edges_for_call_stmt_node): added case when
>         gimple call statement is updated.
>         * gimple-fold.c (gimple_fold_call): changed order for GIMPLE_ASSIGN
> and
>         GIMPLE_CALL, where gsi iterator still points to GIMPLE CALL.
>
> OK for trunk?
>
> Thank you,
> Martin
>
>
Jakub Jelinek March 18, 2014, 1:13 p.m. UTC | #2
Hi!

> > 2014-03-18  Martin Liska  <mliska@suse.cz>
> >
> >         * cgraph.c (cgraph_update_edges_for_call_stmt_node): added case when
> >         gimple call statement is updated.

Capital letter after :

> >         * gimple-fold.c (gimple_fold_call): changed order for GIMPLE_ASSIGN and

Likewise here.

	Jakub
diff mbox

Patch

diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index a15b6bc..cd68894 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1519,7 +1519,11 @@  cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
 		{
 		  if (callee->decl == new_call
 		      || callee->former_clone_of == new_call)
-		    return;
+                    {
+                      cgraph_set_call_stmt (cgraph_edge (node, old_stmt),
+                                            new_stmt);
+		      return;
+                    }
 		  callee = callee->clone_of;
 		}
 	    }
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index eafdb2d..a033fbc 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1153,8 +1153,14 @@  gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
 		    {
 		      tree var = create_tmp_var (TREE_TYPE (lhs), NULL);
 		      tree def = get_or_create_ssa_default_def (cfun, var);
-		      gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
-		      update_call_from_tree (gsi, def);
+
+                      /* To satisfy condition for
+                         cgraph_update_edges_for_call_stmt_node,
+                         we need to preserve GIMPLE_CALL statement
+                         at position of GSI iterator.  */
+                      gimple_stmt_iterator oldgsi = *gsi;
+		      gsi_insert_before (gsi, new_stmt, GSI_NEW_STMT);
+		      update_call_from_tree (&oldgsi, def);
 		    }
 		  else
 		    gsi_replace (gsi, new_stmt, true);