https://github.com/ilovepi updated 
https://github.com/llvm/llvm-project/pull/179509

>From cb6a3f79829ddbf2961da040abd89a88036c058e Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Tue, 3 Feb 2026 09:02:48 -0800
Subject: [PATCH 1/8] [llvm] Force TLSDESC for all TLS access in Fuchsia code

Fuchsia no longer supports TLS access via __tls_get_addr, and only
supports the TLSDESC ABI on all target machines.

Though we already set Fuchsia as enabling TLSDESC by default, LLD's LTO
pipeline is initialized with an empty target triple, and thus does not
correctly select the correct codegen options for Fuchsia's ABI. Instead,
we can additionally check if Fuchsia is the actual target if the option
isn't set, since useTLSDESC() is only called later, when a non-default
target triple will be available.

The alternative is to rework how LLD initializes the LTO code generation
options, so that it selects the correct target, and initializes them
correctly. However, that's a more invasive change, and would need some
discussion to make sure that is handled correctly across all of LLDs
supported formats (e.g. ELF, Mach-O, COFF, etc.).
---
 llvm/lib/Target/TargetMachine.cpp     |  4 +-
 llvm/test/CodeGen/RISCV/tls-models.ll | 69 +++++++++++++++++++++++++++
 llvm/test/CodeGen/X86/tls-desc.ll     | 43 +++++++++++++++++
 3 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/TargetMachine.cpp 
b/llvm/lib/Target/TargetMachine.cpp
index f8f13a042fec0..3f59b819ffbf1 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -257,7 +257,9 @@ bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue 
*GV) const {
 }
 
 bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; }
-bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; }
+bool TargetMachine::useTLSDESC() const {
+  return Options.EnableTLSDESC || TargetTriple.isOSFuchsia();
+}
 
 TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
   bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
diff --git a/llvm/test/CodeGen/RISCV/tls-models.ll 
b/llvm/test/CodeGen/RISCV/tls-models.ll
index 52c2c31d8fa81..8caa6108ffbe9 100644
--- a/llvm/test/CodeGen/RISCV/tls-models.ll
+++ b/llvm/test/CodeGen/RISCV/tls-models.ll
@@ -7,10 +7,13 @@
 ; RUN:     | FileCheck -check-prefix=RV64-PIC %s
 ; RUN: llc -mtriple=riscv64 -relocation-model=pic -enable-tlsdesc < %s \
 ; RUN:     | FileCheck -check-prefix=RV64-PIC-TLSDESC %s
+; RUN: llc -mtriple=riscv64-unknown-fuchsia -relocation-model=pic < %s \
+; RUN:     | FileCheck -check-prefix=RV64-PIC-FUCHSIA %s
 ; RUN: llc -mtriple=riscv32 < %s | FileCheck -check-prefix=RV32-NOPIC %s
 ; RUN: llc -mtriple=riscv32 < %s -enable-tlsdesc | FileCheck 
-check-prefix=RV32-NOPIC-TLSDESC %s
 ; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefix=RV64-NOPIC %s
 ; RUN: llc -mtriple=riscv64 < %s -enable-tlsdesc | FileCheck 
-check-prefix=RV64-NOPIC-TLSDESC %s
+; RUN: llc -mtriple=riscv64-unknown-fuchsia < %s | FileCheck 
-check-prefix=RV64-NOPIC-FUCHSIA %s
 
 ; Check that TLS symbols are lowered correctly based on the specified
 ; model. Make sure they're external to avoid them all being optimised to Local
@@ -69,6 +72,16 @@ define ptr @f1() nounwind {
 ; RV64-PIC-TLSDESC-NEXT:    add a0, a0, tp
 ; RV64-PIC-TLSDESC-NEXT:    ret
 ;
+; RV64-PIC-FUCHSIA-LABEL: f1:
+; RV64-PIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-PIC-FUCHSIA-NEXT:  .Ltlsdesc_hi0:
+; RV64-PIC-FUCHSIA-NEXT:    auipc a0, %tlsdesc_hi(unspecified)
+; RV64-PIC-FUCHSIA-NEXT:    ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi0)(a0)
+; RV64-PIC-FUCHSIA-NEXT:    addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi0)
+; RV64-PIC-FUCHSIA-NEXT:    jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi0)
+; RV64-PIC-FUCHSIA-NEXT:    add a0, a0, tp
+; RV64-PIC-FUCHSIA-NEXT:    ret
+;
 ; RV32-NOPIC-LABEL: f1:
 ; RV32-NOPIC:       # %bb.0: # %entry
 ; RV32-NOPIC-NEXT:  .Lpcrel_hi0:
@@ -100,6 +113,14 @@ define ptr @f1() nounwind {
 ; RV64-NOPIC-TLSDESC-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
 ; RV64-NOPIC-TLSDESC-NEXT:    add a0, a0, tp
 ; RV64-NOPIC-TLSDESC-NEXT:    ret
+;
+; RV64-NOPIC-FUCHSIA-LABEL: f1:
+; RV64-NOPIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-NOPIC-FUCHSIA-NEXT:  .Lpcrel_hi0:
+; RV64-NOPIC-FUCHSIA-NEXT:    auipc a0, %tls_ie_pcrel_hi(unspecified)
+; RV64-NOPIC-FUCHSIA-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV64-NOPIC-FUCHSIA-NEXT:    add a0, a0, tp
+; RV64-NOPIC-FUCHSIA-NEXT:    ret
 entry:
   ret ptr @unspecified
 }
@@ -152,6 +173,16 @@ define ptr @f2() nounwind {
 ; RV64-PIC-TLSDESC-NEXT:    add a0, a0, tp
 ; RV64-PIC-TLSDESC-NEXT:    ret
 ;
+; RV64-PIC-FUCHSIA-LABEL: f2:
+; RV64-PIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-PIC-FUCHSIA-NEXT:  .Ltlsdesc_hi1:
+; RV64-PIC-FUCHSIA-NEXT:    auipc a0, %tlsdesc_hi(ld)
+; RV64-PIC-FUCHSIA-NEXT:    ld a1, %tlsdesc_load_lo(.Ltlsdesc_hi1)(a0)
+; RV64-PIC-FUCHSIA-NEXT:    addi a0, a0, %tlsdesc_add_lo(.Ltlsdesc_hi1)
+; RV64-PIC-FUCHSIA-NEXT:    jalr t0, 0(a1), %tlsdesc_call(.Ltlsdesc_hi1)
+; RV64-PIC-FUCHSIA-NEXT:    add a0, a0, tp
+; RV64-PIC-FUCHSIA-NEXT:    ret
+;
 ; RV32-NOPIC-LABEL: f2:
 ; RV32-NOPIC:       # %bb.0: # %entry
 ; RV32-NOPIC-NEXT:  .Lpcrel_hi1:
@@ -183,6 +214,14 @@ define ptr @f2() nounwind {
 ; RV64-NOPIC-TLSDESC-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
 ; RV64-NOPIC-TLSDESC-NEXT:    add a0, a0, tp
 ; RV64-NOPIC-TLSDESC-NEXT:    ret
+;
+; RV64-NOPIC-FUCHSIA-LABEL: f2:
+; RV64-NOPIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-NOPIC-FUCHSIA-NEXT:  .Lpcrel_hi1:
+; RV64-NOPIC-FUCHSIA-NEXT:    auipc a0, %tls_ie_pcrel_hi(ld)
+; RV64-NOPIC-FUCHSIA-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi1)(a0)
+; RV64-NOPIC-FUCHSIA-NEXT:    add a0, a0, tp
+; RV64-NOPIC-FUCHSIA-NEXT:    ret
 entry:
   ret ptr @ld
 }
@@ -223,6 +262,14 @@ define ptr @f3() nounwind {
 ; RV64-PIC-TLSDESC-NEXT:    add a0, a0, tp
 ; RV64-PIC-TLSDESC-NEXT:    ret
 ;
+; RV64-PIC-FUCHSIA-LABEL: f3:
+; RV64-PIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-PIC-FUCHSIA-NEXT:  .Lpcrel_hi0:
+; RV64-PIC-FUCHSIA-NEXT:    auipc a0, %tls_ie_pcrel_hi(ie)
+; RV64-PIC-FUCHSIA-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi0)(a0)
+; RV64-PIC-FUCHSIA-NEXT:    add a0, a0, tp
+; RV64-PIC-FUCHSIA-NEXT:    ret
+;
 ; RV32-NOPIC-LABEL: f3:
 ; RV32-NOPIC:       # %bb.0: # %entry
 ; RV32-NOPIC-NEXT:  .Lpcrel_hi2:
@@ -254,6 +301,14 @@ define ptr @f3() nounwind {
 ; RV64-NOPIC-TLSDESC-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi2)(a0)
 ; RV64-NOPIC-TLSDESC-NEXT:    add a0, a0, tp
 ; RV64-NOPIC-TLSDESC-NEXT:    ret
+;
+; RV64-NOPIC-FUCHSIA-LABEL: f3:
+; RV64-NOPIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-NOPIC-FUCHSIA-NEXT:  .Lpcrel_hi2:
+; RV64-NOPIC-FUCHSIA-NEXT:    auipc a0, %tls_ie_pcrel_hi(ie)
+; RV64-NOPIC-FUCHSIA-NEXT:    ld a0, %pcrel_lo(.Lpcrel_hi2)(a0)
+; RV64-NOPIC-FUCHSIA-NEXT:    add a0, a0, tp
+; RV64-NOPIC-FUCHSIA-NEXT:    ret
 entry:
   ret ptr @ie
 }
@@ -290,6 +345,13 @@ define ptr @f4() nounwind {
 ; RV64-PIC-TLSDESC-NEXT:    addi a0, a0, %tprel_lo(le)
 ; RV64-PIC-TLSDESC-NEXT:    ret
 ;
+; RV64-PIC-FUCHSIA-LABEL: f4:
+; RV64-PIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-PIC-FUCHSIA-NEXT:    lui a0, %tprel_hi(le)
+; RV64-PIC-FUCHSIA-NEXT:    add a0, a0, tp, %tprel_add(le)
+; RV64-PIC-FUCHSIA-NEXT:    addi a0, a0, %tprel_lo(le)
+; RV64-PIC-FUCHSIA-NEXT:    ret
+;
 ; RV32-NOPIC-LABEL: f4:
 ; RV32-NOPIC:       # %bb.0: # %entry
 ; RV32-NOPIC-NEXT:    lui a0, %tprel_hi(le)
@@ -317,6 +379,13 @@ define ptr @f4() nounwind {
 ; RV64-NOPIC-TLSDESC-NEXT:    add a0, a0, tp, %tprel_add(le)
 ; RV64-NOPIC-TLSDESC-NEXT:    addi a0, a0, %tprel_lo(le)
 ; RV64-NOPIC-TLSDESC-NEXT:    ret
+;
+; RV64-NOPIC-FUCHSIA-LABEL: f4:
+; RV64-NOPIC-FUCHSIA:       # %bb.0: # %entry
+; RV64-NOPIC-FUCHSIA-NEXT:    lui a0, %tprel_hi(le)
+; RV64-NOPIC-FUCHSIA-NEXT:    add a0, a0, tp, %tprel_add(le)
+; RV64-NOPIC-FUCHSIA-NEXT:    addi a0, a0, %tprel_lo(le)
+; RV64-NOPIC-FUCHSIA-NEXT:    ret
 entry:
   ret ptr @le
 }
diff --git a/llvm/test/CodeGen/X86/tls-desc.ll 
b/llvm/test/CodeGen/X86/tls-desc.ll
index c73986e69e791..f7dc0ceeeeb32 100644
--- a/llvm/test/CodeGen/X86/tls-desc.ll
+++ b/llvm/test/CodeGen/X86/tls-desc.ll
@@ -2,6 +2,7 @@
 ; RUN: llc < %s -mtriple=i686 --relocation-model=pic -enable-tlsdesc | 
FileCheck %s --check-prefix=X86
 ; RUN: llc < %s -mtriple=x86_64-pc-linux-gnux32 --relocation-model=pic 
-enable-tlsdesc | FileCheck %s --check-prefix=X32
 ; RUN: llc < %s -mtriple=x86_64 --relocation-model=pic -enable-tlsdesc | 
FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=x86_64-unknown-fuchsia --relocation-model=pic | 
FileCheck %s --check-prefix=X64-FUCHSIA
 
 @x = thread_local global i32 0, align 4
 @y = internal thread_local global i32 1, align 4
@@ -62,6 +63,19 @@ define ptr @f1() nounwind {
 ; X64-NEXT:    #NO_APP
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
+;
+; X64-FUCHSIA-LABEL: f1:
+; X64-FUCHSIA:       # %bb.0:
+; X64-FUCHSIA-NEXT:    pushq %rax
+; X64-FUCHSIA-NEXT:    #APP
+; X64-FUCHSIA-NEXT:    #NO_APP
+; X64-FUCHSIA-NEXT:    leaq x@tlsdesc(%rip), %rax
+; X64-FUCHSIA-NEXT:    callq *x@tlscall(%rax)
+; X64-FUCHSIA-NEXT:    addq %fs:0, %rax
+; X64-FUCHSIA-NEXT:    #APP
+; X64-FUCHSIA-NEXT:    #NO_APP
+; X64-FUCHSIA-NEXT:    popq %rcx
+; X64-FUCHSIA-NEXT:    retq
   %a = call { i32, i32, i32, i32, i32, i32 } asm sideeffect "", 
"=r,=r,=r,=r,=r,=r,~{dirflag},~{fpsr},~{flags}"()
   %b = call ptr @llvm.threadlocal.address.p0(ptr @x)
   %a.0 = extractvalue { i32, i32, i32, i32, i32, i32 } %a, 0
@@ -109,6 +123,15 @@ define i32 @f2() nounwind {
 ; X64-NEXT:    movl (%rax,%rcx), %eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
+;
+; X64-FUCHSIA-LABEL: f2:
+; X64-FUCHSIA:       # %bb.0:
+; X64-FUCHSIA-NEXT:    pushq %rax
+; X64-FUCHSIA-NEXT:    leaq x@tlsdesc(%rip), %rax
+; X64-FUCHSIA-NEXT:    callq *x@tlscall(%rax)
+; X64-FUCHSIA-NEXT:    movl %fs:(%rax), %eax
+; X64-FUCHSIA-NEXT:    popq %rcx
+; X64-FUCHSIA-NEXT:    retq
   %1 = tail call ptr @llvm.threadlocal.address.p0(ptr @x)
   %2 = load i32, ptr %1
   ret i32 %2
@@ -147,6 +170,15 @@ define ptr @f3() nounwind {
 ; X64-NEXT:    addq %fs:0, %rax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
+;
+; X64-FUCHSIA-LABEL: f3:
+; X64-FUCHSIA:       # %bb.0:
+; X64-FUCHSIA-NEXT:    pushq %rax
+; X64-FUCHSIA-NEXT:    leaq x@tlsdesc(%rip), %rax
+; X64-FUCHSIA-NEXT:    callq *x@tlscall(%rax)
+; X64-FUCHSIA-NEXT:    addq %fs:0, %rax
+; X64-FUCHSIA-NEXT:    popq %rcx
+; X64-FUCHSIA-NEXT:    retq
   %1 = tail call ptr @llvm.threadlocal.address.p0(ptr @x)
   ret ptr %1
 }
@@ -192,6 +224,17 @@ define i32 @f4() nounwind {
 ; X64-NEXT:    movl %ecx, %eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
+;
+; X64-FUCHSIA-LABEL: f4:
+; X64-FUCHSIA:       # %bb.0:
+; X64-FUCHSIA-NEXT:    pushq %rax
+; X64-FUCHSIA-NEXT:    leaq _TLS_MODULE_BASE_@tlsdesc(%rip), %rax
+; X64-FUCHSIA-NEXT:    callq *_TLS_MODULE_BASE_@tlscall(%rax)
+; X64-FUCHSIA-NEXT:    movl %fs:y@DTPOFF(%rax), %ecx
+; X64-FUCHSIA-NEXT:    addl %fs:z@DTPOFF(%rax), %ecx
+; X64-FUCHSIA-NEXT:    movl %ecx, %eax
+; X64-FUCHSIA-NEXT:    popq %rcx
+; X64-FUCHSIA-NEXT:    retq
   %1 = load i32, ptr @y, align 4
   %2 = load i32, ptr @z, align 4
   %3 = add nsw i32 %1, %2

>From c4a42aa9b5ca4d8d2f0ba96edf351a3bf4704730 Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Thu, 5 Feb 2026 14:29:26 -0800
Subject: [PATCH 2/8] Redesign how TargetOptions are used in LTO

---
 clang/lib/CodeGen/BackendUtil.cpp             |  7 +-
 .../ClangNVLinkWrapper.cpp                    |  2 -
 lld/COFF/LTO.cpp                              | 24 +++---
 lld/ELF/LTO.cpp                               | 79 ++++++++++---------
 lld/MachO/LTO.cpp                             |  8 +-
 lld/wasm/LTO.cpp                              | 10 +--
 llvm/include/llvm/LTO/Config.h                |  4 +-
 llvm/include/llvm/LTO/LTO.h                   |  2 +-
 .../llvm/LTO/legacy/LTOCodeGenerator.h        |  1 +
 llvm/lib/LTO/LTO.cpp                          | 50 ++++++++----
 llvm/lib/LTO/LTOBackend.cpp                   | 19 +++--
 llvm/lib/LTO/LTOCodeGenerator.cpp             |  8 +-
 llvm/lib/LTO/ThinLTOCodeGenerator.cpp         |  3 +-
 llvm/lib/Target/TargetMachine.cpp             |  4 +-
 llvm/tools/llvm-lto2/llvm-lto2.cpp            |  2 +-
 15 files changed, 135 insertions(+), 88 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index b286ff359ec40..5afe8a07471c0 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -25,6 +25,7 @@
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Frontend/Driver/CodeGenOptions.h"
@@ -51,6 +52,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/Program.h"
+#include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -1351,7 +1353,10 @@ runThinLTOBackend(CompilerInstance &CI, 
ModuleSummaryIndex *CombinedIndex,
   assert(OptLevelOrNone && "Invalid optimization level!");
   Conf.CGOptLevel = *OptLevelOrNone;
   Conf.OptLevel = CGOpts.OptimizationLevel;
-  initTargetOptions(CI, Diags, Conf.Options);
+  // llvm::codegen::RegisterCodeGenFlags F;
+  Conf.ModifyTargetOptions = [&](llvm::TargetOptions &TargetOpts)->void {
+    initTargetOptions(CI, Diags, TargetOpts);
+  };
   Conf.SampleProfile = std::move(SampleProfile);
   Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
   Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops;
diff --git a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp 
b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
index 3ebd4ea979322..f940951584fab 100644
--- a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
+++ b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp
@@ -358,8 +358,6 @@ Expected<std::unique_ptr<lto::LTO>> createLTO(const ArgList 
&Args) {
       lto::createInProcessThinBackend(heavyweight_hardware_concurrency(Jobs));
 
   Conf.CPU = Args.getLastArgValue(OPT_arch);
-  Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple);
-
   Conf.RemarksFilename =
       Args.getLastArgValue(OPT_opt_remarks_filename, RemarksFilename);
   Conf.RemarksPasses =
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index d55f95493a85f..de083a356271e 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -46,17 +46,24 @@ std::string BitcodeCompiler::getThinLTOOutputFile(StringRef 
path) {
 
 lto::Config BitcodeCompiler::createConfig() {
   lto::Config c;
-  c.Options = initTargetOptionsFromCodeGenFlags();
-  c.Options.EmitAddrsig = true;
+  bool emitAsm = ctx.config.emit == EmitKind::ASM;
+  c.ModifyTargetOptions = [emitAsm](TargetOptions &options) {
+    options.EmitAddrsig = true;
+    // Always emit a section per function/datum with LTO. LLVM LTO should get
+    // most of the benefit of linker GC, but there are still opportunities for
+    // ICF.
+    options.FunctionSections = true;
+    options.DataSections = true;
+
+    if (emitAsm) {
+      options.MCOptions.AsmVerbose = true;
+    }
+  };
+
   for (StringRef C : ctx.config.mllvmOpts)
     c.MllvmArgs.emplace_back(C.str());
 
-  // Always emit a section per function/datum with LTO. LLVM LTO should get 
most
-  // of the benefit of linker GC, but there are still opportunities for ICF.
-  c.Options.FunctionSections = true;
-  c.Options.DataSections = true;
-
-  // Use static reloc model on 32-bit x86 because it usually results in more
+    // Use static reloc model on 32-bit x86 because it usually results in more
   // compact code, and because there are also known code generation bugs when
   // using the PIC model (see PR34306).
   if (ctx.config.machine == COFF::IMAGE_FILE_MACHINE_I386)
@@ -95,7 +102,6 @@ lto::Config BitcodeCompiler::createConfig() {
     };
   } else if (ctx.config.emit == EmitKind::ASM) {
     c.CGFileType = CodeGenFileType::AssemblyFile;
-    c.Options.MCOptions.AsmVerbose = true;
   }
 
   if (!ctx.config.saveTempsArgs.empty())
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 6f916a501a262..692651a8506ca 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -46,47 +46,52 @@ static std::string getThinLTOOutputFile(Ctx &ctx, StringRef 
modulePath) {
 static lto::Config createConfig(Ctx &ctx) {
   lto::Config c;
 
-  // LLD supports the new relocations and address-significance tables.
-  c.Options = initTargetOptionsFromCodeGenFlags();
-  c.Options.EmitAddrsig = true;
-  for (StringRef C : ctx.arg.mllvmOpts)
-    c.MllvmArgs.emplace_back(C.str());
-
-  // Always emit a section per function/datum with LTO.
-  c.Options.FunctionSections = true;
-  c.Options.DataSections = true;
-
-  // Check if basic block sections must be used.
-  // Allowed values for --lto-basic-block-sections are "all",
-  // "<file name specifying basic block ids>", or none.  This is the equivalent
-  // of -fbasic-block-sections= flag in clang.
-  if (!ctx.arg.ltoBasicBlockSections.empty()) {
-    if (ctx.arg.ltoBasicBlockSections == "all") {
-      c.Options.BBSections = BasicBlockSection::All;
-    } else if (ctx.arg.ltoBasicBlockSections == "labels") {
-      c.Options.BBAddrMap = true;
-      Warn(ctx)
-          << "'--lto-basic-block-sections=labels' is deprecated; Please use "
-             "'--lto-basic-block-address-map' instead";
-    } else if (ctx.arg.ltoBasicBlockSections == "none") {
-      c.Options.BBSections = BasicBlockSection::None;
-    } else {
-      ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
-          MemoryBuffer::getFile(ctx.arg.ltoBasicBlockSections.str());
-      if (!MBOrErr) {
-        ErrAlways(ctx) << "cannot open " << ctx.arg.ltoBasicBlockSections << 
":"
-                       << MBOrErr.getError().message();
+  // Set up the callback to modify TargetOptions.
+  c.ModifyTargetOptions = [&](TargetOptions &Options) -> void {
+    // LLD supports the new relocations and address-significance tables.
+    Options.EmitAddrsig = true;
+    // Always emit a section per function/datum with LTO.
+    Options.FunctionSections = true;
+    Options.DataSections = true;
+
+    // Check if basic block sections must be used.
+    // Allowed values for --lto-basic-block-sections are "all",
+    // "<file name specifying basic block ids>", or none.  This is the
+    // equivalent of -fbasic-block-sections= flag in clang.
+    if (!ctx.arg.ltoBasicBlockSections.empty()) {
+      if (ctx.arg.ltoBasicBlockSections == "all") {
+        Options.BBSections = BasicBlockSection::All;
+      } else if (ctx.arg.ltoBasicBlockSections == "labels") {
+        Options.BBAddrMap = true;
+        Warn(ctx)
+            << "'--lto-basic-block-sections=labels' is deprecated; Please use "
+               "'--lto-basic-block-address-map' instead";
+      } else if (ctx.arg.ltoBasicBlockSections == "none") {
+        Options.BBSections = BasicBlockSection::None;
       } else {
-        c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
+        ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+            MemoryBuffer::getFile(ctx.arg.ltoBasicBlockSections.str());
+        if (!MBOrErr) {
+          ErrAlways(ctx) << "cannot open " << ctx.arg.ltoBasicBlockSections
+                         << ":" << MBOrErr.getError().message();
+        } else {
+          Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
+        }
+        Options.BBSections = BasicBlockSection::List;
       }
-      c.Options.BBSections = BasicBlockSection::List;
     }
-  }
 
-  c.Options.BBAddrMap = ctx.arg.ltoBBAddrMap;
+    Options.BBAddrMap = ctx.arg.ltoBBAddrMap;
 
-  c.Options.UniqueBasicBlockSectionNames =
-      ctx.arg.ltoUniqueBasicBlockSectionNames;
+    Options.UniqueBasicBlockSectionNames =
+        ctx.arg.ltoUniqueBasicBlockSectionNames;
+    if (ctx.arg.ltoEmitAsm) {
+      Options.MCOptions.AsmVerbose = true;
+    }
+  };
+
+  for (StringRef C : ctx.arg.mllvmOpts)
+    c.MllvmArgs.emplace_back(C.str());
 
   if (auto relocModel = getRelocModelFromCMModel())
     c.RelocModel = *relocModel;
@@ -156,7 +161,7 @@ static lto::Config createConfig(Ctx &ctx) {
 
   if (ctx.arg.ltoEmitAsm) {
     c.CGFileType = CodeGenFileType::AssemblyFile;
-    c.Options.MCOptions.AsmVerbose = true;
+    // c.Options.MCOptions.AsmVerbose = true;
   }
 
   if (!ctx.arg.saveTempsArgs.empty())
diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index 2c360374ef3cc..e25c63e1fce6b 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -38,8 +38,12 @@ static std::string getThinLTOOutputFile(StringRef 
modulePath) {
 
 static lto::Config createConfig() {
   lto::Config c;
-  c.Options = initTargetOptionsFromCodeGenFlags();
-  c.Options.EmitAddrsig = config->icfLevel == ICFLevel::safe;
+
+  bool emitAddrsig = config->icfLevel == ICFLevel::safe;
+  c.ModifyTargetOptions = [emitAddrsig](TargetOptions &options) {
+    options.EmitAddrsig = emitAddrsig;
+  };
+
   for (StringRef C : config->mllvmOpts)
     c.MllvmArgs.emplace_back(C.str());
   for (StringRef pluginFn : config->passPlugins)
diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp
index 668cdf21ea3ed..f6f69e934a00a 100644
--- a/lld/wasm/LTO.cpp
+++ b/lld/wasm/LTO.cpp
@@ -42,11 +42,11 @@ static std::string getThinLTOOutputFile(StringRef 
modulePath) {
 
 static lto::Config createConfig() {
   lto::Config c;
-  c.Options = initTargetOptionsFromCodeGenFlags();
-
-  // Always emit a section per function/data with LTO.
-  c.Options.FunctionSections = true;
-  c.Options.DataSections = true;
+  c.ModifyTargetOptions = [&](TargetOptions &options) {
+    // Always emit a section per function/data with LTO.
+    options.FunctionSections = true;
+    options.DataSections = true;
+  };
 
   c.DisableVerify = ctx.arg.disableVerify;
   c.DiagHandler = diagnosticHandler;
diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h
index 566a87ed1a790..29350964fd0cb 100644
--- a/llvm/include/llvm/LTO/Config.h
+++ b/llvm/include/llvm/LTO/Config.h
@@ -47,7 +47,8 @@ struct Config {
   // Note: when adding fields here, consider whether they need to be added to
   // computeLTOCacheKey in LTO.cpp.
   std::string CPU;
-  TargetOptions Options;
+  // Callback to modify the target options once they are instantiated.
+  std::function<void(TargetOptions& Options)> ModifyTargetOptions = 
[](TargetOptions&){};
   std::vector<std::string> MAttrs;
   std::vector<std::string> MllvmArgs;
   std::vector<std::string> PassPlugins;
@@ -286,6 +287,7 @@ struct Config {
   LLVM_ABI Error addSaveTemps(std::string OutputFileName,
                               bool UseInputModulePath = false,
                               const DenseSet<StringRef> &SaveTempsArgs = {});
+
 };
 
 struct LTOLLVMDiagnosticHandler : public DiagnosticHandler {
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index f992be9899e3d..fd91345cf548f 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -74,7 +74,7 @@ LLVM_ABI std::string computeLTOCacheKey(
     StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList,
     const FunctionImporter::ExportSetTy &ExportList,
     const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
-    const GVSummaryMapTy &DefinedGlobals,
+    const GVSummaryMapTy &DefinedGlobals, const Triple &TT,
     const DenseSet<GlobalValue::GUID> &CfiFunctionDefs = {},
     const DenseSet<GlobalValue::GUID> &CfiFunctionDecls = {});
 
diff --git a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h 
b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
index caff198358caa..117269c1b58a1 100644
--- a/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
+++ b/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
@@ -249,6 +249,7 @@ struct LTOCodeGenerator {
   std::string SaveIRBeforeOptPath;
 
   lto::Config Config;
+  llvm::TargetOptions TO;
 };
 
 /// A convenience function that calls cl::ParseCommandLineOptions on the given
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index bbbdfcbd71f2b..01039ef0f8a43 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -24,6 +24,7 @@
 #include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/CGData/CodeGenData.h"
 #include "llvm/CodeGen/Analysis.h"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/AutoUpgrade.h"
 #include "llvm/IR/DiagnosticPrinter.h"
@@ -107,6 +108,7 @@ std::string llvm::computeLTOCacheKey(
     const FunctionImporter::ExportSetTy &ExportList,
     const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
     const GVSummaryMapTy &DefinedGlobals,
+    const Triple& TT,
     const DenseSet<GlobalValue::GUID> &CfiFunctionDefs,
     const DenseSet<GlobalValue::GUID> &CfiFunctionDecls) {
   // Compute the unique hash for this entry.
@@ -140,14 +142,17 @@ std::string llvm::computeLTOCacheKey(
     Hasher.update(ArrayRef<uint8_t>(&I, 1));
   };
   AddString(Conf.CPU);
+  TargetOptions Opts = codegen::InitTargetOptionsFromCodeGenFlags(TT);
+  Conf.ModifyTargetOptions(Opts);
+
   // FIXME: Hash more of Options. For now all clients initialize Options from
   // command-line flags (which is unsupported in production), but may set
   // X86RelaxRelocations. The clang driver can also pass FunctionSections,
   // DataSections and DebuggerTuning via command line flags.
-  AddUnsigned(Conf.Options.MCOptions.X86RelaxRelocations);
-  AddUnsigned(Conf.Options.FunctionSections);
-  AddUnsigned(Conf.Options.DataSections);
-  AddUnsigned((unsigned)Conf.Options.DebuggerTuning);
+  AddUnsigned(Opts.MCOptions.X86RelaxRelocations);
+  AddUnsigned(Opts.FunctionSections);
+  AddUnsigned(Opts.DataSections);
+  AddUnsigned((unsigned)Opts.DebuggerTuning);
   for (auto &A : Conf.MAttrs)
     AddString(A);
   if (Conf.RelocModel)
@@ -1535,10 +1540,10 @@ class InProcessThinBackend : public CGThinBackend {
       const GVSummaryMapTy &DefinedGlobals,
       MapVector<StringRef, BitcodeModule> &ModuleMap) {
     auto ModuleID = BM.getModuleIdentifier();
+    LTOLLVMContext BackendContext(Conf);
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (in-process)",
                                    ModuleID);
     auto RunThinBackend = [&](AddStreamFn AddStream) {
-      LTOLLVMContext BackendContext(Conf);
       Expected<std::unique_ptr<Module>> MOrErr = 
BM.parseModule(BackendContext);
       if (!MOrErr)
         return MOrErr.takeError();
@@ -1559,10 +1564,15 @@ class InProcessThinBackend : public CGThinBackend {
       // no module hash.
       return RunThinBackend(AddStream);
 
+    auto Mod = ModuleMap.front().second.parseModule(BackendContext);
+    if (!Mod)
+      return Mod.takeError();
+    Triple TT = (*Mod)->getTargetTriple();
+
     // The module may be cached, this helps handling it.
     std::string Key = computeLTOCacheKey(
         Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
-        DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
+        DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls);
     Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
     if (Error Err = CacheAddStreamOrErr.takeError())
       return Err;
@@ -1650,9 +1660,9 @@ class FirstRoundThinBackend : public InProcessThinBackend 
{
     auto ModuleID = BM.getModuleIdentifier();
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)",
                                    ModuleID);
+      LTOLLVMContext BackendContext(Conf);
     auto RunThinBackend = [&](AddStreamFn CGAddStream,
                               AddStreamFn IRAddStream) {
-      LTOLLVMContext BackendContext(Conf);
       Expected<std::unique_ptr<Module>> MOrErr = 
BM.parseModule(BackendContext);
       if (!MOrErr)
         return MOrErr.takeError();
@@ -1678,10 +1688,15 @@ class FirstRoundThinBackend : public 
InProcessThinBackend {
       // no module hash.
       return RunThinBackend(CGAddStream, IRAddStream);
 
+    auto Mod = ModuleMap.front().second.parseModule(BackendContext);
+    if (!Mod)
+      return Mod.takeError();
+    Triple TT = (*Mod)->getTargetTriple();
+
     // Get CGKey for caching object in CGCache.
     std::string CGKey = computeLTOCacheKey(
         Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
-        DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
+        DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls);
     Expected<AddStreamFn> CacheCGAddStreamOrErr =
         CGCache(Task, CGKey, ModuleID);
     if (Error Err = CacheCGAddStreamOrErr.takeError())
@@ -1747,8 +1762,8 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
     auto ModuleID = BM.getModuleIdentifier();
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (second round)",
                                    ModuleID);
+    LTOLLVMContext BackendContext(Conf);
     auto RunThinBackend = [&](AddStreamFn AddStream) {
-      LTOLLVMContext BackendContext(Conf);
       std::unique_ptr<Module> LoadedModule =
           cgdata::loadModuleForTwoRounds(BM, Task, BackendContext, *IRFiles);
 
@@ -1763,11 +1778,16 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
       // no module hash.
       return RunThinBackend(AddStream);
 
+    auto Mod = ModuleMap.front().second.parseModule(BackendContext);
+    if (!Mod)
+      return Mod.takeError();
+    Triple TT = (*Mod)->getTargetTriple();
+
     // Get Key for caching the final object file in Cache with the combined
     // CGData hash.
     std::string Key = computeLTOCacheKey(
         Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
-        DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls);
+        DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls);
     Key = recomputeLTOCacheKey(Key,
                                /*ExtraID=*/std::to_string(CombinedCGDataHash));
     Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
@@ -2340,7 +2360,7 @@ class OutOfProcessThinBackend : public CGThinBackend {
     // The module may be cached, this helps handling it.
     J.CacheKey = computeLTOCacheKey(Conf, CombinedIndex, J.ModuleID, 
ImportList,
                                     ExportList, ResolvedODR, DefinedGlobals,
-                                    CfiFunctionDefs, CfiFunctionDecls);
+                                    Triple, CfiFunctionDefs, CfiFunctionDecls);
 
     // The module may be cached, this helps handling it.
     auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
@@ -2436,12 +2456,14 @@ class OutOfProcessThinBackend : public CGThinBackend {
     auto &Ops = CodegenOptions;
 
     Ops.push_back(Saver.save("-O" + Twine(C.OptLevel)));
+    TargetOptions TO = codegen::InitTargetOptionsFromCodeGenFlags(Triple);
+    C.ModifyTargetOptions(TO);
 
-    if (C.Options.EmitAddrsig)
+    if (TO.EmitAddrsig)
       Ops.push_back("-faddrsig");
-    if (C.Options.FunctionSections)
+    if (TO.FunctionSections)
       Ops.push_back("-ffunction-sections");
-    if (C.Options.DataSections)
+    if (TO.DataSections)
       Ops.push_back("-fdata-sections");
 
     if (C.RelocModel == Reloc::PIC_)
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 43e5c3b398372..cd3b476ba4ccf 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/CGData/CodeGenData.h"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/PassManager.h"
@@ -215,6 +216,9 @@ static void RegisterPassPlugins(ArrayRef<std::string> 
PassPlugins,
   }
 }
 
+// Required to call InitTargetOptionsFromCodeGenFlags().
+static  codegen::RegisterCodeGenFlags F;
+
 static std::unique_ptr<TargetMachine>
 createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
   const Triple &TheTriple = M.getTargetTriple();
@@ -236,7 +240,10 @@ createTargetMachine(const Config &Conf, const Target 
*TheTarget, Module &M) {
   else
     CodeModel = M.getCodeModel();
 
-  TargetOptions TargetOpts = Conf.Options;
+  TargetOptions TargetOpts =
+      codegen::InitTargetOptionsFromCodeGenFlags(TheTriple);
+  Conf.ModifyTargetOptions(TargetOpts);
+
   if (TargetOpts.MCOptions.ABIName.empty()) {
     TargetOpts.MCOptions.ABIName = M.getTargetABIFromMD();
   }
@@ -413,7 +420,7 @@ bool lto::opt(const Config &Conf, TargetMachine *TM, 
unsigned Task, Module &Mod,
   return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
 }
 
-static void codegen(const Config &Conf, TargetMachine *TM,
+static void startCodegen(const Config &Conf, TargetMachine *TM,
                     AddStreamFn AddStream, unsigned Task, Module &Mod,
                     const ModuleSummaryIndex &CombinedIndex) {
   llvm::TimeTraceScope timeScope("codegen");
@@ -526,7 +533,7 @@ static void splitCodeGen(const Config &C, TargetMachine *TM,
               std::unique_ptr<TargetMachine> TM =
                   createTargetMachine(C, T, *MPartInCtx);
 
-              codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
+              startCodegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
                       CombinedIndex);
             },
             // Pass BC using std::move to ensure that it get moved rather than
@@ -591,7 +598,7 @@ Error lto::backend(const Config &C, AddStreamFn AddStream,
   }
 
   if (ParallelCodeGenParallelismLevel == 1) {
-    codegen(C, TM.get(), AddStream, 0, Mod, CombinedIndex);
+    startCodegen(C, TM.get(), AddStream, 0, Mod, CombinedIndex);
   } else {
     splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, Mod,
                  CombinedIndex);
@@ -652,7 +659,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, 
AddStreamFn AddStream,
   if (CodeGenOnly) {
     // If CodeGenOnly is set, we only perform code generation and skip
     // optimization. This value may differ from Conf.CodeGenOnly.
-    codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
+    startCodegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
   }
 
@@ -675,7 +682,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, 
AddStreamFn AddStream,
         if (IRAddStream)
           cgdata::saveModuleForTwoRounds(Mod, Task, IRAddStream);
 
-        codegen(Conf, TM, AddStream, Task, Mod, CombinedIndex);
+        startCodegen(Conf, TM, AddStream, Task, Mod, CombinedIndex);
         return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
       };
 
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp 
b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 46be71da5a092..218048b3a0873 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -166,7 +166,7 @@ void LTOCodeGenerator::setModule(std::unique_ptr<LTOModule> 
Mod) {
 }
 
 void LTOCodeGenerator::setTargetOptions(const TargetOptions &Options) {
-  Config.Options = Options;
+  TO = Options;
 }
 
 void LTOCodeGenerator::setDebugInfo(lto_debug_model Debug) {
@@ -230,7 +230,7 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
 
 bool LTOCodeGenerator::useAIXSystemAssembler() {
   const auto &Triple = TargetMach->getTargetTriple();
-  return Triple.isOSAIX() && Config.Options.DisableIntegratedAS;
+  return Triple.isOSAIX() && TO.DisableIntegratedAS;
 }
 
 bool LTOCodeGenerator::runAIXSystemAssembler(SmallString<128> &AssemblyFile) {
@@ -397,7 +397,7 @@ bool LTOCodeGenerator::determineTarget() {
   // If data-sections is not explicitly set or unset, set data-sections by
   // default to match the behaviour of lld and gold plugin.
   if (!codegen::getExplicitDataSections())
-    Config.Options.DataSections = true;
+    TO.DataSections = true;
 
   TargetMach = createTargetMachine();
   assert(TargetMach && "Unable to create target machine");
@@ -408,7 +408,7 @@ bool LTOCodeGenerator::determineTarget() {
 std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
   assert(MArch && "MArch is not set!");
   return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
-      MergedModule->getTargetTriple(), Config.CPU, FeatureStr, Config.Options,
+      MergedModule->getTargetTriple(), Config.CPU, FeatureStr,TO,
       Config.RelocModel, std::nullopt, Config.CGOptLevel));
 }
 
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp 
b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 93b672ae7840c..22c53660f0a36 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -374,7 +374,6 @@ class ModuleCacheEntry {
 
     llvm::lto::Config Conf;
     Conf.OptLevel = OptLevel;
-    Conf.Options = TMBuilder.Options;
     Conf.CPU = TMBuilder.MCpu;
     Conf.MAttrs.push_back(TMBuilder.MAttr);
     Conf.RelocModel = TMBuilder.RelocModel;
@@ -382,7 +381,7 @@ class ModuleCacheEntry {
     Conf.Freestanding = Freestanding;
     std::string Key =
         computeLTOCacheKey(Conf, Index, ModuleID, ImportList, ExportList,
-                           ResolvedODR, DefinedGVSummaries);
+                           ResolvedODR, DefinedGVSummaries, 
TMBuilder.TheTriple);
 
     // This choice of file name allows the cache to be pruned (see pruneCache()
     // in include/llvm/Support/CachePruning.h).
diff --git a/llvm/lib/Target/TargetMachine.cpp 
b/llvm/lib/Target/TargetMachine.cpp
index 3f59b819ffbf1..f8f13a042fec0 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -257,9 +257,7 @@ bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue 
*GV) const {
 }
 
 bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; }
-bool TargetMachine::useTLSDESC() const {
-  return Options.EnableTLSDESC || TargetTriple.isOSFuchsia();
-}
+bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; }
 
 TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
   bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp 
b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 955c1130e9f4c..87ca7810d5486 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -334,7 +334,7 @@ static int run(int argc, char **argv) {
     Conf.TimeTraceGranularity = TimeTraceGranularity;
   }
   Conf.CPU = codegen::getMCPU();
-  Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
+  Conf.ModifyTargetOptions = [](llvm::TargetOptions &TO) {};
   Conf.MAttrs = codegen::getMAttrs();
   if (auto RM = codegen::getExplicitRelocModel())
     Conf.RelocModel = *RM;

>From 601741b4c3cb5556e1333a6a3a9addeedb33eef1 Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Thu, 5 Feb 2026 14:36:34 -0800
Subject: [PATCH 3/8] clang format

---
 clang/lib/CodeGen/BackendUtil.cpp     | 2 +-
 lld/COFF/LTO.cpp                      | 2 +-
 llvm/include/llvm/LTO/Config.h        | 4 ++--
 llvm/lib/LTO/LTO.cpp                  | 5 ++---
 llvm/lib/LTO/LTOBackend.cpp           | 8 ++++----
 llvm/lib/LTO/LTOCodeGenerator.cpp     | 2 +-
 llvm/lib/LTO/ThinLTOCodeGenerator.cpp | 6 +++---
 7 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 5afe8a07471c0..46d2f97807935 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1354,7 +1354,7 @@ runThinLTOBackend(CompilerInstance &CI, 
ModuleSummaryIndex *CombinedIndex,
   Conf.CGOptLevel = *OptLevelOrNone;
   Conf.OptLevel = CGOpts.OptimizationLevel;
   // llvm::codegen::RegisterCodeGenFlags F;
-  Conf.ModifyTargetOptions = [&](llvm::TargetOptions &TargetOpts)->void {
+  Conf.ModifyTargetOptions = [&](llvm::TargetOptions &TargetOpts) -> void {
     initTargetOptions(CI, Diags, TargetOpts);
   };
   Conf.SampleProfile = std::move(SampleProfile);
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index de083a356271e..f0dfe47a1d4d5 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -63,7 +63,7 @@ lto::Config BitcodeCompiler::createConfig() {
   for (StringRef C : ctx.config.mllvmOpts)
     c.MllvmArgs.emplace_back(C.str());
 
-    // Use static reloc model on 32-bit x86 because it usually results in more
+  // Use static reloc model on 32-bit x86 because it usually results in more
   // compact code, and because there are also known code generation bugs when
   // using the PIC model (see PR34306).
   if (ctx.config.machine == COFF::IMAGE_FILE_MACHINE_I386)
diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h
index 29350964fd0cb..4af8b4af5f177 100644
--- a/llvm/include/llvm/LTO/Config.h
+++ b/llvm/include/llvm/LTO/Config.h
@@ -48,7 +48,8 @@ struct Config {
   // computeLTOCacheKey in LTO.cpp.
   std::string CPU;
   // Callback to modify the target options once they are instantiated.
-  std::function<void(TargetOptions& Options)> ModifyTargetOptions = 
[](TargetOptions&){};
+  std::function<void(TargetOptions &Options)> ModifyTargetOptions =
+      [](TargetOptions &) {};
   std::vector<std::string> MAttrs;
   std::vector<std::string> MllvmArgs;
   std::vector<std::string> PassPlugins;
@@ -287,7 +288,6 @@ struct Config {
   LLVM_ABI Error addSaveTemps(std::string OutputFileName,
                               bool UseInputModulePath = false,
                               const DenseSet<StringRef> &SaveTempsArgs = {});
-
 };
 
 struct LTOLLVMDiagnosticHandler : public DiagnosticHandler {
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 01039ef0f8a43..f609a8a5a7a84 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -107,8 +107,7 @@ std::string llvm::computeLTOCacheKey(
     const FunctionImporter::ImportMapTy &ImportList,
     const FunctionImporter::ExportSetTy &ExportList,
     const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
-    const GVSummaryMapTy &DefinedGlobals,
-    const Triple& TT,
+    const GVSummaryMapTy &DefinedGlobals, const Triple &TT,
     const DenseSet<GlobalValue::GUID> &CfiFunctionDefs,
     const DenseSet<GlobalValue::GUID> &CfiFunctionDecls) {
   // Compute the unique hash for this entry.
@@ -1660,7 +1659,7 @@ class FirstRoundThinBackend : public InProcessThinBackend 
{
     auto ModuleID = BM.getModuleIdentifier();
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)",
                                    ModuleID);
-      LTOLLVMContext BackendContext(Conf);
+    LTOLLVMContext BackendContext(Conf);
     auto RunThinBackend = [&](AddStreamFn CGAddStream,
                               AddStreamFn IRAddStream) {
       Expected<std::unique_ptr<Module>> MOrErr = 
BM.parseModule(BackendContext);
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index cd3b476ba4ccf..09d9f40567ed7 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -217,7 +217,7 @@ static void RegisterPassPlugins(ArrayRef<std::string> 
PassPlugins,
 }
 
 // Required to call InitTargetOptionsFromCodeGenFlags().
-static  codegen::RegisterCodeGenFlags F;
+static codegen::RegisterCodeGenFlags F;
 
 static std::unique_ptr<TargetMachine>
 createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
@@ -421,8 +421,8 @@ bool lto::opt(const Config &Conf, TargetMachine *TM, 
unsigned Task, Module &Mod,
 }
 
 static void startCodegen(const Config &Conf, TargetMachine *TM,
-                    AddStreamFn AddStream, unsigned Task, Module &Mod,
-                    const ModuleSummaryIndex &CombinedIndex) {
+                         AddStreamFn AddStream, unsigned Task, Module &Mod,
+                         const ModuleSummaryIndex &CombinedIndex) {
   llvm::TimeTraceScope timeScope("codegen");
   if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod))
     return;
@@ -534,7 +534,7 @@ static void splitCodeGen(const Config &C, TargetMachine *TM,
                   createTargetMachine(C, T, *MPartInCtx);
 
               startCodegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
-                      CombinedIndex);
+                           CombinedIndex);
             },
             // Pass BC using std::move to ensure that it get moved rather than
             // copied into the thread's context.
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp 
b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 218048b3a0873..2826bb240b8e7 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -408,7 +408,7 @@ bool LTOCodeGenerator::determineTarget() {
 std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() {
   assert(MArch && "MArch is not set!");
   return std::unique_ptr<TargetMachine>(MArch->createTargetMachine(
-      MergedModule->getTargetTriple(), Config.CPU, FeatureStr,TO,
+      MergedModule->getTargetTriple(), Config.CPU, FeatureStr, TO,
       Config.RelocModel, std::nullopt, Config.CGOptLevel));
 }
 
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp 
b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 22c53660f0a36..da7d2c0b1955d 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -379,9 +379,9 @@ class ModuleCacheEntry {
     Conf.RelocModel = TMBuilder.RelocModel;
     Conf.CGOptLevel = TMBuilder.CGOptLevel;
     Conf.Freestanding = Freestanding;
-    std::string Key =
-        computeLTOCacheKey(Conf, Index, ModuleID, ImportList, ExportList,
-                           ResolvedODR, DefinedGVSummaries, 
TMBuilder.TheTriple);
+    std::string Key = computeLTOCacheKey(
+        Conf, Index, ModuleID, ImportList, ExportList, ResolvedODR,
+        DefinedGVSummaries, TMBuilder.TheTriple);
 
     // This choice of file name allows the cache to be pruned (see pruneCache()
     // in include/llvm/Support/CachePruning.h).

>From 15bb96342e7a830d61a56c37ac156fa7e932022f Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Tue, 10 Feb 2026 14:09:09 -0800
Subject: [PATCH 4/8] Address minor review comments

Cleanup stale comments and formatting.
---
 clang/lib/CodeGen/BackendUtil.cpp                  | 1 -
 lld/COFF/LTO.cpp                                   | 3 +--
 lld/Common/TargetOptionsCommandFlags.cpp           | 4 ----
 lld/ELF/LTO.cpp                                    | 1 -
 lld/include/lld/Common/TargetOptionsCommandFlags.h | 1 -
 5 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 46d2f97807935..934475750f70c 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1353,7 +1353,6 @@ runThinLTOBackend(CompilerInstance &CI, 
ModuleSummaryIndex *CombinedIndex,
   assert(OptLevelOrNone && "Invalid optimization level!");
   Conf.CGOptLevel = *OptLevelOrNone;
   Conf.OptLevel = CGOpts.OptimizationLevel;
-  // llvm::codegen::RegisterCodeGenFlags F;
   Conf.ModifyTargetOptions = [&](llvm::TargetOptions &TargetOpts) -> void {
     initTargetOptions(CI, Diags, TargetOpts);
   };
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index f0dfe47a1d4d5..aff38392dbcff 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -55,9 +55,8 @@ lto::Config BitcodeCompiler::createConfig() {
     options.FunctionSections = true;
     options.DataSections = true;
 
-    if (emitAsm) {
+    if (emitAsm)
       options.MCOptions.AsmVerbose = true;
-    }
   };
 
   for (StringRef C : ctx.config.mllvmOpts)
diff --git a/lld/Common/TargetOptionsCommandFlags.cpp 
b/lld/Common/TargetOptionsCommandFlags.cpp
index 0860e8ff8ef8e..5eb08e6e54e30 100644
--- a/lld/Common/TargetOptionsCommandFlags.cpp
+++ b/lld/Common/TargetOptionsCommandFlags.cpp
@@ -12,10 +12,6 @@
 #include "llvm/TargetParser/Triple.h"
 #include <optional>
 
-llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() {
-  return llvm::codegen::InitTargetOptionsFromCodeGenFlags(llvm::Triple());
-}
-
 std::optional<llvm::Reloc::Model> lld::getRelocModelFromCMModel() {
   return llvm::codegen::getExplicitRelocModel();
 }
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 692651a8506ca..4460781ce465e 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -161,7 +161,6 @@ static lto::Config createConfig(Ctx &ctx) {
 
   if (ctx.arg.ltoEmitAsm) {
     c.CGFileType = CodeGenFileType::AssemblyFile;
-    // c.Options.MCOptions.AsmVerbose = true;
   }
 
   if (!ctx.arg.saveTempsArgs.empty())
diff --git a/lld/include/lld/Common/TargetOptionsCommandFlags.h 
b/lld/include/lld/Common/TargetOptionsCommandFlags.h
index 9bc22d441e183..4897126c90a79 100644
--- a/lld/include/lld/Common/TargetOptionsCommandFlags.h
+++ b/lld/include/lld/Common/TargetOptionsCommandFlags.h
@@ -18,7 +18,6 @@
 #include <optional>
 
 namespace lld {
-llvm::TargetOptions initTargetOptionsFromCodeGenFlags();
 std::optional<llvm::Reloc::Model> getRelocModelFromCMModel();
 std::optional<llvm::CodeModel::Model> getCodeModelFromCMModel();
 std::string getCPUStr();

>From 54b0c8c72d484ef72874185202d6eeee1e6e2000 Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Tue, 10 Feb 2026 14:10:42 -0800
Subject: [PATCH 5/8] Plumb the Triple through runThinLTO APIs

---
 llvm/include/llvm/LTO/LTO.h |  2 +-
 llvm/lib/LTO/LTO.cpp        | 38 ++++++++++++-------------------------
 2 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index fd91345cf548f..4f50256ba949c 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -274,7 +274,7 @@ class ThinBackendProc {
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
-      MapVector<StringRef, BitcodeModule> &ModuleMap) = 0;
+      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) = 0;
   virtual Error wait() {
     BackendThreadPool.wait();
     if (Err)
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index f609a8a5a7a84..07adde7bb42b7 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -1537,7 +1537,7 @@ class InProcessThinBackend : public CGThinBackend {
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
       const GVSummaryMapTy &DefinedGlobals,
-      MapVector<StringRef, BitcodeModule> &ModuleMap) {
+      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) {
     auto ModuleID = BM.getModuleIdentifier();
     LTOLLVMContext BackendContext(Conf);
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (in-process)",
@@ -1563,15 +1563,10 @@ class InProcessThinBackend : public CGThinBackend {
       // no module hash.
       return RunThinBackend(AddStream);
 
-    auto Mod = ModuleMap.front().second.parseModule(BackendContext);
-    if (!Mod)
-      return Mod.takeError();
-    Triple TT = (*Mod)->getTargetTriple();
-
     // The module may be cached, this helps handling it.
     std::string Key = computeLTOCacheKey(
         Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
-        DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls);
+        DefinedGlobals, TheTriple, CfiFunctionDefs, CfiFunctionDecls);
     Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
     if (Error Err = CacheAddStreamOrErr.takeError())
       return Err;
@@ -1587,7 +1582,7 @@ class InProcessThinBackend : public CGThinBackend {
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
-      MapVector<StringRef, BitcodeModule> &ModuleMap) override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
     StringRef ModulePath = BM.getModuleIdentifier();
     assert(ModuleToDefinedGVSummaries.count(ModulePath));
     const GVSummaryMapTy &DefinedGlobals =
@@ -1605,7 +1600,7 @@ class InProcessThinBackend : public CGThinBackend {
                                         "thin backend");
           Error E = runThinLTOBackendThread(
               AddStream, Cache, Task, BM, CombinedIndex, ImportList, 
ExportList,
-              ResolvedODR, DefinedGlobals, ModuleMap);
+              ResolvedODR, DefinedGlobals, ModuleMap, TheTriple);
           if (E) {
             std::unique_lock<std::mutex> L(ErrMu);
             if (Err)
@@ -1655,7 +1650,7 @@ class FirstRoundThinBackend : public InProcessThinBackend 
{
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
       const GVSummaryMapTy &DefinedGlobals,
-      MapVector<StringRef, BitcodeModule> &ModuleMap) override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
     auto ModuleID = BM.getModuleIdentifier();
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)",
                                    ModuleID);
@@ -1687,15 +1682,10 @@ class FirstRoundThinBackend : public 
InProcessThinBackend {
       // no module hash.
       return RunThinBackend(CGAddStream, IRAddStream);
 
-    auto Mod = ModuleMap.front().second.parseModule(BackendContext);
-    if (!Mod)
-      return Mod.takeError();
-    Triple TT = (*Mod)->getTargetTriple();
-
     // Get CGKey for caching object in CGCache.
     std::string CGKey = computeLTOCacheKey(
         Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
-        DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls);
+        DefinedGlobals, TheTriple, CfiFunctionDefs, CfiFunctionDecls);
     Expected<AddStreamFn> CacheCGAddStreamOrErr =
         CGCache(Task, CGKey, ModuleID);
     if (Error Err = CacheCGAddStreamOrErr.takeError())
@@ -1757,7 +1747,7 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
       const GVSummaryMapTy &DefinedGlobals,
-      MapVector<StringRef, BitcodeModule> &ModuleMap) override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
     auto ModuleID = BM.getModuleIdentifier();
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (second round)",
                                    ModuleID);
@@ -1777,16 +1767,11 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
       // no module hash.
       return RunThinBackend(AddStream);
 
-    auto Mod = ModuleMap.front().second.parseModule(BackendContext);
-    if (!Mod)
-      return Mod.takeError();
-    Triple TT = (*Mod)->getTargetTriple();
-
     // Get Key for caching the final object file in Cache with the combined
     // CGData hash.
     std::string Key = computeLTOCacheKey(
         Conf, CombinedIndex, ModuleID, ImportList, ExportList, ResolvedODR,
-        DefinedGlobals, TT, CfiFunctionDefs, CfiFunctionDecls);
+        DefinedGlobals, TheTriple, CfiFunctionDefs, CfiFunctionDecls);
     Key = recomputeLTOCacheKey(Key,
                                /*ExtraID=*/std::to_string(CombinedCGDataHash));
     Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
@@ -1879,7 +1864,7 @@ class WriteIndexesThinBackend : public ThinBackendProc {
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
-      MapVector<StringRef, BitcodeModule> &ModuleMap) override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
     StringRef ModulePath = BM.getModuleIdentifier();
 
     // The contents of this file may be used as input to a native link, and 
must
@@ -2108,6 +2093,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache 
Cache,
       ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
 
   auto RunBackends = [&](ThinBackendProc *BackendProcess) -> Error {
+    Triple TheTriple = RegularLTO.CombinedModule->getTargetTriple();
     auto ProcessOneModule = [&](int I) -> Error {
       auto &Mod = *(ModuleMap.begin() + I);
       // Tasks 0 through ParallelCodeGenParallelismLevel-1 are reserved for
@@ -2115,7 +2101,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache 
Cache,
       return BackendProcess->start(
           RegularLTO.ParallelCodeGenParallelismLevel + I, Mod.second,
           ImportLists[Mod.first], ExportLists[Mod.first],
-          ResolvedODR[Mod.first], ThinLTO.ModuleMap);
+          ResolvedODR[Mod.first], ThinLTO.ModuleMap, TheTriple);
     };
 
     BackendProcess->setup(ModuleMap.size(),
@@ -2385,7 +2371,7 @@ class OutOfProcessThinBackend : public CGThinBackend {
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
-      MapVector<StringRef, BitcodeModule> &ModuleMap) override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap, class Triple TheTriple) 
override {
 
     StringRef ModulePath = BM.getModuleIdentifier();
 

>From 1794c31d7443241e68a4c90f5e99f1a1d570c607 Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Tue, 10 Feb 2026 14:11:15 -0800
Subject: [PATCH 6/8] Fix formatting

---
 .../lld/Common/TargetOptionsCommandFlags.h        |  2 +-
 llvm/lib/LTO/LTO.cpp                              | 15 ++++++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/lld/include/lld/Common/TargetOptionsCommandFlags.h 
b/lld/include/lld/Common/TargetOptionsCommandFlags.h
index 4897126c90a79..8b8ecba11f796 100644
--- a/lld/include/lld/Common/TargetOptionsCommandFlags.h
+++ b/lld/include/lld/Common/TargetOptionsCommandFlags.h
@@ -22,6 +22,6 @@ std::optional<llvm::Reloc::Model> getRelocModelFromCMModel();
 std::optional<llvm::CodeModel::Model> getCodeModelFromCMModel();
 std::string getCPUStr();
 std::vector<std::string> getMAttrs();
-}
+} // namespace lld
 
 #endif
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 07adde7bb42b7..322f81c5ae864 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -1582,7 +1582,8 @@ class InProcessThinBackend : public CGThinBackend {
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
-      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap,
+      Triple TheTriple) override {
     StringRef ModulePath = BM.getModuleIdentifier();
     assert(ModuleToDefinedGVSummaries.count(ModulePath));
     const GVSummaryMapTy &DefinedGlobals =
@@ -1650,7 +1651,8 @@ class FirstRoundThinBackend : public InProcessThinBackend 
{
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
       const GVSummaryMapTy &DefinedGlobals,
-      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap,
+      Triple TheTriple) override {
     auto ModuleID = BM.getModuleIdentifier();
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)",
                                    ModuleID);
@@ -1747,7 +1749,8 @@ class SecondRoundThinBackend : public 
InProcessThinBackend {
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
       const GVSummaryMapTy &DefinedGlobals,
-      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap,
+      Triple TheTriple) override {
     auto ModuleID = BM.getModuleIdentifier();
     llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (second round)",
                                    ModuleID);
@@ -1864,7 +1867,8 @@ class WriteIndexesThinBackend : public ThinBackendProc {
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
-      MapVector<StringRef, BitcodeModule> &ModuleMap, Triple TheTriple) 
override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap,
+      Triple TheTriple) override {
     StringRef ModulePath = BM.getModuleIdentifier();
 
     // The contents of this file may be used as input to a native link, and 
must
@@ -2371,7 +2375,8 @@ class OutOfProcessThinBackend : public CGThinBackend {
       const FunctionImporter::ImportMapTy &ImportList,
       const FunctionImporter::ExportSetTy &ExportList,
       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 
&ResolvedODR,
-      MapVector<StringRef, BitcodeModule> &ModuleMap, class Triple TheTriple) 
override {
+      MapVector<StringRef, BitcodeModule> &ModuleMap,
+      class Triple TheTriple) override {
 
     StringRef ModulePath = BM.getModuleIdentifier();
 

>From a276e00ab3da7ff002f826bed8d68dc3a39f9535 Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Tue, 10 Feb 2026 14:53:45 -0800
Subject: [PATCH 7/8] Restore static API name in LTOBackend.cpp

---
 llvm/lib/LTO/LTOBackend.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 09d9f40567ed7..20310e2ebf855 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -420,7 +420,7 @@ bool lto::opt(const Config &Conf, TargetMachine *TM, 
unsigned Task, Module &Mod,
   return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
 }
 
-static void startCodegen(const Config &Conf, TargetMachine *TM,
+static void codegen(const Config &Conf, TargetMachine *TM,
                          AddStreamFn AddStream, unsigned Task, Module &Mod,
                          const ModuleSummaryIndex &CombinedIndex) {
   llvm::TimeTraceScope timeScope("codegen");
@@ -533,7 +533,7 @@ static void splitCodeGen(const Config &C, TargetMachine *TM,
               std::unique_ptr<TargetMachine> TM =
                   createTargetMachine(C, T, *MPartInCtx);
 
-              startCodegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
+              ::codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
                            CombinedIndex);
             },
             // Pass BC using std::move to ensure that it get moved rather than
@@ -598,7 +598,7 @@ Error lto::backend(const Config &C, AddStreamFn AddStream,
   }
 
   if (ParallelCodeGenParallelismLevel == 1) {
-    startCodegen(C, TM.get(), AddStream, 0, Mod, CombinedIndex);
+    ::codegen(C, TM.get(), AddStream, 0, Mod, CombinedIndex);
   } else {
     splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, Mod,
                  CombinedIndex);
@@ -659,7 +659,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, 
AddStreamFn AddStream,
   if (CodeGenOnly) {
     // If CodeGenOnly is set, we only perform code generation and skip
     // optimization. This value may differ from Conf.CodeGenOnly.
-    startCodegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
+    ::codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
   }
 
@@ -682,7 +682,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, 
AddStreamFn AddStream,
         if (IRAddStream)
           cgdata::saveModuleForTwoRounds(Mod, Task, IRAddStream);
 
-        startCodegen(Conf, TM, AddStream, Task, Mod, CombinedIndex);
+        ::codegen(Conf, TM, AddStream, Task, Mod, CombinedIndex);
         return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
       };
 

>From 94993fdf14a5fd844a03f4fbedd5ea54a04dcb84 Mon Sep 17 00:00:00 2001
From: Paul Kirth <[email protected]>
Date: Tue, 10 Feb 2026 15:30:01 -0800
Subject: [PATCH 8/8] Clang Format

---
 llvm/lib/LTO/LTOBackend.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 20310e2ebf855..e6d249754db40 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -421,8 +421,8 @@ bool lto::opt(const Config &Conf, TargetMachine *TM, 
unsigned Task, Module &Mod,
 }
 
 static void codegen(const Config &Conf, TargetMachine *TM,
-                         AddStreamFn AddStream, unsigned Task, Module &Mod,
-                         const ModuleSummaryIndex &CombinedIndex) {
+                    AddStreamFn AddStream, unsigned Task, Module &Mod,
+                    const ModuleSummaryIndex &CombinedIndex) {
   llvm::TimeTraceScope timeScope("codegen");
   if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod))
     return;
@@ -534,7 +534,7 @@ static void splitCodeGen(const Config &C, TargetMachine *TM,
                   createTargetMachine(C, T, *MPartInCtx);
 
               ::codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
-                           CombinedIndex);
+                        CombinedIndex);
             },
             // Pass BC using std::move to ensure that it get moved rather than
             // copied into the thread's context.

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

Reply via email to