mirror of
https://github.com/gcc-mirror/gcc.git
synced 2025-07-21 23:52:54 +00:00
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.
This commit is contained in:
@ -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,
|
||||
|
16
gcc/testsuite/g++.dg/lto/pr114790_0.C
Normal file
16
gcc/testsuite/g++.dg/lto/pr114790_0.C
Normal file
@ -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() {}
|
||||
|
15
gcc/testsuite/g++.dg/lto/pr114790_1.C
Normal file
15
gcc/testsuite/g++.dg/lto/pr114790_1.C
Normal file
@ -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( );
|
||||
}
|
Reference in New Issue
Block a user