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,

Reply via email to