Index: lib/LTO/LTO.cpp =================================================================== --- lib/LTO/LTO.cpp +++ lib/LTO/LTO.cpp @@ -665,6 +665,15 @@ 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. + auto S = ThinLTO.CombinedIndex.findSummaryInModule( + GUID, BM.getModuleIdentifier()); + if (S && Res.LinkerRedefined) + S->setLinkage(GlobalValue::WeakAnyLinkage); } } } Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -537,7 +537,11 @@ }; auto updateLinkage = [&](GlobalValue &GV) { - if (!GlobalValue::isWeakForLinker(GV.getLinkage())) + // Only rename symbols that are weak for the linker, i.e. + // have linkonce or linkonce_odr linkage or have been explicitly + // redefined at link time, via, e.g. --wrap or -defsym (in ELF). + if (GV.getLinkage() == GlobalValue::AppendingLinkage || + GV.getLinkage() == GlobalValue::ExternalLinkage) return; // See if the global summary analysis computed a new resolved linkage. const auto &GS = DefinedGlobals.find(GV.getGUID()); Index: test/LTO/Resolution/X86/linker-redef-thin.ll =================================================================== --- /dev/null +++ test/LTO/Resolution/X86/linker-redef-thin.ll @@ -0,0 +1,16 @@ +; RUN: opt -module-summmary %s -o %t.o +; RUN: llvm-lto2 run -o %t1.o %t.o -r %t.o,bar,pr +; RUN: llvm-readobj -t %t1.o.0 | FileCheck %s + +; CHECK: Name: bar +; 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 @bar() { + ret void +}