From 6411a7949b10bd2a89120018017efe6a609cf8e9 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Thu, 6 Jul 2017 19:58:26 +0000 Subject: [PATCH] [LTO] Fix the interaction between linker redefined symbols and ThinLTO This is the same as r304719 but for ThinLTO. The substantial difference is that in this case we don't have whole visibility, just the summary. In the LTO case, when we got the resolution for the input file we could just see if the linker told us whether a symbol was linker redefined (using --wrap or --defsym) and switch the linkage directly for the GV. Here, we have the summary. So, we record that the linkage changed from to $weakany to prevent IPOs across this symbol boundaries and actually just switch the linkage at FunctionImport time. This patch should also fixes the lld bits (as all the scaffolding for communicating if a symbol is linker redefined should be there & should be the same), but I'll make sure to add some tests there as well. Fixes PR33192. Differential Revision: https://reviews.llvm.org/D35064 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307303 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/LTO/LTO.cpp | 9 +++++++++ lib/Transforms/IPO/FunctionImport.cpp | 12 ++++++++++-- test/LTO/Resolution/X86/linker-redef-thin.ll | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 test/LTO/Resolution/X86/linker-redef-thin.ll diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp index 68b8c9fcb93..8be5312b920 100644 --- a/lib/LTO/LTO.cpp +++ b/lib/LTO/LTO.cpp @@ -665,6 +665,15 @@ Error LTO::addThinLTO(BitcodeModule BM, ArrayRef Syms, auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier( Sym.getIRName(), GlobalValue::ExternalLinkage, "")); ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier(); + + // For linker redefined symbols (via --wrap or --defsym) we want to + // switch the linkage to `weak` to prevent IPOs from happening. + // Find the summary in the module for this very GV and record the new + // linkage so that we can switch it when we import the GV. + if (Res.LinkerRedefined) + if (auto S = ThinLTO.CombinedIndex.findSummaryInModule( + GUID, BM.getModuleIdentifier())) + S->setLinkage(GlobalValue::WeakAnyLinkage); } } } diff --git a/lib/Transforms/IPO/FunctionImport.cpp b/lib/Transforms/IPO/FunctionImport.cpp index 6d34ab8b0d9..5e7cf436e2e 100644 --- a/lib/Transforms/IPO/FunctionImport.cpp +++ b/lib/Transforms/IPO/FunctionImport.cpp @@ -537,8 +537,6 @@ void llvm::thinLTOResolveWeakForLinkerModule( }; auto updateLinkage = [&](GlobalValue &GV) { - if (!GlobalValue::isWeakForLinker(GV.getLinkage())) - return; // See if the global summary analysis computed a new resolved linkage. const auto &GS = DefinedGlobals.find(GV.getGUID()); if (GS == DefinedGlobals.end()) @@ -546,6 +544,16 @@ void llvm::thinLTOResolveWeakForLinkerModule( auto NewLinkage = GS->second->linkage(); if (NewLinkage == GV.getLinkage()) return; + + // Switch the linkage to weakany if asked for, e.g. we do this for + // linker redefined symbols (via --wrap or --defsym). + if (NewLinkage == GlobalValue::WeakAnyLinkage) { + GV.setLinkage(NewLinkage); + return; + } + + if (!GlobalValue::isWeakForLinker(GV.getLinkage())) + return; // Check for a non-prevailing def that has interposable linkage // (e.g. non-odr weak or linkonce). In that case we can't simply // convert to available_externally, since it would lose the diff --git a/test/LTO/Resolution/X86/linker-redef-thin.ll b/test/LTO/Resolution/X86/linker-redef-thin.ll new file mode 100644 index 00000000000..ebaac8094e7 --- /dev/null +++ b/test/LTO/Resolution/X86/linker-redef-thin.ll @@ -0,0 +1,16 @@ +; RUN: opt -module-summary %s -o %t.o +; RUN: llvm-lto2 run -o %t1.o %t.o -r %t.o,patatino,pr +; RUN: llvm-readobj -t %t1.o.0 | FileCheck %s + +; CHECK: Name: patatino +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: +; CHECK-NEXT: Binding: Weak +; CHECK-NEXT: Type: Function + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @patatino() { + ret void +} -- 2.40.0