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.
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,
--- /dev/null
+// { 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() {}
+
--- /dev/null
+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( );
+}