From 8045ba89488c9f7cc1c291e6c939e02e04fbcd2e Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Thu, 16 Feb 2023 11:19:27 -0800 Subject: [ThinLTO/WPD] Handle function alias in vtable correctly We were not summarizing a function alias in the vtable, leading to incorrect WPD in some cases, and missing WPD in others. Specifically, we would end up ignoring function aliases as they aren't summarized, so we could incorrectly devirtualize if there was a single other non-alias function in a compatible vtable. And if there was only one implementation, but it was an alias, we would not be able to identify and perform the single implementation devirtualization. Handling the alias summary correctly also required fixing the handling in mustBeUnreachableFunction, so that it is not incorrectly ignored. Regular LTO is conservatively correct because it will skip devirtualizing when any pointer within a vtable is not a function. However, it needs additional work to be able to take advantage of function alias within the vtable that is in fact the only implementation. For that reason, the Regular LTO testing in the second test case is currently disabled, and will be enabled along with a follow on enhancement fix for Regular LTO WPD. Differential Revision: https://reviews.llvm.org/D144209 --- llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp') diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index 3dfa2d8..26ff84f 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -583,12 +583,17 @@ static void findFuncPointers(const Constant *I, uint64_t StartingOffset, VTableFuncList &VTableFuncs) { // First check if this is a function pointer. if (I->getType()->isPointerTy()) { - auto Fn = dyn_cast(I->stripPointerCasts()); - // We can disregard __cxa_pure_virtual as a possible call target, as - // calls to pure virtuals are UB. - if (Fn && Fn->getName() != "__cxa_pure_virtual") - VTableFuncs.push_back({Index.getOrInsertValueInfo(Fn), StartingOffset}); - return; + auto C = I->stripPointerCasts(); + auto A = dyn_cast(C); + if (isa(C) || (A && isa(A->getAliasee()))) { + auto GV = dyn_cast(C); + assert(GV); + // We can disregard __cxa_pure_virtual as a possible call target, as + // calls to pure virtuals are UB. + if (GV && GV->getName() != "__cxa_pure_virtual") + VTableFuncs.push_back({Index.getOrInsertValueInfo(GV), StartingOffset}); + return; + } } // Walk through the elements in the constant struct or array and recursively -- cgit v1.1