[llvm] TargetMachine: Verify option/module-flag consistency once per module (PR #217597)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 06:19:10 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/217597
>From 140fe2010da0dcff41c4592e2f8198ba9fba06d4 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 20 Aug 2026 13:15:32 +0200
Subject: [PATCH] TargetMachine: Verify option/module-flag consistency once per
module
The -target-abi option / "target-abi" module flag conflict was reported from
the per-function getSubtargetImpl in RISCV and LoongArch, so a module with
multiple subtargets would repeatedly diagnose. Introduce a new TargetMachine
method to validate the module for the global options.
I wasn't sure the best place to actually perform this check. This is now
performing it in the earliest pass in codegen, MachineModuleInfo.
MachineModuleInfo is a glorified map from IR to MachineFunction, so I'm not
sure this is the right place. The other alternative I started with was the
AsmPrinter initialization.
Ideally we would eliminate the global options. In particular target-abi is
going to be a bit sticky, because it lives in MCOptions and is thus used by
non-codegen contexts which won't have an IR module to read a flag from.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
llvm/include/llvm/Target/TargetMachine.h | 11 ++++++---
llvm/lib/CodeGen/MachineModuleInfo.cpp | 2 ++
llvm/lib/Target/TargetMachine.cpp | 24 +++++++++++--------
.../RISCV/module-target-abi-conflict.ll | 24 +++++++++++++++++++
4 files changed, 48 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/module-target-abi-conflict.ll
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index d6067613cf324..a6b73d636dc27 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -138,11 +138,16 @@ class LLVM_ABI TargetMachine {
StringRef getTargetFeatureString() const { return TargetFS; }
void setTargetFeatureString(StringRef FS) { TargetFS = std::string(FS); }
- /// Returns the effective target ABI name. Reads the "target-abi" module flag
- /// if present, otherwise the -target-abi option. Emits an error if both are
- /// present and disagree.
+ /// Returns the effective target ABI name: the "target-abi" module flag if
+ /// present, otherwise the -target-abi option. This is a pure query; call
+ /// verifyOptionsConsistency once per module to diagnose a conflict.
StringRef getTargetABIName(const Module &M) const;
+ /// Diagnoses command-line codegen options that conflict with the
+ /// corresponding module flags (e.g. -target-abi vs the "target-abi" module
+ /// flag). Intended to be called once per module.
+ void verifyOptionsConsistency(const Module &M) const;
+
/// Virtual method implemented by subclasses that returns a reference to that
/// target's TargetSubtargetInfo-derived member variable.
virtual const TargetSubtargetInfo *getSubtargetImpl(const Function &) const {
diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp
index e421378bd5b17..dd9defdec276b 100644
--- a/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -218,6 +218,7 @@ bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
Ctx.diagnose(
DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
});
+ MMI.getTarget().verifyOptionsConsistency(M);
return false;
}
@@ -242,5 +243,6 @@ MachineModuleAnalysis::run(Module &M, ModuleAnalysisManager &) {
Ctx.diagnose(
DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
});
+ MMI.getTarget().verifyOptionsConsistency(M);
return Result(MMI);
}
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index c26661f365d7b..676c44495e798 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -331,18 +331,22 @@ std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
}
StringRef TargetMachine::getTargetABIName(const Module &M) const {
+ if (const auto *MD = cast_or_null<MDString>(M.getModuleFlag("target-abi")))
+ return MD->getString();
+ return Options.MCOptions.getABIName();
+}
+
+void TargetMachine::verifyOptionsConsistency(const Module &M) const {
+ // The "target-abi" module flag must agree with the -target-abi option.
StringRef OptionABI = Options.MCOptions.getABIName();
- const auto *MD = cast_or_null<MDString>(M.getModuleFlag("target-abi"));
- if (!MD)
- return OptionABI;
-
- StringRef ModuleABI = MD->getString();
- if (!OptionABI.empty() && OptionABI != ModuleABI) {
- M.getContext().emitError("-target-abi option != target-abi module flag");
- return "";
+ if (!OptionABI.empty()) {
+ if (const auto *MD =
+ cast_or_null<MDString>(M.getModuleFlag("target-abi"))) {
+ if (OptionABI != MD->getString())
+ M.getContext().emitError(
+ "-target-abi option != target-abi module flag");
+ }
}
-
- return ModuleABI;
}
const MCSubtargetInfo &TargetMachine::getMCSubtargetInfo(StringRef CPU,
diff --git a/llvm/test/CodeGen/RISCV/module-target-abi-conflict.ll b/llvm/test/CodeGen/RISCV/module-target-abi-conflict.ll
new file mode 100644
index 0000000000000..36ed06e895ca3
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/module-target-abi-conflict.ll
@@ -0,0 +1,24 @@
+; A "target-abi" module flag that conflicts with the -target-abi
+; command-line option is an error, which should be diagnosed exactly
+; once
+
+; RUN: not llc -target-abi=lp64d -filetype=null < %s 2>&1 | FileCheck %s -implicit-check-not=error:
+; RUN: not llc -enable-new-pm -target-abi=lp64d -filetype=null < %s 2>&1 | FileCheck %s -implicit-check-not=error:
+
+; CHECK: error: -target-abi option != target-abi module flag
+
+target triple = "riscv64"
+
+define void @f1() #0 {
+ ret void
+}
+
+define void @f2() #1 {
+ ret void
+}
+
+attributes #0 = { "target-cpu"="generic-rv64" }
+attributes #1 = { "target-cpu"="rocket-rv64" }
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"lp64"}
More information about the llvm-commits
mailing list