https://gcc.gnu.org/g:8cf191e93763ee9c00b5bed4092a426c7761362b
commit r16-7524-g8cf191e93763ee9c00b5bed4092a426c7761362b Author: Jan Hubicka <[email protected]> Date: Sun Feb 15 20:19:57 2026 +0100 Disable simpe-call devirtualization of already devirtualized calls Fix ICE caused by speculating already speculated target with auto-fdo. ipa_devirt is supposed to consistently skip devirtualized edges (or just check if devirtualization agrees with the static prediction when dumping). This was not hecked correctly in the simpe call path. gcc/ChangeLog: * ipa-devirt.cc (ipa_devirt): Improve statistics for multi-target devirtualization; do not simple-call devirtualize already devirtualized calls. Diff: --- gcc/ipa-devirt.cc | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc index a7cb2697813c..8577e9b30fb8 100644 --- a/gcc/ipa-devirt.cc +++ b/gcc/ipa-devirt.cc @@ -3845,23 +3845,21 @@ ipa_devirt (void) with the speculation. */ if (e->speculative) { - bool found = false; for (cgraph_node * likely_target: likely_targets) if (e->speculative_call_for_target (likely_target)) { - found = true; - break; + fprintf (dump_file, + "We agree with speculation on target %s\n\n", + likely_target->dump_name ()); + stats.nok++; + } + else + { + fprintf (dump_file, + "We disagree with speculation on target %s\n\n", + likely_target->dump_name ()); + stats.nwrong++; } - if (found) - { - fprintf (dump_file, "We agree with speculation\n\n"); - stats.nok++; - } - else - { - fprintf (dump_file, "We disagree with speculation\n\n"); - stats.nwrong++; - } continue; } bool first = true; @@ -3908,6 +3906,16 @@ ipa_devirt (void) else if (cgraph_simple_indirect_info *sii = dyn_cast <cgraph_simple_indirect_info *> (e->indirect_info)) { + if (e->speculative) + { + if (dump_file) + fprintf (dump_file, "Call is already speculated\n\n"); + stats.nspeculated++; + + /* When dumping see if we agree with speculation. */ + if (!dump_file) + continue; + } if (!sii->fnptr_loaded_from_record || !opt_for_fn (n->decl, flag_speculatively_call_stored_functions)) @@ -3930,6 +3938,20 @@ ipa_devirt (void) if (alias) likely_tgt_node = alias; } + if (e->speculative) + { + if (e->speculative_call_for_target (likely_tgt_node)) + { + fprintf (dump_file, "Simple call agree with speculation\n\n"); + stats.nok++; + } + else + { + fprintf (dump_file, "Simple call disagree with speculation\n\n"); + stats.nwrong++; + } + continue; + } if (dump_enabled_p ()) dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, e->call_stmt,
