[clang] [lld] [llvm] [Option] Make OptionsStruct per-context by default (PR #232170)
Fangrui Song via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 14 20:59:25 PDT 2026
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/232170
>From baeb153d00cefd92e629693401a1d74def1f2595 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 14 Oct 2026 19:39:01 -0700
Subject: [PATCH 1/3] [Option] Make OptionsStruct per-context by default
Make perContext the default, and opt out the ported libraries that still
read Global with perContext = false. X86Options, X86MCOptions, and
RISCVOptions become per-context.
A TargetMachine and the MC layer have no LLVMContext. Add
MCTargetOptions::LibraryOptions, which llc, opt, and clang set to the
compiled module's LLVMContext. X86TargetMachine, RISCVTargetMachine, and
X86's MCAsmInfo, MCAsmBackend, and MCTargetAsmParser read their options
through LibraryOptionsContext::get, which returns the global values when
it is unset, as in llvm-mc and clang -cc1as.
Aided by Opus 5.5
---
clang/lib/CodeGen/BackendUtil.cpp | 2 +
llvm/include/llvm/CodeGen/CommandFlags.h | 3 +-
llvm/include/llvm/MC/MCTargetOptions.h | 8 ++
llvm/include/llvm/Option/LibraryOptions.td | 2 +-
.../llvm/Support/LibraryOptionsContext.h | 5 ++
llvm/lib/CGData/CGDataOptions.td | 2 +-
llvm/lib/CodeGen/CodeGenOptions.td | 2 +-
llvm/lib/CodeGen/CommandFlags.cpp | 11 +--
llvm/lib/MC/MCCLOptions.td | 2 +-
llvm/lib/Passes/PassesOptions.td | 2 +-
llvm/lib/Target/AArch64/AArch64Options.td | 2 +-
.../AArch64/MCTargetDesc/AArch64MCOptions.td | 2 +-
.../Target/Mips/MCTargetDesc/MipsMCOptions.td | 2 +-
llvm/lib/Target/Mips/MipsOptions.td | 2 +-
.../RISCV/MCTargetDesc/RISCVMCOptions.td | 2 +-
llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 4 +-
llvm/lib/Target/Sparc/SparcOptions.td | 2 +-
.../lib/Target/X86/AsmParser/X86AsmParser.cpp | 4 +-
.../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 78 ++++++++++---------
.../Target/X86/MCTargetDesc/X86MCAsmInfo.cpp | 14 ++--
llvm/lib/Target/X86/X86TargetMachine.cpp | 5 +-
.../InstCombine/InstCombineCLOptions.td | 2 +-
.../Instrumentation/InstrumentationOptions.td | 2 +-
llvm/lib/Transforms/Scalar/ScalarOptions.td | 2 +-
.../Transforms/Vectorize/VectorizeOptions.td | 2 +-
llvm/tools/llc/lib/llcdriver.cpp | 1 +
llvm/tools/opt/optdriver.cpp | 4 +-
llvm/unittests/Option/LibraryOpts.td | 2 +-
28 files changed, 102 insertions(+), 69 deletions(-)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index f07e4ee84b9b65..5a9ff964380023 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -597,6 +597,8 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
llvm::TargetOptions Options;
if (!initTargetOptions(CI, Diags, Options))
return;
+ Options.MCOptions.LibraryOptions =
+ &TheModule->getContext().getLibraryOptions();
TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
Options, RM, CM, OptLevel));
if (TM)
diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index 4e09a2c720c170..8959d7995fb9b7 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -194,7 +194,8 @@ LLVM_ABI void setFunctionAttributes(Module &M, StringRef CPU,
/// the TargetOptions.
LLVM_ABI Expected<std::unique_ptr<TargetMachine>> createTargetMachineForTriple(
const Triple &TargetTriple,
- CodeGenOptLevel OptLevel = CodeGenOptLevel::Default);
+ CodeGenOptLevel OptLevel = CodeGenOptLevel::Default,
+ const cl::LibraryOptionsContext *LibraryOptions = nullptr);
/// Conditionally enables the collection of LLVM statistics during the tool run,
/// based on the value of the flag. Must be called before the tool run to
diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h
index 6bda34904a5c56..8414723cf6e0c8 100644
--- a/llvm/include/llvm/MC/MCTargetOptions.h
+++ b/llvm/include/llvm/MC/MCTargetOptions.h
@@ -35,6 +35,9 @@ enum class RelocSectionSymType {
};
class StringRef;
+namespace cl {
+class LibraryOptionsContext;
+} // namespace cl
class MCTargetOptions {
public:
@@ -133,6 +136,11 @@ class MCTargetOptions {
// (personality/LSDA/TType already default to sdata8).
bool LargeEHEncoding = false;
+ // The library options of the compilation, usually its LLVMContext's.
+ // TODO: Make it non-null once every tool sets it. Null means the global
+ // values.
+ const cl::LibraryOptionsContext *LibraryOptions = nullptr;
+
LLVM_ABI MCTargetOptions();
/// Parse a binutils version string ("major[.minor]" or "none") into a
diff --git a/llvm/include/llvm/Option/LibraryOptions.td b/llvm/include/llvm/Option/LibraryOptions.td
index ab027c056831ea..9cd18a5a0de1d9 100644
--- a/llvm/include/llvm/Option/LibraryOptions.td
+++ b/llvm/include/llvm/Option/LibraryOptions.td
@@ -18,7 +18,7 @@ include "llvm/Option/OptParser.td"
// A row whose spelling starts with prefix names its member without it.
// perContext makes Global private; read through cl::LibraryOptionsContext::get.
-class OptionsStruct<string namespace = "llvm", string prefix = "", bit perContext = false> {
+class OptionsStruct<string namespace = "llvm", string prefix = "", bit perContext = true> {
string Namespace = namespace;
string MemberPrefix = prefix;
bit PerContext = perContext;
diff --git a/llvm/include/llvm/Support/LibraryOptionsContext.h b/llvm/include/llvm/Support/LibraryOptionsContext.h
index 16312dc4ba32b1..4fad737637db78 100644
--- a/llvm/include/llvm/Support/LibraryOptionsContext.h
+++ b/llvm/include/llvm/Support/LibraryOptionsContext.h
@@ -50,6 +50,11 @@ class LLVM_ABI LibraryOptionsContext {
return T::Global;
}
+ // C's values of T, or T::Global if C is null.
+ template <typename T> static const T &get(const LibraryOptionsContext *C) {
+ return C ? C->get<T>() : T::Global;
+ }
+
private:
DenseMap<const void *, void *> Values;
SmallVector<const char *, 0> SavedArgs;
diff --git a/llvm/lib/CGData/CGDataOptions.td b/llvm/lib/CGData/CGDataOptions.td
index 025e91f5bca236..0e4cbdcc005bac 100644
--- a/llvm/lib/CGData/CGDataOptions.td
+++ b/llvm/lib/CGData/CGDataOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def CGDataOptions : OptionsStruct;
+def CGDataOptions : OptionsStruct<perContext = false>;
defm : BoolField<"codegen-data-generate", "false",
"Emit CodeGen Data into custom sections">;
diff --git a/llvm/lib/CodeGen/CodeGenOptions.td b/llvm/lib/CodeGen/CodeGenOptions.td
index 21ba8450ca3947..0b644d0b96e96c 100644
--- a/llvm/lib/CodeGen/CodeGenOptions.td
+++ b/llvm/lib/CodeGen/CodeGenOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def CodeGenOptions : OptionsStruct;
+def CodeGenOptions : OptionsStruct<perContext = false>;
// CodeGenPrepare.cpp
defm : BoolField<"bbsections-guided-section-prefix", "true",
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 46a294f3524b94..ea1b0a089f5f3a 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -752,9 +752,9 @@ void codegen::setFunctionAttributes(Module &M, StringRef CPU,
setFunctionAttributes(F, CPU, Features, TuneCPU);
}
-Expected<std::unique_ptr<TargetMachine>>
-codegen::createTargetMachineForTriple(const Triple &TargetTriple,
- CodeGenOptLevel OptLevel) {
+Expected<std::unique_ptr<TargetMachine>> codegen::createTargetMachineForTriple(
+ const Triple &TargetTriple, CodeGenOptLevel OptLevel,
+ const cl::LibraryOptionsContext *LibraryOptions) {
// lookupTarget may mutate the triple, so we need a copy.
Triple TheTriple(TargetTriple);
std::string Error;
@@ -762,9 +762,10 @@ codegen::createTargetMachineForTriple(const Triple &TargetTriple,
TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
if (!TheTarget)
return createStringError(inconvertibleErrorCode(), Error);
+ TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(TheTriple);
+ Options.MCOptions.LibraryOptions = LibraryOptions;
auto *Target = TheTarget->createTargetMachine(
- TheTriple, codegen::getCPUStr(), codegen::getFeaturesStr(),
- codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
+ TheTriple, codegen::getCPUStr(), codegen::getFeaturesStr(), Options,
codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
OptLevel);
if (!Target)
diff --git a/llvm/lib/MC/MCCLOptions.td b/llvm/lib/MC/MCCLOptions.td
index 37bb5ac6a3125a..fea3e378450a4b 100644
--- a/llvm/lib/MC/MCCLOptions.td
+++ b/llvm/lib/MC/MCCLOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def MCCLOptions : OptionsStruct;
+def MCCLOptions : OptionsStruct<perContext = false>;
defm : DefaultOnOffField<"dwarf-extended-loc",
"Disable emission of the extended flags in .loc directives">;
diff --git a/llvm/lib/Passes/PassesOptions.td b/llvm/lib/Passes/PassesOptions.td
index 4398d5c06bff2b..8789b2a243dd8c 100644
--- a/llvm/lib/Passes/PassesOptions.td
+++ b/llvm/lib/Passes/PassesOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def PassesOptions : OptionsStruct;
+def PassesOptions : OptionsStruct<perContext = false>;
// PassBuilder.cpp
defm : FlagOrEnumField<"print-pipeline-passes",
diff --git a/llvm/lib/Target/AArch64/AArch64Options.td b/llvm/lib/Target/AArch64/AArch64Options.td
index 57cd2553c7aeb4..ed6f6e3888d8d8 100644
--- a/llvm/lib/Target/AArch64/AArch64Options.td
+++ b/llvm/lib/Target/AArch64/AArch64Options.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def AArch64Options : OptionsStruct<prefix = "aarch64-">;
+def AArch64Options : OptionsStruct<prefix = "aarch64-", perContext = false>;
// AArch64A57FPLoadBalancing.cpp
// Enforce the algorithm to use the scavenged register even when the original
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCOptions.td b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCOptions.td
index c8805db89fa46a..e73d73daebfa98 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCOptions.td
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def AArch64MCOptions : OptionsStruct<prefix = "aarch64-">;
+def AArch64MCOptions : OptionsStruct<prefix = "aarch64-", perContext = false>;
// AArch64MCAsmInfo.cpp
defm : EnumField<"aarch64-neon-syntax", "std::optional<AArch64::AsmWriterVariantTy>", "std::nullopt",
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCOptions.td b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCOptions.td
index da7bc248b46116..ce5403d97cbed6 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCOptions.td
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def MipsMCOptions : OptionsStruct<prefix = "mips-">;
+def MipsMCOptions : OptionsStruct<prefix = "mips-", perContext = false>;
// MCTargetDesc/MipsABIInfo.cpp
defm : BoolField<"mips-jalr-reloc", "true",
diff --git a/llvm/lib/Target/Mips/MipsOptions.td b/llvm/lib/Target/Mips/MipsOptions.td
index 22e0c8e652b538..7e239ebd3ca003 100644
--- a/llvm/lib/Target/Mips/MipsOptions.td
+++ b/llvm/lib/Target/Mips/MipsOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def MipsOptions : OptionsStruct<prefix = "mips-">;
+def MipsOptions : OptionsStruct<prefix = "mips-", perContext = false>;
// Mips16ISelLowering.cpp
defm : BoolField<"mips16-dont-expand-cond-pseudo", "false",
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCOptions.td b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCOptions.td
index 491914a1a9b465..daf443dd9ebcf8 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCOptions.td
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def RISCVMCOptions : OptionsStruct<prefix = "riscv-">;
+def RISCVMCOptions : OptionsStruct<prefix = "riscv-", perContext = false>;
// AsmParser/RISCVAsmParser.cpp
defm : BoolField<"riscv-add-build-attributes", "false", "">;
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 5b717bbe02b538..1100e6ebfa304c 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -107,7 +107,9 @@ RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
: CodeGenTargetMachineImpl(T, TT, CPU, FS, Options,
getEffectiveRelocModel(TT, RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
- CLOpts(RISCVOptions::Global), TLOF(createTLOF(TT)) {
+ CLOpts(cl::LibraryOptionsContext::get<RISCVOptions>(
+ Options.MCOptions.LibraryOptions)),
+ TLOF(createTLOF(TT)) {
initAsmInfo();
// RISC-V supports the MachineOutliner.
diff --git a/llvm/lib/Target/Sparc/SparcOptions.td b/llvm/lib/Target/Sparc/SparcOptions.td
index 8d02271270e8e4..d76ad8c275325d 100644
--- a/llvm/lib/Target/Sparc/SparcOptions.td
+++ b/llvm/lib/Target/Sparc/SparcOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def SparcOptions : OptionsStruct<prefix = "sparc-">;
+def SparcOptions : OptionsStruct<prefix = "sparc-", perContext = false>;
defm : BoolField<"disable-sparc-delay-filler", "false",
"Disable the Sparc delay slot filler">;
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 4fefb1a6f6597f..47ce4689c622e0 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1401,7 +1401,9 @@ class X86AsmParser : public MCTargetAsmParser {
X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
const MCInstrInfo &mii)
- : MCTargetAsmParser(sti, mii), CLOpts(X86MCOptions::Global),
+ : MCTargetAsmParser(sti, mii),
+ CLOpts(cl::LibraryOptionsContext::get<X86MCOptions>(
+ Parser.getContext().getTargetOptions().LibraryOptions)),
InstInfo(nullptr), Code16GCC(false) {
Parser.addAliasForDirective(".word", ".2byte");
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 1368d9f91c450b..2aa611d6d6f192 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -97,9 +97,10 @@ class X86AsmBackend : public MCAsmBackend {
void emitInstructionEndBundle(MCObjectStreamer &OS);
public:
- X86AsmBackend(const Target &T, const MCSubtargetInfo &STI)
- : MCAsmBackend(llvm::endianness::little), CLOpts(X86MCOptions::Global),
- STI(STI), MCII(T.createMCInstrInfo()) {
+ X86AsmBackend(const X86MCOptions &CLOpts, const Target &T,
+ const MCSubtargetInfo &STI)
+ : MCAsmBackend(llvm::endianness::little), CLOpts(CLOpts), STI(STI),
+ MCII(T.createMCInstrInfo()) {
if (CLOpts.branches_within_32B_boundaries) {
// At the moment, this defaults to aligning fused branches, unconditional
// jumps, and (unfused) conditional jumps with nops. Both the
@@ -125,6 +126,8 @@ class X86AsmBackend : public MCAsmBackend {
AllowBundling = true;
}
+ const X86MCOptions &getCLOpts() const { return CLOpts; }
+
// The streamer frees the fragments these point into.
void reset() override {
PrevInst = MCInst();
@@ -424,8 +427,9 @@ bool X86AsmBackend::needAlign(const MCInst &Inst) const {
void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst,
const MCSubtargetInfo &STI) {
+ auto &Backend = static_cast<X86AsmBackend &>(S.getAssembler().getBackend());
bool AutoPadding = S.getAllowAutoPadding();
- if (LLVM_LIKELY(!AutoPadding && !X86MCOptions::Global.pad_for_align)) {
+ if (LLVM_LIKELY(!AutoPadding && !Backend.getCLOpts().pad_for_align)) {
S.MCObjectStreamer::emitInstruction(Inst, STI);
return;
}
@@ -436,7 +440,6 @@ void X86_MC::emitInstruction(MCObjectStreamer &S, const MCInst &Inst,
if (S.getLFIRewriter() && S.getLFIRewriter()->rewriteInst(Inst, S, STI))
return;
- auto &Backend = static_cast<X86AsmBackend &>(S.getAssembler().getBackend());
Backend.emitInstructionBegin(S, Inst, STI);
S.MCObjectStreamer::emitInstruction(Inst, STI);
Backend.emitInstructionEnd(S, Inst);
@@ -1186,15 +1189,16 @@ namespace {
class ELFX86AsmBackend : public X86AsmBackend {
public:
uint8_t OSABI;
- ELFX86AsmBackend(const Target &T, uint8_t OSABI, const MCSubtargetInfo &STI)
- : X86AsmBackend(T, STI), OSABI(OSABI) {}
+ ELFX86AsmBackend(const X86MCOptions &CLOpts, const Target &T, uint8_t OSABI,
+ const MCSubtargetInfo &STI)
+ : X86AsmBackend(CLOpts, T, STI), OSABI(OSABI) {}
};
class ELFX86_32AsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_32AsmBackend(const Target &T, uint8_t OSABI,
- const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(T, OSABI, STI) {}
+ ELFX86_32AsmBackend(const X86MCOptions &CLOpts, const Target &T,
+ uint8_t OSABI, const MCSubtargetInfo &STI)
+ : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1204,9 +1208,9 @@ class ELFX86_32AsmBackend : public ELFX86AsmBackend {
class ELFX86_X32AsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI,
- const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(T, OSABI, STI) {}
+ ELFX86_X32AsmBackend(const X86MCOptions &CLOpts, const Target &T,
+ uint8_t OSABI, const MCSubtargetInfo &STI)
+ : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1217,9 +1221,9 @@ class ELFX86_X32AsmBackend : public ELFX86AsmBackend {
class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_IAMCUAsmBackend(const Target &T, uint8_t OSABI,
- const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(T, OSABI, STI) {}
+ ELFX86_IAMCUAsmBackend(const X86MCOptions &CLOpts, const Target &T,
+ uint8_t OSABI, const MCSubtargetInfo &STI)
+ : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1230,9 +1234,9 @@ class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend {
class ELFX86_64AsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_64AsmBackend(const Target &T, uint8_t OSABI,
- const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(T, OSABI, STI) {}
+ ELFX86_64AsmBackend(const X86MCOptions &CLOpts, const Target &T,
+ uint8_t OSABI, const MCSubtargetInfo &STI)
+ : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1244,11 +1248,9 @@ class WindowsX86AsmBackend : public X86AsmBackend {
bool Is64Bit;
public:
- WindowsX86AsmBackend(const Target &T, bool is64Bit,
- const MCSubtargetInfo &STI)
- : X86AsmBackend(T, STI)
- , Is64Bit(is64Bit) {
- }
+ WindowsX86AsmBackend(const X86MCOptions &CLOpts, const Target &T,
+ bool is64Bit, const MCSubtargetInfo &STI)
+ : X86AsmBackend(CLOpts, T, STI), Is64Bit(is64Bit) {}
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override {
return StringSwitch<std::optional<MCFixupKind>>(Name)
@@ -1438,9 +1440,9 @@ class DarwinX86AsmBackend : public X86AsmBackend {
}
public:
- DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI)
- : X86AsmBackend(T, STI), MRI(MRI), TT(STI.getTargetTriple()),
+ DarwinX86AsmBackend(const X86MCOptions &CLOpts, const Target &T,
+ const MCRegisterInfo &MRI, const MCSubtargetInfo &STI)
+ : X86AsmBackend(CLOpts, T, STI), MRI(MRI), TT(STI.getTargetTriple()),
Is64Bit(TT.isX86_64()) {
memset(SavedRegs, 0, sizeof(SavedRegs));
OffsetSize = Is64Bit ? 8 : 4;
@@ -1632,18 +1634,20 @@ MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
const Triple &TheTriple = STI.getTargetTriple();
+ const X86MCOptions &CLOpts =
+ cl::LibraryOptionsContext::get<X86MCOptions>(Options.LibraryOptions);
if (TheTriple.isOSBinFormatMachO())
- return new DarwinX86AsmBackend(T, MRI, STI);
+ return new DarwinX86AsmBackend(CLOpts, T, MRI, STI);
if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
- return new WindowsX86AsmBackend(T, false, STI);
+ return new WindowsX86AsmBackend(CLOpts, T, false, STI);
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
if (TheTriple.isOSIAMCU())
- return new ELFX86_IAMCUAsmBackend(T, OSABI, STI);
+ return new ELFX86_IAMCUAsmBackend(CLOpts, T, OSABI, STI);
- return new ELFX86_32AsmBackend(T, OSABI, STI);
+ return new ELFX86_32AsmBackend(CLOpts, T, OSABI, STI);
}
MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
@@ -1651,23 +1655,25 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
const Triple &TheTriple = STI.getTargetTriple();
+ const X86MCOptions &CLOpts =
+ cl::LibraryOptionsContext::get<X86MCOptions>(Options.LibraryOptions);
if (TheTriple.isOSBinFormatMachO())
- return new DarwinX86AsmBackend(T, MRI, STI);
+ return new DarwinX86AsmBackend(CLOpts, T, MRI, STI);
if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
- return new WindowsX86AsmBackend(T, true, STI);
+ return new WindowsX86AsmBackend(CLOpts, T, true, STI);
if (TheTriple.isUEFI()) {
assert(TheTriple.isOSBinFormatCOFF() &&
"Only COFF format is supported in UEFI environment.");
- return new WindowsX86AsmBackend(T, true, STI);
+ return new WindowsX86AsmBackend(CLOpts, T, true, STI);
}
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
if (TheTriple.isX32())
- return new ELFX86_X32AsmBackend(T, OSABI, STI);
- return new ELFX86_64AsmBackend(T, OSABI, STI);
+ return new ELFX86_X32AsmBackend(CLOpts, T, OSABI, STI);
+ return new ELFX86_64AsmBackend(CLOpts, T, OSABI, STI);
}
namespace {
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
index af96b318270069..4ea19bac46dc04 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
@@ -50,6 +50,10 @@ constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
};
constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
+static const X86MCOptions &getCLOpts(const MCTargetOptions &Options) {
+ return cl::LibraryOptionsContext::get<X86MCOptions>(Options.LibraryOptions);
+}
+
void X86MCAsmInfoDarwin::anchor() { }
X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T,
@@ -59,7 +63,7 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T,
if (is64Bit)
CodePointerSize = CalleeSaveStackSlotSize = 8;
- AssemblerDialect = X86MCOptions::Global.asm_syntax;
+ AssemblerDialect = getCLOpts(Options).asm_syntax;
if (!is64Bit)
Data64bitsDirective = nullptr; // we can't emit a 64-bit unit
@@ -72,7 +76,7 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T,
CommentString = "##";
SupportsDebugInformation = true;
- UseDataRegionDirectives = X86MCOptions::Global.mark_data_regions;
+ UseDataRegionDirectives = getCLOpts(Options).mark_data_regions;
// Exceptions handling
ExceptionsType = ExceptionHandling::DwarfCFI;
@@ -111,7 +115,7 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T,
// OTOH, stack slot size is always 8 for x86-64, even with the x32 ABI.
CalleeSaveStackSlotSize = is64Bit ? 8 : 4;
- AssemblerDialect = X86MCOptions::Global.asm_syntax;
+ AssemblerDialect = getCLOpts(Options).asm_syntax;
// Debug Information
SupportsDebugInformation = true;
@@ -150,7 +154,7 @@ X86MCAsmInfoMicrosoft::X86MCAsmInfoMicrosoft(const Triple &Triple,
ExceptionsType = ExceptionHandling::WinEH;
- AssemblerDialect = X86MCOptions::Global.asm_syntax;
+ AssemblerDialect = getCLOpts(Options).asm_syntax;
AllowAtInName = true;
@@ -187,7 +191,7 @@ X86MCAsmInfoGNUCOFF::X86MCAsmInfoGNUCOFF(const Triple &Triple,
ExceptionsType = ExceptionHandling::DwarfCFI;
}
- AssemblerDialect = X86MCOptions::Global.asm_syntax;
+ AssemblerDialect = getCLOpts(Options).asm_syntax;
AllowAtInName = true;
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index c7b836610a1167..ad498dd498d0c2 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -184,8 +184,9 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
: CodeGenTargetMachineImpl(T, TT, CPU, FS, Options,
getEffectiveRelocModel(TT, JIT, RM),
getEffectiveX86CodeModel(TT, CM, JIT), OL),
- CLOpts(X86Options::Global), TLOF(createTLOF(getTargetTriple())),
- IsJIT(JIT) {
+ CLOpts(cl::LibraryOptionsContext::get<X86Options>(
+ Options.MCOptions.LibraryOptions)),
+ TLOF(createTLOF(getTargetTriple())), IsJIT(JIT) {
// On PS4/PS5, the "return address" of a 'noreturn' call must still be within
// the calling function. Note that this also includes __stack_chk_fail,
// so there was some target-specific logic in the instruction selectors
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCLOptions.td b/llvm/lib/Transforms/InstCombine/InstCombineCLOptions.td
index 868852632fe158..290977ac2f2628 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCLOptions.td
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCLOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def InstCombineCLOptions : OptionsStruct<prefix = "instcombine-", perContext = true>;
+def InstCombineCLOptions : OptionsStruct<prefix = "instcombine-">;
defm : BoolField<"instcombine-code-sinking", "true",
"Enable code sinking">;
diff --git a/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td b/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td
index 44a2c46ed3ec43..a430c79f325758 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td
+++ b/llvm/lib/Transforms/Instrumentation/InstrumentationOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def InstrumentationOptions : OptionsStruct;
+def InstrumentationOptions : OptionsStruct<perContext = false>;
// AddressSanitizer.cpp
defm : BoolField<"asan-always-slow-path", "false",
diff --git a/llvm/lib/Transforms/Scalar/ScalarOptions.td b/llvm/lib/Transforms/Scalar/ScalarOptions.td
index 0f7cba53e38509..8ca44f7009eaff 100644
--- a/llvm/lib/Transforms/Scalar/ScalarOptions.td
+++ b/llvm/lib/Transforms/Scalar/ScalarOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def ScalarOptions : OptionsStruct;
+def ScalarOptions : OptionsStruct<perContext = false>;
// ADCE.cpp
// This is a temporary option until we change the interface to this pass based
diff --git a/llvm/lib/Transforms/Vectorize/VectorizeOptions.td b/llvm/lib/Transforms/Vectorize/VectorizeOptions.td
index 9a43436ee057a3..e3bb555306f387 100644
--- a/llvm/lib/Transforms/Vectorize/VectorizeOptions.td
+++ b/llvm/lib/Transforms/Vectorize/VectorizeOptions.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def VectorizeOptions : OptionsStruct<perContext = true>;
+def VectorizeOptions : OptionsStruct;
// LoopIdiomVectorize.cpp
defm : BoolField<"disable-loop-idiom-vectorize-all", "false",
diff --git a/llvm/tools/llc/lib/llcdriver.cpp b/llvm/tools/llc/lib/llcdriver.cpp
index 241c5148bd4ab6..fa27cda8b515e8 100644
--- a/llvm/tools/llc/lib/llcdriver.cpp
+++ b/llvm/tools/llc/lib/llcdriver.cpp
@@ -571,6 +571,7 @@ static int compileModule(char **argv, SmallVectorImpl<PassPlugin> &PluginList,
Options.MCOptions.IASSearchPaths = IncludeDirs;
Options.MCOptions.InstPrinterOptions = InstPrinterOptions;
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
+ Options.MCOptions.LibraryOptions = &Context.getLibraryOptions();
if (DwarfDirectory.getPosition()) {
Options.MCOptions.MCUseDwarfDirectory =
DwarfDirectory ? MCTargetOptions::EnableDwarfDirectory
diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp
index da87ef049c7d4e..28b01bfc6c95c0 100644
--- a/llvm/tools/opt/optdriver.cpp
+++ b/llvm/tools/opt/optdriver.cpp
@@ -698,8 +698,8 @@ optMain(int argc, char **argv,
TuneCPUStr = codegen::getTuneCPUStr();
FeaturesStr = codegen::getFeaturesStr();
Expected<std::unique_ptr<TargetMachine>> ExpectedTM =
- codegen::createTargetMachineForTriple(ModuleTriple,
- GetCodeGenOptLevel());
+ codegen::createTargetMachineForTriple(
+ ModuleTriple, GetCodeGenOptLevel(), &Context.getLibraryOptions());
if (auto E = ExpectedTM.takeError()) {
errs() << argv[0] << ": WARNING: failed to create target machine for '"
<< ModuleTriple.str() << "': " << toString(std::move(E)) << "\n";
diff --git a/llvm/unittests/Option/LibraryOpts.td b/llvm/unittests/Option/LibraryOpts.td
index 6e4d48bc8d37ac..ce51590056bc57 100644
--- a/llvm/unittests/Option/LibraryOpts.td
+++ b/llvm/unittests/Option/LibraryOpts.td
@@ -8,7 +8,7 @@
include "llvm/Option/LibraryOptions.td"
-def TestLibraryOptions : OptionsStruct<"test", prefix = "lib-">;
+def TestLibraryOptions : OptionsStruct<"test", prefix = "lib-", perContext = false>;
defm : BoolField<"lib-enable", "false", "A bool">;
def InBuild : BuildCondition<"__cplusplus">;
>From 4143e457bcd76f7460988ad6dfe6de41c86cbe3e Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 14 Oct 2026 20:44:28 -0700
Subject: [PATCH 2/3] simplify
---
.../lib/Target/X86/AsmParser/X86AsmParser.cpp | 3 +--
.../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 22 +++++--------------
.../Target/X86/MCTargetDesc/X86MCAsmInfo.cpp | 14 +++++-------
.../Target/X86/MCTargetDesc/X86MCOptions.h | 7 ++++++
llvm/tools/llc/lib/llcdriver.cpp | 1 -
5 files changed, 19 insertions(+), 28 deletions(-)
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 47ce4689c622e0..7038fe6ef229f6 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1402,8 +1402,7 @@ class X86AsmParser : public MCTargetAsmParser {
X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
const MCInstrInfo &mii)
: MCTargetAsmParser(sti, mii),
- CLOpts(cl::LibraryOptionsContext::get<X86MCOptions>(
- Parser.getContext().getTargetOptions().LibraryOptions)),
+ CLOpts(X86_MC::getCLOpts(Parser.getContext().getTargetOptions())),
InstInfo(nullptr), Code16GCC(false) {
Parser.addAliasForDirective(".word", ".2byte");
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 2aa611d6d6f192..2904221ee71136 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -1196,9 +1196,7 @@ class ELFX86AsmBackend : public X86AsmBackend {
class ELFX86_32AsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_32AsmBackend(const X86MCOptions &CLOpts, const Target &T,
- uint8_t OSABI, const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
+ using ELFX86AsmBackend::ELFX86AsmBackend;
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1208,9 +1206,7 @@ class ELFX86_32AsmBackend : public ELFX86AsmBackend {
class ELFX86_X32AsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_X32AsmBackend(const X86MCOptions &CLOpts, const Target &T,
- uint8_t OSABI, const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
+ using ELFX86AsmBackend::ELFX86AsmBackend;
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1221,9 +1217,7 @@ class ELFX86_X32AsmBackend : public ELFX86AsmBackend {
class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_IAMCUAsmBackend(const X86MCOptions &CLOpts, const Target &T,
- uint8_t OSABI, const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
+ using ELFX86AsmBackend::ELFX86AsmBackend;
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1234,9 +1228,7 @@ class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend {
class ELFX86_64AsmBackend : public ELFX86AsmBackend {
public:
- ELFX86_64AsmBackend(const X86MCOptions &CLOpts, const Target &T,
- uint8_t OSABI, const MCSubtargetInfo &STI)
- : ELFX86AsmBackend(CLOpts, T, OSABI, STI) {}
+ using ELFX86AsmBackend::ELFX86AsmBackend;
std::unique_ptr<MCObjectTargetWriter>
createObjectTargetWriter() const override {
@@ -1634,8 +1626,7 @@ MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
const Triple &TheTriple = STI.getTargetTriple();
- const X86MCOptions &CLOpts =
- cl::LibraryOptionsContext::get<X86MCOptions>(Options.LibraryOptions);
+ const X86MCOptions &CLOpts = X86_MC::getCLOpts(Options);
if (TheTriple.isOSBinFormatMachO())
return new DarwinX86AsmBackend(CLOpts, T, MRI, STI);
@@ -1655,8 +1646,7 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
const Triple &TheTriple = STI.getTargetTriple();
- const X86MCOptions &CLOpts =
- cl::LibraryOptionsContext::get<X86MCOptions>(Options.LibraryOptions);
+ const X86MCOptions &CLOpts = X86_MC::getCLOpts(Options);
if (TheTriple.isOSBinFormatMachO())
return new DarwinX86AsmBackend(CLOpts, T, MRI, STI);
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
index 4ea19bac46dc04..ace32354153178 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
@@ -50,10 +50,6 @@ constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
};
constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
-static const X86MCOptions &getCLOpts(const MCTargetOptions &Options) {
- return cl::LibraryOptionsContext::get<X86MCOptions>(Options.LibraryOptions);
-}
-
void X86MCAsmInfoDarwin::anchor() { }
X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T,
@@ -63,7 +59,7 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T,
if (is64Bit)
CodePointerSize = CalleeSaveStackSlotSize = 8;
- AssemblerDialect = getCLOpts(Options).asm_syntax;
+ AssemblerDialect = X86_MC::getCLOpts(Options).asm_syntax;
if (!is64Bit)
Data64bitsDirective = nullptr; // we can't emit a 64-bit unit
@@ -76,7 +72,7 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T,
CommentString = "##";
SupportsDebugInformation = true;
- UseDataRegionDirectives = getCLOpts(Options).mark_data_regions;
+ UseDataRegionDirectives = X86_MC::getCLOpts(Options).mark_data_regions;
// Exceptions handling
ExceptionsType = ExceptionHandling::DwarfCFI;
@@ -115,7 +111,7 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T,
// OTOH, stack slot size is always 8 for x86-64, even with the x32 ABI.
CalleeSaveStackSlotSize = is64Bit ? 8 : 4;
- AssemblerDialect = getCLOpts(Options).asm_syntax;
+ AssemblerDialect = X86_MC::getCLOpts(Options).asm_syntax;
// Debug Information
SupportsDebugInformation = true;
@@ -154,7 +150,7 @@ X86MCAsmInfoMicrosoft::X86MCAsmInfoMicrosoft(const Triple &Triple,
ExceptionsType = ExceptionHandling::WinEH;
- AssemblerDialect = getCLOpts(Options).asm_syntax;
+ AssemblerDialect = X86_MC::getCLOpts(Options).asm_syntax;
AllowAtInName = true;
@@ -191,7 +187,7 @@ X86MCAsmInfoGNUCOFF::X86MCAsmInfoGNUCOFF(const Triple &Triple,
ExceptionsType = ExceptionHandling::DwarfCFI;
}
- AssemblerDialect = getCLOpts(Options).asm_syntax;
+ AssemblerDialect = X86_MC::getCLOpts(Options).asm_syntax;
AllowAtInName = true;
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCOptions.h b/llvm/lib/Target/X86/MCTargetDesc/X86MCOptions.h
index 4b6583f73ca374..676a06cd0e586a 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCOptions.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCOptions.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIB_TARGET_X86_MCTARGETDESC_X86MCOPTIONS_H
#define LLVM_LIB_TARGET_X86_MCTARGETDESC_X86MCOPTIONS_H
+#include "llvm/MC/MCTargetOptions.h"
#include <optional>
namespace llvm::X86 {
@@ -20,4 +21,10 @@ enum AsmWriterFlavorTy { ATT = 0, Intel = 1 };
#define OPTIONS_STRUCT_DECL
#include "X86MCOptions.inc"
+namespace llvm::X86_MC {
+inline const X86MCOptions &getCLOpts(const MCTargetOptions &Options) {
+ return cl::LibraryOptionsContext::get<X86MCOptions>(Options.LibraryOptions);
+}
+} // namespace llvm::X86_MC
+
#endif // LLVM_LIB_TARGET_X86_MCTARGETDESC_X86MCOPTIONS_H
diff --git a/llvm/tools/llc/lib/llcdriver.cpp b/llvm/tools/llc/lib/llcdriver.cpp
index fa27cda8b515e8..241c5148bd4ab6 100644
--- a/llvm/tools/llc/lib/llcdriver.cpp
+++ b/llvm/tools/llc/lib/llcdriver.cpp
@@ -571,7 +571,6 @@ static int compileModule(char **argv, SmallVectorImpl<PassPlugin> &PluginList,
Options.MCOptions.IASSearchPaths = IncludeDirs;
Options.MCOptions.InstPrinterOptions = InstPrinterOptions;
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
- Options.MCOptions.LibraryOptions = &Context.getLibraryOptions();
if (DwarfDirectory.getPosition()) {
Options.MCOptions.MCUseDwarfDirectory =
DwarfDirectory ? MCTargetOptions::EnableDwarfDirectory
>From 84d618a6f887640ebc71417c0c240a0ec84ee765 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 14 Oct 2026 20:59:12 -0700
Subject: [PATCH 3/3] add clang -fthinlto-index= and ld.lld -mllvm tests to
ensure integrated and distributed LTO modes accept -mllvm
---
clang/test/CodeGen/thinlto-loop-vectorize-pm.c | 6 ++++++
lld/test/ELF/lto/mllvm.ll | 6 ++++++
llvm/lib/LTO/LTOBackend.cpp | 1 +
3 files changed, 13 insertions(+)
diff --git a/clang/test/CodeGen/thinlto-loop-vectorize-pm.c b/clang/test/CodeGen/thinlto-loop-vectorize-pm.c
index 18fcf7595cd20c..9e56093f893f29 100644
--- a/clang/test/CodeGen/thinlto-loop-vectorize-pm.c
+++ b/clang/test/CodeGen/thinlto-loop-vectorize-pm.c
@@ -31,6 +31,12 @@
// O2-NoInterLeave: = !{!"llvm.loop.isvectorized", i32 1}
// O0-InterLeave-NOT: = !{!"llvm.loop.isvectorized", i32 1}
+// Test that -mllvm options of per-context libraries reach the ThinLTO backend's
+// TargetMachine.
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -mllvm -x86-asm-syntax=intel -S -o - -x ir %t.o -fthinlto-index=%t.thinlto.bc 2>&1 | FileCheck %s --check-prefix=INTEL
+// INTEL: .intel_syntax
+
void foo(double *a) {
for (int i = 0; i < 1000; i++)
a[i] = 10;
diff --git a/lld/test/ELF/lto/mllvm.ll b/lld/test/ELF/lto/mllvm.ll
index d09dcd0bf7b95d..69489ee4e5153b 100644
--- a/lld/test/ELF/lto/mllvm.ll
+++ b/lld/test/ELF/lto/mllvm.ll
@@ -7,11 +7,17 @@
;; most -plugin-opt=- prefixed options are passed through to cl::ParseCommandLineOptions.
; RUN: ld.lld %t.o -o %t -plugin-opt=-debug-pass=Structure -plugin-opt=-print-after-all 2>&1 | FileCheck %s
+;; -mllvm reaches per-context library options.
+; RUN: ld.lld %t.o -o %t2 --lto-emit-asm -mllvm -x86-asm-syntax=intel
+; RUN: FileCheck %s --check-prefix=INTEL < %t2.lto.s
+
; CHECK: Pass Arguments:
; CHECK: # *** IR Dump
; DISASM: nopw
+; INTEL: .intel_syntax
+
target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 13b5e6e93335dc..9e906e00342ac2 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -243,6 +243,7 @@ createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
if (TargetOpts.MCOptions.ABIName.empty()) {
TargetOpts.MCOptions.ABIName = M.getTargetABIFromMD();
}
+ TargetOpts.MCOptions.LibraryOptions = &M.getContext().getLibraryOptions();
std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine(
TheTriple, Conf.CPU, Features.getString(), TargetOpts, RelocModel,
More information about the cfe-commits
mailing list