https://gcc.gnu.org/g:1e314be3ccc50dc7dcf0ad6c3aebe63cf025f4bf

commit r16-6458-g1e314be3ccc50dc7dcf0ad6c3aebe63cf025f4bf
Author: Kugan Vivekanandarajah <[email protected]>
Date:   Fri Jan 2 07:58:28 2026 +1100

    [PATCH] [AutoFDO/devirt] Fix ICE with duplicate speculative ID
    
    This happens due to autoprofile pass makes edge make_speculative.
    Then ipa-devirt does the same with the same speculative_id which
    reults in duplicate speculative_id and ICE.
    
    during IPA pass: cp
    test.i:31:1: internal compiler error: verify_cgraph_node failed
    0x39bfa6b internal_error(char const*, ...)
            ../../gcc/gcc/diagnostic-global-context.cc:787
    0x13914eb cgraph_node::verify_node()
            ../../gcc/gcc/cgraph.cc:4454
    0x13738ab symtab_node::verify()
            ../../gcc/gcc/symtab.cc:1377
    0x1373d1b symtab_node::verify_symtab_nodes()
            ../../gcc/gcc/symtab.cc:1499
    0x13a3653 symtab_node::checking_verify_symtab_nodes()
            ../../gcc/gcc/cgraph.h:718
    0x182d267 symbol_table::remove_unreachable_nodes(_IO_FILE*)
            ../../gcc/gcc/ipa.cc:688
    0x19f8c33 execute_todo
            ../../gcc/gcc/passes.cc:2163
    
    We may also have to check if the speculative edge is present
    before making speculative.
    
    gcc/ChangeLog:
    
    2025-12-22  Kugan Vivekanandarajah  <[email protected]>
    
            * cgraph.cc (cgraph_edge::get_next_speculative_id): New.
            * cgraph.h (cgraph_edge::get_next_speculative_id): New.
            * ipa-devirt.cc (ipa_devirt): Use get_next_speculative_id
            in make_speculative.
    
    Signed-off-by: Kugan Vivekanandarajah <[email protected]>

Diff:
---
 gcc/cgraph.cc     | 26 ++++++++++++++++++++++++++
 gcc/cgraph.h      |  5 +++++
 gcc/ipa-devirt.cc |  5 +++--
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 9e273642dab9..0c1995dcfbdb 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -1265,6 +1265,32 @@ cgraph_edge::remove (cgraph_edge *edge)
   symtab->free_edge (edge);
 }
 
+/* Returns the next speculative_id based on currently in use
+   for the given statement for the edge.
+   Returns 0 if no speculative edges exist for this statement. */
+
+int
+cgraph_edge::get_next_speculative_id ()
+{
+  int max_id = -1;
+  cgraph_edge *e;
+
+  /* Iterate through all edges leaving this caller */
+  for (e = caller->callees; e; e = e->next_callee)
+    {
+      /* Match the specific GIMPLE statement and check the
+        speculative flag */
+      if (e->call_stmt == call_stmt && e->speculative)
+       {
+         if (e->speculative_id > max_id)
+           max_id = e->speculative_id;
+       }
+    }
+
+  return max_id + 1;
+}
+
+
 /* Turn edge into speculative call calling N2. Update
    the profile so the direct call is taken COUNT times
    with FREQUENCY.
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index dbbab4087a9a..d471ce85c1ed 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1894,6 +1894,11 @@ public:
      call.  */
   static cgraph_edge *make_direct (cgraph_edge *edge, cgraph_node *callee);
 
+  /* Returns the next speculative_id based on currently in use
+     for the given statement for the edge.
+     Returns 0 if no speculative edges exist for this statement. */
+  int get_next_speculative_id ();
+
   /* Turn edge into speculative call calling N2. Update
      the profile so the direct call is taken COUNT times
      with FREQUENCY.  speculative_id is used to link direct calls with their
diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index bb0f5c767102..0b7e8bb6fae6 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -3865,7 +3865,7 @@ ipa_devirt (void)
                continue;
              }
            bool first = true;
-           unsigned speculative_id = 0;
+           unsigned speculative_id = e->get_next_speculative_id ();
            for (cgraph_node * likely_target: likely_targets)
              {
                if (!devirt_target_ok_p (likely_target, &stats))
@@ -3940,7 +3940,8 @@ ipa_devirt (void)
 
                update = true;
                e->make_speculative (likely_tgt_node,
-                                    e->count.apply_scale (8, 10));
+                                    e->count.apply_scale (8, 10),
+                                    e->get_next_speculative_id ());
              }
          }
       if (update)

Reply via email to