Hi,
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.
profiledbootstrapped and autoprofiledbootstraped/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 --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 94a2e6e6105..32071a84bac 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 00000000000..eed112df389
--- /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 00000000000..511fae45be8
--- /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( );
+}