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 <kvivekananda@nvidia.com>
* 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 <kvivekananda@nvidia.com>
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.
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
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))
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)