https://gcc.gnu.org/g:52d9c2272f6366cd5b30e9540ce8ef16b482cee5

commit r16-2196-g52d9c2272f6366cd5b30e9540ce8ef16b482cee5
Author: Jan Hubicka <hubi...@ucw.cz>
Date:   Fri Jul 11 12:37:24 2025 +0200

    Fix ICE in speculative devirtualization
    
    This patch fixes ICE bilding lto1 with autoprofiledbootstrap and in 
pr114790.
    What happens is that auto-fdo speculatively devirtualizes to a wrong target.
    This is due to a bug where it mixes up dwarf names and linkage names of 
inline
    functions I need to fix as well.
    
    Later we clone at WPA time. At ltrans time clone is materialized and call is
    turned into a direct call (this optimization is missed by ipa-cp 
propagation).
    At this time we should resolve speculation but we don't.  As a result we get
    error from verifier after inlining complaining that there is speculative 
call
    with corresponding direct call lacking speculative flag.
    
    This seems long-lasting problem in cgraph_update_edges_for_call_stmt_node 
but
    I suppose it does not trigger since we usually speculate correctly or notice
    the direct call at WPA time already.
    
    Bootstrapped/regtested x86_64-linux.
    
    gcc/ChangeLog:
    
            PR ipa/114790
            * cgraph.cc (cgraph_update_edges_for_call_stmt_node): Resolve 
devirtualization
            if call statement was optimized out or turned to direct call.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/lto/pr114790_0.C: New test.
            * g++.dg/lto/pr114790_1.C: New test.

Diff:
---
 gcc/cgraph.cc                         | 13 +++++++++++++
 gcc/testsuite/g++.dg/lto/pr114790_0.C | 16 ++++++++++++++++
 gcc/testsuite/g++.dg/lto/pr114790_1.C | 15 +++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 94a2e6e61058..32071a84bacc 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -1790,6 +1790,19 @@ cgraph_update_edges_for_call_stmt_node (cgraph_node 
*node,
 
       if (e)
        {
+         /* If call was devirtualized during cloning, mark edge
+            as resolved.  */
+         if (e->speculative)
+           {
+             if (new_stmt && is_gimple_call (new_stmt))
+               {
+                 tree decl = gimple_call_fndecl (new_stmt);
+                 if (decl)
+                   e = cgraph_edge::resolve_speculation (e, decl);
+               }
+             else
+               e = cgraph_edge::resolve_speculation (e, NULL);
+           }
          /* Keep calls marked as dead dead.  */
          if (new_stmt && is_gimple_call (new_stmt) && e->callee
              && fndecl_built_in_p (e->callee->decl, BUILT_IN_UNREACHABLE,
diff --git a/gcc/testsuite/g++.dg/lto/pr114790_0.C 
b/gcc/testsuite/g++.dg/lto/pr114790_0.C
new file mode 100644
index 000000000000..eed112df3897
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr114790_0.C
@@ -0,0 +1,16 @@
+// { dg-lto-do link }
+// { dg-lto-options { { -w -flto -g -flto-partition=1to1 -O2 -shared -fPIC 
-fvisibility=hidden} } }
+// { dg-require-effective-target fpic }
+// { dg-require-effective-target shared }
+struct APITracerContext {
+  virtual ~APITracerContext() = default;
+  virtual void releaseActivetracersList() = 0;
+};
+struct APITracerContextImp : APITracerContext {
+  ~APITracerContextImp() override;
+  void releaseActivetracersList() override;
+};
+struct APITracerContextImp globalAPITracerContextImp;
+struct APITracerContextImp *pGlobalAPITracerContextImp = 
&globalAPITracerContextImp;
+APITracerContextImp::~APITracerContextImp() {}
+
diff --git a/gcc/testsuite/g++.dg/lto/pr114790_1.C 
b/gcc/testsuite/g++.dg/lto/pr114790_1.C
new file mode 100644
index 000000000000..511fae45be8b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr114790_1.C
@@ -0,0 +1,15 @@
+struct APITracerContext {
+  virtual void releaseActivetracersList() = 0;
+};
+extern struct APITracerContextImp *pGlobalAPITracerContextImp;
+struct APITracerContextImp : APITracerContext { void 
releaseActivetracersList();};
+int g();
+inline int
+apiTracerWrapperImp(  ) {
+  for (int i = 0; i < g(); i++) 
+  pGlobalAPITracerContextImp->releaseActivetracersList();
+}
+__attribute__((visibility("default"))) int
+zeCommandListAppendMemoryCopyTracing() {
+  return apiTracerWrapperImp(      );
+}

Reply via email to