public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/42228]  New: verify_cgraph_node failed:node has wrong clone_of
@ 2009-11-30 10:04 dcb314 at hotmail dot com
  2009-11-30 10:07 ` [Bug c++/42228] " dcb314 at hotmail dot com
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: dcb314 at hotmail dot com @ 2009-11-30 10:04 UTC (permalink / raw)
  To: gcc-bugs

I just tried to compile package libcrypto++ with the GNU C++ compiler
version 4.5 snapshot 20091126 and the compiler said

validat2.cpp: At global scope:
validat2.cpp:764:1: error: node has wrong clone_of
validat2.cpp:764:1: error: double linked list of clones corrupted
CryptoPP::DL_FixedBasePrecomputationImpl<T>::DL_FixedBasePrecomputationImpl()
[with T = CryptoPP::ECPPoint]/4286(-1) @0x2affd636b110 (clone of
CryptoPP::DL_FixedBasePrecomputationImpl<T>::DL_FixedBasePrecomputationImpl()
[with T = CryptoPP::ECPPoint]/5234) availability:available 30 time, 19 benefit
(41 after inlining) 17 size, 11 benefit (23 after inlining) body finalized
inlinable
  called by:
  calls: CryptoPP::Integer::Integer()/7921 (1.00 per call)
CryptoPP::ECPPoint::~ECPPoint()/1510
validat2.cpp:764:1: 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.

Preprocessed source code attached. Flag -O3 required.


-- 
           Summary: verify_cgraph_node failed:node has wrong clone_of
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dcb314 at hotmail dot com
  GCC host triplet: suse-linux-x86_64


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/42228] verify_cgraph_node failed:node has wrong clone_of
  2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
@ 2009-11-30 10:07 ` dcb314 at hotmail dot com
  2009-11-30 10:41 ` [Bug middle-end/42228] [4.5 Regression] " rguenth at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: dcb314 at hotmail dot com @ 2009-11-30 10:07 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from dcb314 at hotmail dot com  2009-11-30 10:06 -------
Created an attachment (id=19186)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=19186&action=view)
gzipped C++ source code


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/42228] [4.5 Regression] verify_cgraph_node failed:node has wrong clone_of
  2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
  2009-11-30 10:07 ` [Bug c++/42228] " dcb314 at hotmail dot com
@ 2009-11-30 10:41 ` rguenth at gcc dot gnu dot org
  2009-12-02 12:16 ` rguenth at gcc dot gnu dot org
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2009-11-30 10:41 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from rguenth at gcc dot gnu dot org  2009-11-30 10:41 -------
Confirmed.


-- 

rguenth at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu dot
                   |                            |org
             Status|UNCONFIRMED                 |NEW
          Component|c++                         |middle-end
     Ever Confirmed|0                           |1
           Keywords|                            |ice-checking, ice-on-valid-
                   |                            |code
      Known to work|                            |4.4.2
   Last reconfirmed|0000-00-00 00:00:00         |2009-11-30 10:41:11
               date|                            |
            Summary|verify_cgraph_node          |[4.5 Regression]
                   |failed:node has wrong       |verify_cgraph_node
                   |clone_of                    |failed:node has wrong
                   |                            |clone_of
   Target Milestone|---                         |4.5.0


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/42228] [4.5 Regression] verify_cgraph_node failed:node has wrong clone_of
  2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
  2009-11-30 10:07 ` [Bug c++/42228] " dcb314 at hotmail dot com
  2009-11-30 10:41 ` [Bug middle-end/42228] [4.5 Regression] " rguenth at gcc dot gnu dot org
@ 2009-12-02 12:16 ` rguenth at gcc dot gnu dot org
  2009-12-08 14:16 ` reichelt at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2009-12-02 12:16 UTC (permalink / raw)
  To: gcc-bugs



-- 

rguenth at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P1


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/42228] [4.5 Regression] verify_cgraph_node failed:node has wrong clone_of
  2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
                   ` (2 preceding siblings ...)
  2009-12-02 12:16 ` rguenth at gcc dot gnu dot org
@ 2009-12-08 14:16 ` reichelt at gcc dot gnu dot org
  2009-12-10 17:36 ` hubicka at ucw dot cz
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: reichelt at gcc dot gnu dot org @ 2009-12-08 14:16 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from reichelt at gcc dot gnu dot org  2009-12-08 14:16 -------
After removing a couple of lines from the preprocessed code I end up with the
same problem as in PR41290. Apparently this bug hasn't been fixed and still
haunts us.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/42228] [4.5 Regression] verify_cgraph_node failed:node has wrong clone_of
  2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
                   ` (3 preceding siblings ...)
  2009-12-08 14:16 ` reichelt at gcc dot gnu dot org
@ 2009-12-10 17:36 ` hubicka at ucw dot cz
  2009-12-10 20:51 ` hubicka at gcc dot gnu dot org
  2009-12-11 11:17 ` hubicka at gcc dot gnu dot org
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at ucw dot cz @ 2009-12-10 17:36 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from hubicka at ucw dot cz  2009-12-10 17:36 -------
Subject: Re:  [4.5 Regression] verify_cgraph_node failed:node has wrong
clone_of

Hi,
it turns out that this testcase seems firs tthat excercise code path
where clone is created partially inlined and as a result of later
optimization out of line copy of that clone is no longer needed.  It
shows I got quite few updates of the clone tree wrong here.

Sadly I failed to distille small testcase, but I am testing the
following (it contains also few other minor fixes I spotted while
proofreading the code)

        * cgraph.c (cgraph_create_edge_including_clones): Add old_stmt
parameter;
        update edge if it already exists.
        (cgraph_remove_node): Handle correctly cases where we are removing node
having
        clones.
        * cgraph.h (cgraph_create_edge_including_clones): Declare.
        (verify_cgraph_node): Add missing error_found = true code.
        (cgraph_materialize_all_clones): Remove call edges of dead nodes.
        * ipa.c (cgraph_remove_unreachable_nodes): Correctly look for master
        clone; fix double linked list removal.
        * tree-inline.c (copy_bb): Update cgraph_create_edge_including_clones
call;
        fix frequency of newly created edge.
Index: cgraph.c
===================================================================
--- cgraph.c    (revision 155090)
+++ cgraph.c    (working copy)
@@ -829,7 +829,8 @@ cgraph_set_call_stmt_including_clones (s
 }

 /* Like cgraph_create_edge walk the clone tree and update all clones sharing
-   same function body.
+   same function body.  If clones already have edge for OLD_STMT; only
+   update the edge same way as cgraph_set_call_stmt_including_clones does.

    TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
    frequencies of the clones.  */
@@ -837,6 +838,7 @@ cgraph_set_call_stmt_including_clones (s
 void
 cgraph_create_edge_including_clones (struct cgraph_node *orig,
                                     struct cgraph_node *callee,
+                                    gimple old_stmt,
                                     gimple stmt, gcov_type count,
                                     int freq, int loop_depth,
                                     cgraph_inline_failed_t reason)
@@ -854,9 +856,15 @@ cgraph_create_edge_including_clones (str
   if (node)
     while (node != orig)
       {
-        /* It is possible that we already constant propagated into the clone
-          and turned indirect call into dirrect call.  */
-        if (!cgraph_edge (node, stmt))
+       struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
+
+        /* It is possible that clones already contain the edge while
+          master didn't.  Either we promoted indirect call into direct
+          call in the clone or we are processing clones of unreachable
+          master where edges has been rmeoved.  */
+       if (edge)
+         cgraph_set_call_stmt (edge, stmt);
+       else if (!cgraph_edge (node, stmt))
          {
            edge = cgraph_create_edge (node, callee, stmt, count,
                                       freq, loop_depth);
@@ -1337,11 +1345,15 @@ cgraph_remove_node (struct cgraph_node *
              = next_inline_clone->prev_sibling_clone;
          if (next_inline_clone->prev_sibling_clone)
            {
+             gcc_assert (node->clones != next_inline_clone);
              next_inline_clone->prev_sibling_clone->next_sibling_clone
                = next_inline_clone->next_sibling_clone;
            }
          else
-          node->clones = next_inline_clone->next_sibling_clone;
+           {
+             gcc_assert (node->clones == next_inline_clone);
+             node->clones = next_inline_clone->next_sibling_clone;
+           }

          new_clones = node->clones;
          node->clones = NULL;
@@ -1355,6 +1367,8 @@ cgraph_remove_node (struct cgraph_node *
          next_inline_clone->next_sibling_clone = NULL;
          if (node->clone_of)
            {
+             if (node->clone_of->clones)
+               node->clone_of->clones->prev_sibling_clone = next_inline_clone;
              next_inline_clone->next_sibling_clone = node->clone_of->clones;
              node->clone_of->clones = next_inline_clone;
            }
@@ -1389,8 +1403,6 @@ cgraph_remove_node (struct cgraph_node *
        }

     }
-  else
-    gcc_assert (node->clone_of);
   if (node->prev_sibling_clone)
     node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
   else if (node->clone_of)
@@ -1399,15 +1411,33 @@ cgraph_remove_node (struct cgraph_node *
     node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
   if (node->clones)
     {
-      struct cgraph_node *n;
+      struct cgraph_node *n, *next;

-      for (n = node->clones; n->next_sibling_clone; n = n->next_sibling_clone)
-       n->clone_of = node->clone_of;
-      n->clone_of = node->clone_of;
-      n->next_sibling_clone = node->clone_of->clones;
-      if (node->clone_of->clones)
-       node->clone_of->clones->prev_sibling_clone = n;
-      node->clone_of->clones = node->clones;
+      if (node->clone_of)
+        {
+         for (n = node->clones; n->next_sibling_clone; n =
n->next_sibling_clone)
+           n->clone_of = node->clone_of;
+         n->clone_of = node->clone_of;
+         n->next_sibling_clone = node->clone_of->clones;
+         if (node->clone_of->clones)
+           node->clone_of->clones->prev_sibling_clone = n;
+         node->clone_of->clones = node->clones;
+       }
+      else
+        {
+         /* We are removing node with clones.  this makes clones inconsistent,
+            but assume they will be removed subsequently and just keep clone
+            tree intact.  This can happen in unreachable function removal
since
+            we remove unreachable functions in random order, not by bottom-up
+            walk of clone trees.  */
+         for (n = node->clones; n; n = next)
+           {
+              next = n->next_sibling_clone;
+              n->next_sibling_clone = NULL;
+              n->prev_sibling_clone = NULL;
+              n->clone_of = NULL;
+           }
+       }
     }

   while (node->same_body)
Index: cgraph.h
===================================================================
--- cgraph.h    (revision 155090)
+++ cgraph.h    (working copy)
@@ -445,7 +445,7 @@ void cgraph_set_call_stmt (struct cgraph
 void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple,
gimple);
 void cgraph_create_edge_including_clones (struct cgraph_node *,
                                          struct cgraph_node *,
-                                         gimple, gcov_type, int, int,
+                                         gimple, gimple, gcov_type, int, int,
                                          cgraph_inline_failed_t);
 void cgraph_update_edges_for_call_stmt (gimple, tree, gimple);
 struct cgraph_local_info *cgraph_local_info (tree);
Index: cgraphunit.c
===================================================================
--- cgraphunit.c        (revision 155090)
+++ cgraphunit.c        (working copy)
@@ -749,6 +749,7 @@ verify_cgraph_node (struct cgraph_node *
                          {
                            error ("edge points to same body alias:");
                            debug_tree (e->callee->decl);
+                           error_found = true;
                          }
                        else if (!clone_of_p (cgraph_node (decl), e->callee)
                                 && !e->callee->global.inlined_to)
@@ -757,6 +758,7 @@ verify_cgraph_node (struct cgraph_node *
                            debug_tree (e->callee->decl);
                            fprintf (stderr," Instead of:");
                            debug_tree (decl);
+                           error_found = true;
                          }
                        e->aux = (void *)1;
                      }
@@ -2248,6 +2250,9 @@ cgraph_materialize_all_clones (void)
            }
        }
     }
+  for (node = cgraph_nodes; node; node = node->next)
+    if (!node->analyzed && node->callees)
+      cgraph_node_remove_callees (node);
   if (cgraph_dump_file)
     fprintf (cgraph_dump_file, "Updating call sites\n");
   for (node = cgraph_nodes; node; node = node->next)
Index: ipa.c
===================================================================
--- ipa.c       (revision 155090)
+++ ipa.c       (working copy)
@@ -179,11 +179,21 @@ cgraph_remove_unreachable_nodes (bool be
                  first = e->callee;
                }
            }
+       
+      /* We can freely remove inline clones even if they are cloned, however
if
+        function is clone of real clone, we must keep it around in order to
+        make materialize_clones produce function body with the changes
+        applied.  */
       while (node->clone_of && !node->clone_of->aux && !gimple_has_body_p
(node->decl))
         {
+         bool noninline = node->clone_of->decl != node->decl;
          node = node->clone_of;
-         node->aux = first;
-         first = node;
+         if (noninline)
+           {
+             node->aux = first;
+             first = node;
+             break;
+           }
        }
     }

@@ -244,6 +254,9 @@ cgraph_remove_unreachable_nodes (bool be
                    node->clone_of->clones = node->next_sibling_clone;
                  if (node->next_sibling_clone)
                    node->next_sibling_clone->prev_sibling_clone =
node->prev_sibling_clone;
+                 node->clone_of = NULL;
+                 node->next_sibling_clone = NULL;
+                 node->prev_sibling_clone = NULL;
                }
              else
                cgraph_remove_node (node);
Index: tree-inline.c
===================================================================
--- tree-inline.c       (revision 155090)
+++ tree-inline.c       (working copy)
@@ -1694,13 +1694,15 @@ copy_bb (copy_body_data *id, basic_block
                              || !id->src_node->analyzed);
                  if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
                    cgraph_create_edge_including_clones
-                     (id->dst_node, dest, stmt, bb->count,
+                     (id->dst_node, dest, orig_stmt, stmt, bb->count,
                       compute_call_stmt_bb_frequency (id->dst_node->decl,
                                                       copy_basic_block),
                       bb->loop_depth, CIF_ORIGINALLY_INDIRECT_CALL);
                  else
                    cgraph_create_edge (id->dst_node, dest, stmt,
-                                       bb->count, CGRAPH_FREQ_BASE,
+                                       bb->count,
+                                       compute_call_stmt_bb_frequency
+                                         (id->dst_node->decl,
copy_basic_block),
                                        bb->loop_depth)->inline_failed
                      = CIF_ORIGINALLY_INDIRECT_CALL;
                  if (dump_file)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/42228] [4.5 Regression] verify_cgraph_node failed:node has wrong clone_of
  2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
                   ` (4 preceding siblings ...)
  2009-12-10 17:36 ` hubicka at ucw dot cz
@ 2009-12-10 20:51 ` hubicka at gcc dot gnu dot org
  2009-12-11 11:17 ` hubicka at gcc dot gnu dot org
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at gcc dot gnu dot org @ 2009-12-10 20:51 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from hubicka at gcc dot gnu dot org  2009-12-10 20:51 -------
Subject: Bug 42228

Author: hubicka
Date: Thu Dec 10 20:50:47 2009
New Revision: 155140

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

        PR middle-end/42228
        PR middle-end/42110
        * cgraph.c (cgraph_create_edge_including_clones): Add old_stmt
parameter;
        update edge if it already exists.
        (cgraph_remove_node): Handle correctly cases where we are removing node
having
        clones.
        * cgraph.h (cgraph_create_edge_including_clones): Declare.
        (verify_cgraph_node): Add missing error_found = true code.
        (cgraph_materialize_all_clones): Remove call edges of dead nodes.
        * ipa.c (cgraph_remove_unreachable_nodes): Correctly look for master
        clone; fix double linked list removal.
        * tree-inline.c (copy_bb): Update cgraph_create_edge_including_clones
call;
        fix frequency of newly created edge.

        * g++.dg/torture/pr42110.C: new file.

Added:
    trunk/gcc/testsuite/g++.dg/torture/pr42110.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cgraph.c
    trunk/gcc/cgraph.h
    trunk/gcc/cgraphunit.c
    trunk/gcc/ipa.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-inline.c


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug middle-end/42228] [4.5 Regression] verify_cgraph_node failed:node has wrong clone_of
  2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
                   ` (5 preceding siblings ...)
  2009-12-10 20:51 ` hubicka at gcc dot gnu dot org
@ 2009-12-11 11:17 ` hubicka at gcc dot gnu dot org
  6 siblings, 0 replies; 8+ messages in thread
From: hubicka at gcc dot gnu dot org @ 2009-12-11 11:17 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from hubicka at gcc dot gnu dot org  2009-12-11 11:17 -------
Fixed.


-- 

hubicka at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42228


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-12-11 11:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-30 10:04 [Bug c++/42228] New: verify_cgraph_node failed:node has wrong clone_of dcb314 at hotmail dot com
2009-11-30 10:07 ` [Bug c++/42228] " dcb314 at hotmail dot com
2009-11-30 10:41 ` [Bug middle-end/42228] [4.5 Regression] " rguenth at gcc dot gnu dot org
2009-12-02 12:16 ` rguenth at gcc dot gnu dot org
2009-12-08 14:16 ` reichelt at gcc dot gnu dot org
2009-12-10 17:36 ` hubicka at ucw dot cz
2009-12-10 20:51 ` hubicka at gcc dot gnu dot org
2009-12-11 11:17 ` hubicka at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).