https://github.com/mysterymath updated 
https://github.com/llvm/llvm-project/pull/164916

>From c2782be78f3f3a72ea81549365a675e18df8e12d Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <[email protected]>
Date: Thu, 7 Aug 2025 16:05:09 -0700
Subject: [PATCH 1/5] [LTO][LLD] Prevent invalid LTO libfunc transforms

This patch ensures that:
1) New bitcode is not extracted for libfuncs after LTO occurs, and
2) Extracted bitcode for libfuncs is considered external, since new
   calls to it may be emitted.
---
 clang/lib/CodeGen/BackendUtil.cpp             | 10 +--
 lld/ELF/Driver.cpp                            | 19 +++++-
 lld/ELF/LTO.cpp                               |  5 +-
 lld/ELF/LTO.h                                 |  3 +-
 lld/test/ELF/lto/libcall-archive-bitcode.test | 41 ++++++++++++
 llvm/include/llvm/LTO/LTO.h                   | 24 ++++++-
 llvm/include/llvm/LTO/LTOBackend.h            |  7 ++-
 llvm/lib/LTO/LTO.cpp                          | 62 +++++++++++++------
 llvm/lib/LTO/LTOBackend.cpp                   | 43 ++++++++++---
 llvm/lib/LTO/LTOCodeGenerator.cpp             |  4 +-
 llvm/lib/Object/CMakeLists.txt                |  1 +
 llvm/lib/Object/IRSymtab.cpp                  |  8 ++-
 .../X86/libcall-external-bitcode.ll           | 20 ++++++
 .../X86/libcall-external-not-bitcode.ll       | 20 ++++++
 llvm/test/LTO/Resolution/X86/libcall-in-tu.ll | 34 ++++++++++
 llvm/tools/llvm-lto2/llvm-lto2.cpp            |  7 +++
 16 files changed, 266 insertions(+), 42 deletions(-)
 create mode 100644 lld/test/ELF/lto/libcall-archive-bitcode.test
 create mode 100644 llvm/test/LTO/Resolution/X86/libcall-external-bitcode.ll
 create mode 100644 llvm/test/LTO/Resolution/X86/libcall-external-not-bitcode.ll
 create mode 100644 llvm/test/LTO/Resolution/X86/libcall-in-tu.ll

diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 5590d217e96ff..8382ae0873adb 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1451,11 +1451,11 @@ runThinLTOBackend(CompilerInstance &CI, 
ModuleSummaryIndex *CombinedIndex,
   // FIXME: Both ExecuteAction and thinBackend set up optimization remarks for
   // the same context.
   finalizeLLVMOptimizationRemarks(M->getContext());
-  if (Error E =
-          thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
-                      ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
-                      /*ModuleMap=*/nullptr, Conf.CodeGenOnly,
-                      /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
+  if (Error E = thinBackend(
+          Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
+          ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
+          /*ModuleMap=*/nullptr, Conf.CodeGenOnly, /*BitcodeLibFuncs=*/{},
+          /*IRAddStream=*/nullptr, CGOpts.CmdArgs)) {
     handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
       errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
     });
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 8647752be31fe..b0834e6c26b7a 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2701,15 +2701,30 @@ static void markBuffersAsDontNeed(Ctx &ctx, bool 
skipLinkedOutput) {
 template <class ELFT>
 void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
   llvm::TimeTraceScope timeScope("LTO");
+  // Capture the triple before moving the bitcode into the bitcode compiler.
+  std::optional<llvm::Triple> tt;
+  if (!ctx.bitcodeFiles.empty())
+    tt = llvm::Triple(ctx.bitcodeFiles.front()->obj->getTargetTriple());
   // Compile bitcode files and replace bitcode symbols.
   lto.reset(new BitcodeCompiler(ctx));
   for (BitcodeFile *file : ctx.bitcodeFiles)
     lto->add(*file);
 
-  if (!ctx.bitcodeFiles.empty())
+  llvm::BumpPtrAllocator alloc;
+  llvm::StringSaver saver(alloc);
+  SmallVector<StringRef> bitcodeLibFuncs;
+  if (!ctx.bitcodeFiles.empty()) {
     markBuffersAsDontNeed(ctx, skipLinkedOutput);
+    for (StringRef libFunc : lto::LTO::getLibFuncSymbols(*tt, saver)) {
+      Symbol *sym = ctx.symtab->find(libFunc);
+      if (!sym)
+        continue;
+      if (isa<BitcodeFile>(sym->file))
+        bitcodeLibFuncs.push_back(libFunc);
+    }
+  }
 
-  ltoObjectFiles = lto->compile();
+  ltoObjectFiles = lto->compile(bitcodeLibFuncs);
   for (auto &file : ltoObjectFiles) {
     auto *obj = cast<ObjFile<ELFT>>(file.get());
     obj->parse(/*ignoreComdats=*/true);
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 80c6d2482f9fa..839eed9956d3a 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -311,7 +311,10 @@ static void thinLTOCreateEmptyIndexFiles(Ctx &ctx) {
 
 // Merge all the bitcode files we have seen, codegen the result
 // and return the resulting ObjectFile(s).
-SmallVector<std::unique_ptr<InputFile>, 0> BitcodeCompiler::compile() {
+SmallVector<std::unique_ptr<InputFile>, 0>
+BitcodeCompiler::compile(const SmallVector<StringRef> &bitcodeLibFuncs) {
+  ltoObj->setBitcodeLibFuncs(bitcodeLibFuncs);
+
   unsigned maxTasks = ltoObj->getMaxTasks();
   buf.resize(maxTasks);
   files.resize(maxTasks);
diff --git a/lld/ELF/LTO.h b/lld/ELF/LTO.h
index acf3bcff7f2f1..8207e91460785 100644
--- a/lld/ELF/LTO.h
+++ b/lld/ELF/LTO.h
@@ -42,7 +42,8 @@ class BitcodeCompiler {
   ~BitcodeCompiler();
 
   void add(BitcodeFile &f);
-  SmallVector<std::unique_ptr<InputFile>, 0> compile();
+  SmallVector<std::unique_ptr<InputFile>, 0>
+  compile(const SmallVector<StringRef> &bitcodeLibFuncs);
 
 private:
   Ctx &ctx;
diff --git a/lld/test/ELF/lto/libcall-archive-bitcode.test 
b/lld/test/ELF/lto/libcall-archive-bitcode.test
new file mode 100644
index 0000000000000..20735b5c89c99
--- /dev/null
+++ b/lld/test/ELF/lto/libcall-archive-bitcode.test
@@ -0,0 +1,41 @@
+; REQUIRES: x86
+
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: llvm-as main.ll -o main.o
+; RUN: llvm-as bcmp.ll -o bcmp.o
+; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu memcmp.s -o 
memcmp.o
+; RUN: llvm-ar rc libc.a bcmp.o memcmp.o
+
+;; Ensure that no memcmp->bcmp translation occurs during LTO because bcmp is in
+;; bitcode, but was not brought into the link. This would fail the link by
+;; extracting bitcode after LTO.
+; RUN: ld.lld -o out main.o -L. -lc
+; RUN: llvm-nm out | FileCheck %s
+
+;--- bcmp.ll
+target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @bcmp(ptr %0, ptr %1, i64 %2) {
+  ret i32 0
+}
+
+;--- memcmp.s
+.globl memcmp
+memcmp:
+  ret
+
+;--- main.ll
+target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i1 @_start(ptr %0, ptr %1, i64 %2) {
+  %cmp = call i32 @memcmp(ptr %0, ptr %1, i64 %2)
+  %eq = icmp eq i32 %cmp, 0
+  ret i1 %eq
+}
+
+; CHECK-NOT: bcmp
+; CHECK: memcmp
+declare i32 @memcmp(ptr, ptr, i64)
+
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index 3a4dc5a3dfcf8..3ee5d455774b3 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -264,7 +264,8 @@ class ThinBackendProc {
 using ThinBackendFunction = std::function<std::unique_ptr<ThinBackendProc>(
     const Config &C, ModuleSummaryIndex &CombinedIndex,
     const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
-    AddStreamFn AddStream, FileCache Cache)>;
+    AddStreamFn AddStream, FileCache Cache,
+    const SmallVector<StringRef> &BitcodeLibFuncs)>;
 
 /// This type defines the behavior following the thin-link phase during 
ThinLTO.
 /// It encapsulates a backend function and a strategy for thread pool
@@ -279,10 +280,11 @@ struct ThinBackend {
   std::unique_ptr<ThinBackendProc> operator()(
       const Config &Conf, ModuleSummaryIndex &CombinedIndex,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
-      AddStreamFn AddStream, FileCache Cache) {
+      AddStreamFn AddStream, FileCache Cache,
+      const SmallVector<StringRef> &BitcodeLibFuncs) {
     assert(isValid() && "Invalid backend function");
     return Func(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
-                std::move(AddStream), std::move(Cache));
+                std::move(AddStream), std::move(Cache), BitcodeLibFuncs);
   }
   ThreadPoolStrategy getParallelism() const { return Parallelism; }
   bool isValid() const { return static_cast<bool>(Func); }
@@ -400,6 +402,12 @@ class LTO {
   LLVM_ABI Error add(std::unique_ptr<InputFile> Obj,
                      ArrayRef<SymbolResolution> Res);
 
+  /// Set the list of functions implemented in bitcode across the link, whether
+  /// extracted or not. Such functions may not be referenced if they were not
+  /// extracted by the time LTO occurs.
+  LLVM_ABI void
+  setBitcodeLibFuncs(const SmallVector<StringRef> &BitcodeLibFuncs);
+
   /// Returns an upper bound on the number of tasks that the client may expect.
   /// This may only be called after all IR object files have been added. For a
   /// full description of tasks see LTOBackend.h.
@@ -420,6 +428,14 @@ class LTO {
   LLVM_ABI static SmallVector<const char *>
   getRuntimeLibcallSymbols(const Triple &TT);
 
+  /// Static method that returns a list of library function symbols that can be
+  /// generated by LTO but might not be visible from bitcode symbol table.
+  /// Unlike the runtime libcalls, the linker can report to the code generator
+  /// which of these are actually available in the link, and the code generator
+  /// can then only reference that set of symbols.
+  LLVM_ABI static SmallVector<StringRef>
+  getLibFuncSymbols(const Triple &TT, llvm::StringSaver &Saver);
+
 private:
   Config Conf;
 
@@ -591,6 +607,8 @@ class LTO {
 
   // Diagnostic optimization remarks file
   LLVMRemarkFileHandle DiagnosticOutputFile;
+
+  SmallVector<StringRef> BitcodeLibFuncs;
 };
 
 /// The resolution for a symbol. The linker must provide a SymbolResolution for
diff --git a/llvm/include/llvm/LTO/LTOBackend.h 
b/llvm/include/llvm/LTO/LTOBackend.h
index 48ad5aa64f61f..6a7d7e0d87ac9 100644
--- a/llvm/include/llvm/LTO/LTOBackend.h
+++ b/llvm/include/llvm/LTO/LTOBackend.h
@@ -39,13 +39,15 @@ LLVM_ABI bool opt(const Config &Conf, TargetMachine *TM, 
unsigned Task,
                   Module &Mod, bool IsThinLTO,
                   ModuleSummaryIndex *ExportSummary,
                   const ModuleSummaryIndex *ImportSummary,
-                  const std::vector<uint8_t> &CmdArgs);
+                  const std::vector<uint8_t> &CmdArgs,
+                  const SmallVector<StringRef> &BitcodeLibFuncs);
 
 /// Runs a regular LTO backend. The regular LTO backend can also act as the
 /// regular LTO phase of ThinLTO, which may need to access the combined index.
 LLVM_ABI Error backend(const Config &C, AddStreamFn AddStream,
                        unsigned ParallelCodeGenParallelismLevel, Module &M,
-                       ModuleSummaryIndex &CombinedIndex);
+                       ModuleSummaryIndex &CombinedIndex,
+                       const SmallVector<StringRef> &BitcodeLibFuncs);
 
 /// Runs a ThinLTO backend.
 /// If \p ModuleMap is not nullptr, all the module files to be imported have
@@ -62,6 +64,7 @@ thinBackend(const Config &C, unsigned Task, AddStreamFn 
AddStream, Module &M,
             const FunctionImporter::ImportMapTy &ImportList,
             const GVSummaryMapTy &DefinedGlobals,
             MapVector<StringRef, BitcodeModule> *ModuleMap, bool CodeGenOnly,
+            const SmallVector<StringRef> &BitcodeLibFuncs,
             AddStreamFn IRAddStream = nullptr,
             const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>());
 
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index a02af59600c44..97d3952b05d06 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -763,6 +763,10 @@ Error LTO::add(std::unique_ptr<InputFile> Input,
   return Error::success();
 }
 
+void LTO::setBitcodeLibFuncs(const SmallVector<StringRef> &BitcodeLibFuncs) {
+  this->BitcodeLibFuncs = BitcodeLibFuncs;
+}
+
 Expected<ArrayRef<SymbolResolution>>
 LTO::addModule(InputFile &Input, ArrayRef<SymbolResolution> InputRes,
                unsigned ModI, ArrayRef<SymbolResolution> Res) {
@@ -1385,9 +1389,9 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) {
   }
 
   if (!RegularLTO.EmptyCombinedModule || Conf.AlwaysEmitRegularLTOObj) {
-    if (Error Err =
-            backend(Conf, AddStream, 
RegularLTO.ParallelCodeGenParallelismLevel,
-                    *RegularLTO.CombinedModule, ThinLTO.CombinedIndex))
+    if (Error Err = backend(
+            Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
+            *RegularLTO.CombinedModule, ThinLTO.CombinedIndex, 
BitcodeLibFuncs))
       return Err;
   }
 
@@ -1407,6 +1411,21 @@ SmallVector<const char *> 
LTO::getRuntimeLibcallSymbols(const Triple &TT) {
   return LibcallSymbols;
 }
 
+SmallVector<StringRef> LTO::getLibFuncSymbols(const Triple &TT,
+                                              StringSaver &Saver) {
+  auto TLII = std::make_unique<TargetLibraryInfoImpl>(TT);
+  TargetLibraryInfo TLI(*TLII);
+  SmallVector<StringRef> LibFuncSymbols;
+  LibFuncSymbols.reserve(LibFunc::NumLibFuncs);
+  for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs); I != E;
+       ++I) {
+    LibFunc F = static_cast<LibFunc>(I);
+    if (TLI.has(F))
+      LibFuncSymbols.push_back(Saver.save(TLI.getName(F)).data());
+  }
+  return LibFuncSymbols;
+}
+
 Error ThinBackendProc::emitFiles(
     const FunctionImporter::ImportMapTy &ImportList, llvm::StringRef 
ModulePath,
     const std::string &NewModulePath) const {
@@ -1484,6 +1503,7 @@ class CGThinBackend : public ThinBackendProc {
 class InProcessThinBackend : public CGThinBackend {
 protected:
   FileCache Cache;
+  const SmallVector<StringRef> &BitcodeLibFuncs;
 
 public:
   InProcessThinBackend(
@@ -1491,11 +1511,12 @@ class InProcessThinBackend : public CGThinBackend {
       ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       AddStreamFn AddStream, FileCache Cache, lto::IndexWriteCallback OnWrite,
-      bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)
+      bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles,
+      const SmallVector<StringRef> &BitcodeLibFuncs)
       : CGThinBackend(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
                       AddStream, OnWrite, ShouldEmitIndexFiles,
                       ShouldEmitImportsFiles, ThinLTOParallelism),
-        Cache(std::move(Cache)) {}
+        Cache(std::move(Cache)), BitcodeLibFuncs(BitcodeLibFuncs) {}
 
   virtual Error runThinLTOBackendThread(
       AddStreamFn AddStream, FileCache Cache, unsigned Task, BitcodeModule BM,
@@ -1516,7 +1537,7 @@ class InProcessThinBackend : public CGThinBackend {
 
       return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
                          ImportList, DefinedGlobals, &ModuleMap,
-                         Conf.CodeGenOnly);
+                         Conf.CodeGenOnly, BitcodeLibFuncs);
     };
     if (ShouldEmitIndexFiles) {
       if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str()))
@@ -1601,13 +1622,14 @@ class FirstRoundThinBackend : public 
InProcessThinBackend {
       const Config &Conf, ModuleSummaryIndex &CombinedIndex,
       ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
-      AddStreamFn CGAddStream, FileCache CGCache, AddStreamFn IRAddStream,
+      AddStreamFn CGAddStream, FileCache CGCache,
+      const SmallVector<StringRef> &BitcodeLibFuncs, AddStreamFn IRAddStream,
       FileCache IRCache)
       : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
                              ModuleToDefinedGVSummaries, 
std::move(CGAddStream),
                              std::move(CGCache), /*OnWrite=*/nullptr,
                              /*ShouldEmitIndexFiles=*/false,
-                             /*ShouldEmitImportsFiles=*/false),
+                             /*ShouldEmitImportsFiles=*/false, 
BitcodeLibFuncs),
         IRAddStream(std::move(IRAddStream)), IRCache(std::move(IRCache)) {}
 
   Error runThinLTOBackendThread(
@@ -1630,7 +1652,7 @@ class FirstRoundThinBackend : public InProcessThinBackend 
{
 
       return thinBackend(Conf, Task, CGAddStream, **MOrErr, CombinedIndex,
                          ImportList, DefinedGlobals, &ModuleMap,
-                         Conf.CodeGenOnly, IRAddStream);
+                         Conf.CodeGenOnly, BitcodeLibFuncs, IRAddStream);
     };
     // Like InProcessThinBackend, we produce index files as needed for
     // FirstRoundThinBackend. However, these files are not generated for
@@ -1697,6 +1719,7 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
       ThreadPoolStrategy ThinLTOParallelism,
       const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
       AddStreamFn AddStream, FileCache Cache,
+      const SmallVector<StringRef> &BitcodeLibFuncs,
       std::unique_ptr<SmallVector<StringRef>> IRFiles,
       stable_hash CombinedCGDataHash)
       : InProcessThinBackend(Conf, CombinedIndex, ThinLTOParallelism,
@@ -1704,7 +1727,7 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
                              std::move(Cache),
                              /*OnWrite=*/nullptr,
                              /*ShouldEmitIndexFiles=*/false,
-                             /*ShouldEmitImportsFiles=*/false),
+                             /*ShouldEmitImportsFiles=*/false, 
BitcodeLibFuncs),
         IRFiles(std::move(IRFiles)), CombinedCGDataHash(CombinedCGDataHash) {}
 
   Error runThinLTOBackendThread(
@@ -1725,7 +1748,7 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
 
       return thinBackend(Conf, Task, AddStream, *LoadedModule, CombinedIndex,
                          ImportList, DefinedGlobals, &ModuleMap,
-                         /*CodeGenOnly=*/true);
+                         /*CodeGenOnly=*/true, BitcodeLibFuncs);
     };
     if (!Cache.isValid() || !CombinedIndex.modulePaths().count(ModuleID) ||
         all_of(CombinedIndex.getModuleHash(ModuleID),
@@ -1764,11 +1787,12 @@ ThinBackend 
lto::createInProcessThinBackend(ThreadPoolStrategy Parallelism,
   auto Func =
       [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
           const DenseMap<StringRef, GVSummaryMapTy> 
&ModuleToDefinedGVSummaries,
-          AddStreamFn AddStream, FileCache Cache) {
+          AddStreamFn AddStream, FileCache Cache,
+          const SmallVector<StringRef> &BitcodeLibFuncs) {
         return std::make_unique<InProcessThinBackend>(
             Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
             AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
-            ShouldEmitImportsFiles);
+            ShouldEmitImportsFiles, BitcodeLibFuncs);
       };
   return ThinBackend(Func, Parallelism);
 }
@@ -1885,7 +1909,8 @@ ThinBackend lto::createWriteIndexesThinBackend(
   auto Func =
       [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
           const DenseMap<StringRef, GVSummaryMapTy> 
&ModuleToDefinedGVSummaries,
-          AddStreamFn AddStream, FileCache Cache) {
+          AddStreamFn AddStream, FileCache Cache,
+          const SmallVector<StringRef> &BitcodeLibFuncs) {
         return std::make_unique<WriteIndexesThinBackend>(
             Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
             OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
@@ -2103,7 +2128,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache 
Cache,
   if (!CodeGenDataThinLTOTwoRounds) {
     std::unique_ptr<ThinBackendProc> BackendProc =
         ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, 
ModuleToDefinedGVSummaries,
-                        AddStream, Cache);
+                        AddStream, Cache, BitcodeLibFuncs);
     return RunBackends(BackendProc.get());
   }
 
@@ -2126,7 +2151,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache 
Cache,
   LLVM_DEBUG(dbgs() << "[TwoRounds] Running the first round of codegen\n");
   auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
       Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
-      CG.AddStream, CG.Cache, IR.AddStream, IR.Cache);
+      CG.AddStream, CG.Cache, BitcodeLibFuncs, IR.AddStream, IR.Cache);
   if (Error E = RunBackends(FirstRoundLTO.get()))
     return E;
 
@@ -2142,7 +2167,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache 
Cache,
   LLVM_DEBUG(dbgs() << "[TwoRounds] Running the second round of codegen\n");
   auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
       Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
-      AddStream, Cache, IR.getResult(), CombinedHash);
+      AddStream, Cache, BitcodeLibFuncs, IR.getResult(), CombinedHash);
   return RunBackends(SecondRoundLTO.get());
 }
 
@@ -2620,7 +2645,8 @@ ThinBackend lto::createOutOfProcessThinBackend(
   auto Func =
       [=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
           const DenseMap<StringRef, GVSummaryMapTy> 
&ModuleToDefinedGVSummaries,
-          AddStreamFn AddStream, FileCache Cache) {
+          AddStreamFn AddStream, FileCache Cache,
+          const SmallVector<StringRef> &BitcodeLibFuncs) {
         return std::make_unique<OutOfProcessThinBackend>(
             Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
             AddStream, Cache, OnWrite, ShouldEmitIndexFiles,
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 93118becedbac..bd91249db50ed 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -239,7 +239,8 @@ createTargetMachine(const Config &Conf, const Target 
*TheTarget, Module &M) {
 static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
                            unsigned OptLevel, bool IsThinLTO,
                            ModuleSummaryIndex *ExportSummary,
-                           const ModuleSummaryIndex *ImportSummary) {
+                           const ModuleSummaryIndex *ImportSummary,
+                           const DenseSet<StringRef> &BitcodeLibFuncs) {
   std::optional<PGOOptions> PGOOpt;
   if (!Conf.SampleProfile.empty())
     PGOOpt = PGOOptions(Conf.SampleProfile, "", Conf.ProfileRemapping,
@@ -281,6 +282,28 @@ static void runNewPMPasses(const Config &Conf, Module 
&Mod, TargetMachine *TM,
       new TargetLibraryInfoImpl(TM->getTargetTriple()));
   if (Conf.Freestanding)
     TLII->disableAllFunctions();
+
+  TargetLibraryInfo TLI(*TLII);
+  for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs); I != E;
+       ++I) {
+    LibFunc F = static_cast<LibFunc>(I);
+    StringRef Name = TLI.getName(F);
+    GlobalValue *Val = Mod.getNamedValue(Name);
+
+    // LibFuncs present in the current TU can always be referenced.
+    if (Val && !Val->isDeclaration())
+      continue;
+
+    // LibFuncs not implemented in bitcode can always be referenced.
+    if (!BitcodeLibFuncs.contains(Name))
+      continue;
+
+    // FIXME: Functions that are somewhere in a ThinLTO link (just not imported
+    // in this module) should not be disabled, as they have already been
+    // extracted.
+    TLII->setUnavailable(F);
+  }
+
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
   // Parse a custom AA pipeline if asked to.
@@ -364,7 +387,8 @@ static bool isEmptyModule(const Module &Mod) {
 bool lto::opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module 
&Mod,
               bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
               const ModuleSummaryIndex *ImportSummary,
-              const std::vector<uint8_t> &CmdArgs) {
+              const std::vector<uint8_t> &CmdArgs,
+              const SmallVector<StringRef> &BitcodeLibFuncs) {
   llvm::TimeTraceScope timeScope("opt");
   if (EmbedBitcode == LTOBitcodeEmbedding::EmbedPostMergePreOptimized) {
     // FIXME: the motivation for capturing post-merge bitcode and command line
@@ -389,9 +413,11 @@ bool lto::opt(const Config &Conf, TargetMachine *TM, 
unsigned Task, Module &Mod,
   // analysis in the case of a ThinLTO build where this might be an empty
   // regular LTO combined module, with a large combined index from ThinLTO.
   if (!isEmptyModule(Mod)) {
+    DenseSet<StringRef> BitcodeLibFuncsSet(BitcodeLibFuncs.begin(),
+                                           BitcodeLibFuncs.end());
     // FIXME: Plumb the combined index into the new pass manager.
     runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
-                   ImportSummary);
+                   ImportSummary, BitcodeLibFuncsSet);
   }
   return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
 }
@@ -552,7 +578,8 @@ Error lto::finalizeOptimizationRemarks(LLVMRemarkFileHandle 
DiagOutputFile) {
 
 Error lto::backend(const Config &C, AddStreamFn AddStream,
                    unsigned ParallelCodeGenParallelismLevel, Module &Mod,
-                   ModuleSummaryIndex &CombinedIndex) {
+                   ModuleSummaryIndex &CombinedIndex,
+                   const SmallVector<StringRef> &BitcodeLibFuncs) {
   llvm::TimeTraceScope timeScope("LTO backend");
   Expected<const Target *> TOrErr = initAndLookupTarget(C, Mod);
   if (!TOrErr)
@@ -564,7 +591,7 @@ Error lto::backend(const Config &C, AddStreamFn AddStream,
   if (!C.CodeGenOnly) {
     if (!opt(C, TM.get(), 0, Mod, /*IsThinLTO=*/false,
              /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
-             /*CmdArgs*/ std::vector<uint8_t>()))
+             /*CmdArgs*/ std::vector<uint8_t>(), BitcodeLibFuncs))
       return Error::success();
   }
 
@@ -604,7 +631,9 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, 
AddStreamFn AddStream,
                        const FunctionImporter::ImportMapTy &ImportList,
                        const GVSummaryMapTy &DefinedGlobals,
                        MapVector<StringRef, BitcodeModule> *ModuleMap,
-                       bool CodeGenOnly, AddStreamFn IRAddStream,
+                       bool CodeGenOnly,
+                       const SmallVector<StringRef> &BitcodeLibFuncs,
+                       AddStreamFn IRAddStream,
                        const std::vector<uint8_t> &CmdArgs) {
   llvm::TimeTraceScope timeScope("Thin backend", Mod.getModuleIdentifier());
   Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod);
@@ -643,7 +672,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, 
AddStreamFn AddStream,
         // Perform optimization and code generation for ThinLTO.
         if (!opt(Conf, TM, Task, Mod, /*IsThinLTO=*/true,
                  /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex,
-                 CmdArgs))
+                 CmdArgs, BitcodeLibFuncs))
           return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
 
         // Save the current module before the first codegen round.
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp 
b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 8aa404da15286..599c5c2eb5f84 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -614,7 +614,7 @@ bool LTOCodeGenerator::optimize() {
   TargetMach = createTargetMachine();
   if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
            /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
-           /*CmdArgs*/ std::vector<uint8_t>())) {
+           /*CmdArgs*/ std::vector<uint8_t>(), {})) {
     emitError("LTO middle-end optimizations failed");
     return false;
   }
@@ -639,7 +639,7 @@ bool LTOCodeGenerator::compileOptimized(AddStreamFn 
AddStream,
 
   Config.CodeGenOnly = true;
   Error Err = backend(Config, AddStream, ParallelismLevel, *MergedModule,
-                      CombinedIndex);
+                      CombinedIndex, {});
   assert(!Err && "unexpected code-generation failure");
   (void)Err;
 
diff --git a/llvm/lib/Object/CMakeLists.txt b/llvm/lib/Object/CMakeLists.txt
index 0f6d2f7c59a5c..c48d251249488 100644
--- a/llvm/lib/Object/CMakeLists.txt
+++ b/llvm/lib/Object/CMakeLists.txt
@@ -51,6 +51,7 @@ add_llvm_component_library(LLVMObject
   BinaryFormat
   MCParser
   Support
+  Target
   TargetParser
   TextAPI
   )
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index a45b34eb2e706..92ed072a80267 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -13,6 +13,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/Comdat.h"
@@ -75,12 +76,14 @@ struct Builder {
   Builder(SmallVector<char, 0> &Symtab, StringTableBuilder &StrtabBuilder,
           BumpPtrAllocator &Alloc, const Triple &TT)
       : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc), TT(TT),
-        Libcalls(TT) {}
+        TLII(TT), TLI(TLII), Libcalls(TT) {}
 
   DenseMap<const Comdat *, int> ComdatMap;
   Mangler Mang;
   const Triple &TT;
 
+  TargetLibraryInfoImpl TLII;
+  TargetLibraryInfo TLI;
   // FIXME: This shouldn't be here.
   RTLIB::RuntimeLibcallsInfo Libcalls;
 
@@ -95,6 +98,9 @@ struct Builder {
   std::vector<storage::Str> DependentLibraries;
 
   bool isPreservedName(StringRef Name) {
+    LibFunc F;
+    if (TLI.getLibFunc(Name, F) && TLI.has(F))
+      return true;
     return Libcalls.getSupportedLibcallImpl(Name) != RTLIB::Unsupported;
   }
 
diff --git a/llvm/test/LTO/Resolution/X86/libcall-external-bitcode.ll 
b/llvm/test/LTO/Resolution/X86/libcall-external-bitcode.ll
new file mode 100644
index 0000000000000..95a599fe75e8b
--- /dev/null
+++ b/llvm/test/LTO/Resolution/X86/libcall-external-bitcode.ll
@@ -0,0 +1,20 @@
+; RUN: opt %s -o %t -module-summary -mtriple x86_64-unknown-linux-musl
+; RUN: llvm-lto2 run -o %t2 \
+; RUN:   -r %t,foo,plx \
+; RUN:   -r %t,memcmp,x \
+; RUN:   -r %t,bcmp,pl --bitcode-libfuncs=bcmp %t -save-temps
+; RUN: llvm-dis %t2.1.4.opt.bc -o - | FileCheck %s
+
+define i1 @foo(ptr %0, ptr %1, i64 %2) {
+  ; CHECK-LABEL: define{{.*}}i1 @foo
+  ; CHECK-NEXT: %cmp = {{.*}}call i32 @memcmp
+  ; CHECK-NEXT: %eq = icmp eq i32 %cmp, 0
+  ; CHECK-NEXT: ret i1 %eq
+
+  %cmp = call i32 @memcmp(ptr %0, ptr %1, i64 %2)
+  %eq = icmp eq i32 %cmp, 0
+  ret i1 %eq
+}
+
+declare i32 @memcmp(ptr, ptr, i64)
+declare i32 @bcmp(ptr, ptr, i64)
diff --git a/llvm/test/LTO/Resolution/X86/libcall-external-not-bitcode.ll 
b/llvm/test/LTO/Resolution/X86/libcall-external-not-bitcode.ll
new file mode 100644
index 0000000000000..2e6cc798d22cd
--- /dev/null
+++ b/llvm/test/LTO/Resolution/X86/libcall-external-not-bitcode.ll
@@ -0,0 +1,20 @@
+; RUN: opt %s -o %t -module-summary -mtriple x86_64-unknown-linux-musl
+; RUN: llvm-lto2 run -o %t2 \
+; RUN:   -r %t,foo,plx \
+; RUN:   -r %t,memcmp,x \
+; RUN:   -r %t,bcmp,pl %t -save-temps
+; RUN: llvm-dis %t2.1.4.opt.bc -o - | FileCheck %s
+
+define i1 @foo(ptr %0, ptr %1, i64 %2) {
+  ; CHECK-LABEL: define{{.*}}i1 @foo
+  ; CHECK-NEXT: %bcmp = {{.*}}call i32 @bcmp
+  ; CHECK-NEXT: %eq = icmp eq i32 %bcmp, 0
+  ; CHECK-NEXT: ret i1 %eq
+
+  %cmp = call i32 @memcmp(ptr %0, ptr %1, i64 %2)
+  %eq = icmp eq i32 %cmp, 0
+  ret i1 %eq
+}
+
+declare i32 @memcmp(ptr, ptr, i64)
+declare i32 @bcmp(ptr, ptr, i64)
diff --git a/llvm/test/LTO/Resolution/X86/libcall-in-tu.ll 
b/llvm/test/LTO/Resolution/X86/libcall-in-tu.ll
new file mode 100644
index 0000000000000..948f21a6536ca
--- /dev/null
+++ b/llvm/test/LTO/Resolution/X86/libcall-in-tu.ll
@@ -0,0 +1,34 @@
+;; This test comes from a real world scenario in LTO, where the definition of
+;; bcmp was deleted because it has no uses, but later instcombine re-introduced
+;; a call to bcmp() as part of SimplifyLibCalls. Such deletions must not be
+;; allowed.
+
+; RUN: opt %s -o %t -module-summary -mtriple x86_64-unknown-linux-musl
+; RUN: llvm-lto2 run -o %t2 \
+; RUN:   -r %t,foo,plx \
+; RUN:   -r %t,memcmp,x \
+; RUN:   -r %t,bcmp,pl \
+; RUN:   -r %t,bcmp_impl,x %t -save-temps
+; RUN: llvm-dis %t2.1.4.opt.bc -o - | FileCheck %s
+
+define i1 @foo(ptr %0, ptr %1, i64 %2) {
+  ; CHECK-LABEL: define{{.*}}i1 @foo
+  ; CHECK-NEXT: %bcmp = {{.*}}call i32 @bcmp
+  ; CHECK-NEXT: %eq = icmp eq i32 %bcmp, 0
+  ; CHECK-NEXT: ret i1 %eq
+
+  %cmp = call i32 @memcmp(ptr %0, ptr %1, i64 %2)
+  %eq = icmp eq i32 %cmp, 0
+  ret i1 %eq
+}
+
+declare i32 @memcmp(ptr, ptr, i64)
+declare i32 @bcmp_impl(ptr, ptr, i64)
+
+;; Ensure bcmp is not removed from module because it is external.
+; CHECK: define dso_local i32 @bcmp
+define i32 @bcmp(ptr %0, ptr %1, i64 %2) noinline {
+  %r = call i32 @bcmp_impl(ptr %0, ptr %1, i64 %2)
+  ret i32 %r
+}
+
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp 
b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 399306f39daeb..fbac9700db04f 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -232,6 +232,10 @@ static cl::opt<bool>
     AllVtablesHaveTypeInfos("all-vtables-have-type-infos", cl::Hidden,
                             cl::desc("All vtables have type infos"));
 
+static cl::list<std::string>
+    BitcodeLibFuncs("bitcode-libfuncs", cl::Hidden,
+                    cl::desc("set of libfuncs implemented in bitcode"));
+
 static void check(Error E, std::string Msg) {
   if (!E)
     return;
@@ -468,6 +472,9 @@ static int run(int argc, char **argv) {
   if (HasErrors)
     return 1;
 
+  Lto.setBitcodeLibFuncs(
+      SmallVector<StringRef>(BitcodeLibFuncs.begin(), BitcodeLibFuncs.end()));
+
   auto AddStream =
       [&](size_t Task,
           const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {

>From d542aacf17a7f64193ddc9e1a07edc0dc83325d0 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <[email protected]>
Date: Thu, 11 Dec 2025 15:33:23 -0800
Subject: [PATCH 2/5] Move bitcodeLibFuncs from compile() to setter

---
 lld/ELF/LTO.cpp | 18 ++++++++++--------
 lld/ELF/LTO.h   |  4 ++--
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 839eed9956d3a..ed1a8c6ddae4f 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -195,10 +195,10 @@ BitcodeCompiler::BitcodeCompiler(Ctx &ctx) : ctx(ctx) {
         ctx.arg.thinLTOEmitImportsFiles);
   }
 
-  constexpr llvm::lto::LTO::LTOKind ltoModes[3] =
-    {llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
-     llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
-     llvm::lto::LTO::LTOKind::LTOK_Default};
+  constexpr llvm::lto::LTO::LTOKind ltoModes[3] = {
+      llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
+      llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
+      llvm::lto::LTO::LTOKind::LTOK_Default};
   ltoObj = std::make_unique<lto::LTO>(createConfig(ctx), backend,
                                       ctx.arg.ltoPartitions,
                                       ltoModes[ctx.arg.ltoKind]);
@@ -311,10 +311,7 @@ static void thinLTOCreateEmptyIndexFiles(Ctx &ctx) {
 
 // Merge all the bitcode files we have seen, codegen the result
 // and return the resulting ObjectFile(s).
-SmallVector<std::unique_ptr<InputFile>, 0>
-BitcodeCompiler::compile(const SmallVector<StringRef> &bitcodeLibFuncs) {
-  ltoObj->setBitcodeLibFuncs(bitcodeLibFuncs);
-
+SmallVector<std::unique_ptr<InputFile>, 0> BitcodeCompiler::compile() {
   unsigned maxTasks = ltoObj->getMaxTasks();
   buf.resize(maxTasks);
   files.resize(maxTasks);
@@ -425,3 +422,8 @@ BitcodeCompiler::compile(const SmallVector<StringRef> 
&bitcodeLibFuncs) {
   }
   return ret;
 }
+
+void BitcodeCompiler::setBitcodeLibFuncs(
+    const SmallVector<StringRef> &bitcodeLibFuncs) {
+  ltoObj->setBitcodeLibFuncs(bitcodeLibFuncs);
+}
diff --git a/lld/ELF/LTO.h b/lld/ELF/LTO.h
index 8207e91460785..b9547202901fd 100644
--- a/lld/ELF/LTO.h
+++ b/lld/ELF/LTO.h
@@ -42,8 +42,8 @@ class BitcodeCompiler {
   ~BitcodeCompiler();
 
   void add(BitcodeFile &f);
-  SmallVector<std::unique_ptr<InputFile>, 0>
-  compile(const SmallVector<StringRef> &bitcodeLibFuncs);
+  SmallVector<std::unique_ptr<InputFile>, 0> compile();
+  void setBitcodeLibFuncs(const SmallVector<StringRef> &bitcodeLibFuncs);
 
 private:
   Ctx &ctx;

>From 99994e5ca8f1b0011bb98235b2b15dfa18b7de6f Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <[email protected]>
Date: Thu, 11 Dec 2025 15:35:22 -0800
Subject: [PATCH 3/5] Densify bitcode file finding

---
 lld/ELF/Driver.cpp | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index b0834e6c26b7a..3a0028c92d060 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2712,19 +2712,18 @@ void LinkerDriver::compileBitcodeFiles(bool 
skipLinkedOutput) {
 
   llvm::BumpPtrAllocator alloc;
   llvm::StringSaver saver(alloc);
-  SmallVector<StringRef> bitcodeLibFuncs;
   if (!ctx.bitcodeFiles.empty()) {
     markBuffersAsDontNeed(ctx, skipLinkedOutput);
-    for (StringRef libFunc : lto::LTO::getLibFuncSymbols(*tt, saver)) {
-      Symbol *sym = ctx.symtab->find(libFunc);
-      if (!sym)
-        continue;
-      if (isa<BitcodeFile>(sym->file))
+
+    SmallVector<StringRef> bitcodeLibFuncs;
+    for (StringRef libFunc : lto::LTO::getLibFuncSymbols(*tt, saver))
+      if (Symbol *sym = ctx.symtab->find(libFunc);
+          sym && isa<BitcodeFile>(sym->file))
         bitcodeLibFuncs.push_back(libFunc);
-    }
+    lto->setBitcodeLibFuncs(bitcodeLibFuncs);
   }
 
-  ltoObjectFiles = lto->compile(bitcodeLibFuncs);
+  ltoObjectFiles = lto->compile();
   for (auto &file : ltoObjectFiles) {
     auto *obj = cast<ObjFile<ELFT>>(file.get());
     obj->parse(/*ignoreComdats=*/true);

>From 16cffa859a683903840d3199e5164e6e3624583c Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <[email protected]>
Date: Thu, 11 Dec 2025 15:39:54 -0800
Subject: [PATCH 4/5] Add comment about triple assumption

---
 lld/ELF/Driver.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 3a0028c92d060..b7a6aa89efb96 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2702,6 +2702,8 @@ template <class ELFT>
 void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
   llvm::TimeTraceScope timeScope("LTO");
   // Capture the triple before moving the bitcode into the bitcode compiler.
+  // Note that this assumes that the set of possible libfuncs is roughly
+  // equivalent for all bitcode translation units.
   std::optional<llvm::Triple> tt;
   if (!ctx.bitcodeFiles.empty())
     tt = llvm::Triple(ctx.bitcodeFiles.front()->obj->getTargetTriple());

>From 50a35b7d51ccef73616292b290767bda23b003a4 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <[email protected]>
Date: Fri, 12 Dec 2025 12:06:47 -0800
Subject: [PATCH 5/5] Undo unneeded formatting

---
 lld/ELF/LTO.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index ed1a8c6ddae4f..cdcb84b4a7dda 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -195,10 +195,10 @@ BitcodeCompiler::BitcodeCompiler(Ctx &ctx) : ctx(ctx) {
         ctx.arg.thinLTOEmitImportsFiles);
   }
 
-  constexpr llvm::lto::LTO::LTOKind ltoModes[3] = {
-      llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
-      llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
-      llvm::lto::LTO::LTOKind::LTOK_Default};
+  constexpr llvm::lto::LTO::LTOKind ltoModes[3] =
+    {llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
+     llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
+     llvm::lto::LTO::LTOKind::LTOK_Default};
   ltoObj = std::make_unique<lto::LTO>(createConfig(ctx), backend,
                                       ctx.arg.ltoPartitions,
                                       ltoModes[ctx.arg.ltoKind]);

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to