Bug 45621 - [4.6 Regression] ICE: verify_cgraph_node failed: inlined_to pointer is set but no predecessors found with -fipa-cp-clone -flto
Summary: [4.6 Regression] ICE: verify_cgraph_node failed: inlined_to pointer is set bu...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.6.0
: P1 normal
Target Milestone: 4.6.0
Assignee: Jan Hubicka
URL:
Keywords: ice-on-valid-code, lto
Depends on:
Blocks:
 
Reported: 2010-09-09 19:30 UTC by Zdenek Sojka
Modified: 2010-10-15 01:24 UTC (History)
3 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build:
Known to work: 4.5.2
Known to fail: 4.6.0
Last reconfirmed: 2010-09-17 01:07:45


Attachments
archive with reduced testcase (305 bytes, application/octet-stream)
2010-09-09 19:35 UTC, Zdenek Sojka
Details
proposed patch (994 bytes, patch)
2010-09-17 12:17 UTC, Jan Hubicka
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Zdenek Sojka 2010-09-09 19:30:52 UTC
Command line:
$ g++ -O2 -fipa-cp-clone -flto -nostdlib -r file1.cpp file2.cpp

Compiler output:
$ g++ -O2 -fipa-cp-clone -flto -nostdlib -r file1.cpp file2.cpp
lto1: error: inlined_to pointer is set but no predecessors found
_ZN1S2v1Ev.constprop.1/6(-1) @0x7f44a7e9eac0 (asm: _ZN1S2v1Ev.constprop.1) (inline copy in foo/0) (clone of _ZN1S2v1Ev.constprop.1/1) availability:local analyzed 13 time, 12 benefit 4 size, 3 benefit reachable body local finalized inlinable
  called by: 
  calls: v2/5 (1.00 per call) 
  References:  var:s (addr)
  Refering this function: 
lto1: internal compiler error: verify_cgraph_node failed
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
lto-wrapper: /mnt/svn/gcc-trunk/binary-164077-lto-fortran-checking-yes-rtl-df/bin/g++ returned 1 exit status
collect2: lto-wrapper returned 1 exit status

Tested revisions:
Comment 1 Zdenek Sojka 2010-09-09 19:35:59 UTC
Created attachment 21757 [details]
archive with reduced testcase

$ g++ -O2 -fipa-cp-clone -flto -nostdlib -r file1.cpp file2.cpp

----- file1.cpp -----
#include "header.h"

void
foo ()
{
  s.v1 ();
  s.m ();
}
---------------------
----- file2.cpp -----
#include "header.h"

void
S::v1 ()
{
  v2 ();
}

void
S::m ()
{
  v1 ();
}
---------------------
----- header.h -----
struct S
{
  void m ();
  virtual void v1 ();
  virtual void v2 ();
};

extern S s;
--------------------

I pressed "Commit" too early, so there is the rest:
Tested revisions:
r164077 - crash
r164096 - crash
r161659 - OK
Comment 2 Jan Hubicka 2010-09-17 01:05:57 UTC
OK, problem is that we both devirtualize and clone the destination function.
Then when producing clone, we run into:
cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
                                        gimple old_stmt, tree old_call, gimple new_stmt)
{
  tree new_call = (is_gimple_call (new_stmt)) ? gimple_call_fndecl (new_stmt) : 0;

  /* We are seeing indirect calls, then there is nothing to update.  */
  if (!new_call && !old_call)
    return;
  /* See if we turned indirect call into direct call or folded call to one builtin
     into different bultin.  */
  if (old_call != new_call)
    { 
      struct cgraph_edge *e = cgraph_edge (node, old_stmt);
      struct cgraph_edge *ne = NULL;
      gcov_type count;
      int frequency;
      int loop_nest;

      if (e)
        { 
          /* See if the edge is already there and has the correct callee.  It
             might be so because of indirect inlining has already updated
             it.  */
          if (new_call && e->callee && e->callee->decl == new_call)
            return;

          /* Otherwise remove edge and create new one; we can't simply redirect
             since function has changed, so inline plan and other information
             attached to edge is invalid.  */

and kill the inline plan.  This code is intended to handle bulitins, I guess
we will need to look out if the decl can be redirected to decl in the function.

Honza
Comment 3 Jan Hubicka 2010-09-17 01:07:45 UTC
testing patch.
Comment 4 Jan Hubicka 2010-09-17 12:17:29 UTC
Created attachment 21818 [details]
proposed patch
Comment 5 Richard Biener 2010-09-29 15:29:31 UTC
Any update?
Comment 6 Jan Hubicka 2010-10-14 18:59:58 UTC
The testing went fine, I just wanted to give more tought if some cheaper self testing can be made instead of keeping clone info and then forgot about the patch.
Will re-test and commit.
Comment 7 Jan Hubicka 2010-10-15 01:20:59 UTC
Author: hubicka
Date: Fri Oct 15 01:20:55 2010
New Revision: 165492

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=165492
Log:

	PR middle-end/45621
	* g++.dg/lto/pr45621.h : New.
	* g++.dg/lto/pr45621_0.C: New.
	* g++.dg/lto/pr45621_1.C: New.
	* cgraph.c (cgraph_update_edges_for_call_stmt_node): When new call is
	redirected to clone, be happy.
	* cgraph.h (cgraph node): Enable former_clone_of unconditinally.
	* cgraphunit.c (verify_cgraph_node, cgraph_materialize_clone): Handle
	former_clone_of unconditinally.

Added:
    trunk/gcc/testsuite/g++.dg/lto/pr45621.h
    trunk/gcc/testsuite/g++.dg/lto/pr45621_0.C
    trunk/gcc/testsuite/g++.dg/lto/pr45621_1.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cgraph.c
    trunk/gcc/cgraph.h
    trunk/gcc/cgraphunit.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Jan Hubicka 2010-10-15 01:24:04 UTC
Fixed.