]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Disable simpe-call devirtualization of already devirtualized calls
authorJan Hubicka <hubicka@ucw.cz>
Sun, 15 Feb 2026 19:19:57 +0000 (20:19 +0100)
committerJan Hubicka <hubicka@ucw.cz>
Sun, 15 Feb 2026 19:19:57 +0000 (20:19 +0100)
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.

gcc/ipa-devirt.cc

index a7cb2697813c16d0d3a685c2f1c654ec38562c2d..8577e9b30fb8832880720d5c1bbac168a0a91022 100644 (file)
@@ -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,