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( ); +}