[llvm] IR: Validate and document the "target-abi" module flag (PR #217397)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 19 11:44:38 PDT 2026
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/217397
>From bb9bd5669b9039ce968aa17787c1af48536a0d78 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 18 Aug 2026 20:06:30 +0200
Subject: [PATCH] IR: Validate and document the "target-abi" module flag
The "target-abi" module flag is already emitted by clang for RISC-V and
consumed by the RISC-V and LoongArch backends, but it was neither validated
by the IR Verifier nor documented in LangRef. Add a Verifier check that the
flag's value operand is a non-empty string.
Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
llvm/docs/LangRef.md | 18 +++++++++++++
llvm/lib/IR/Verifier.cpp | 6 +++++
.../test/Assembler/module-flags-target-abi.ll | 13 ++++++++++
llvm/test/Verifier/module-flags-target-abi.ll | 25 +++++++++++++++++++
4 files changed, 62 insertions(+)
create mode 100644 llvm/test/Assembler/module-flags-target-abi.ll
create mode 100644 llvm/test/Verifier/module-flags-target-abi.ll
diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index 4853b3466467c..600b0d39a5929 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -9442,6 +9442,24 @@ conflicting floating-point ABIs is rejected. For example:
!0 = !{i32 1, !"float-abi", !"hard"}
```
+### Target ABI Module Flags Metadata
+
+This module flag names the target ABI that the module was compiled
+for. The value is an `MDString`. The set of valid values and
+interpretation target-specific.
+
+For example, RISC-V uses names such as `"ilp32"`, `"ilp32d"`, `"lp64"`, and
+`"lp64d"`:
+```
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"lp64d"}
+```
+while ARM uses names such as `"aapcs"` and `"apcs-gnu"`:
+```
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"aapcs"}
+```
+
### Long Double Type Module Flags Metadata
Describe the floating-point format used by libm for `long double`. The
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 4e804425b751d..6d6723a8cedf1 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2023,6 +2023,12 @@ Verifier::visitModuleFlag(const MDNode *Op,
"invalid float-abi metadata value", Op);
}
+ if (ID->getString() == "target-abi") {
+ const MDString *Value = dyn_cast_or_null<MDString>(Op->getOperand(2));
+ Check(Value && !Value->getString().empty(),
+ "target-abi metadata requires a non-empty string argument", Op);
+ }
+
if (ID->getString() == "Linker Options") {
// If the llvm.linker.options named metadata exists, we assume that the
// bitcode reader has upgraded the module flag. Otherwise the flag might
diff --git a/llvm/test/Assembler/module-flags-target-abi.ll b/llvm/test/Assembler/module-flags-target-abi.ll
new file mode 100644
index 0000000000000..e043d3fc64b7f
--- /dev/null
+++ b/llvm/test/Assembler/module-flags-target-abi.ll
@@ -0,0 +1,13 @@
+; RUN: split-file %s %t
+; RUN: llvm-as < %t/aapcs.ll | llvm-dis | FileCheck %s --check-prefix=AAPCS
+; RUN: llvm-as < %t/lp64d.ll | llvm-dis | FileCheck %s --check-prefix=LP64D
+
+;--- aapcs.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"aapcs"}
+; AAPCS: !0 = !{i32 1, !"target-abi", !"aapcs"}
+
+;--- lp64d.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"lp64d"}
+; LP64D: !0 = !{i32 1, !"target-abi", !"lp64d"}
diff --git a/llvm/test/Verifier/module-flags-target-abi.ll b/llvm/test/Verifier/module-flags-target-abi.ll
new file mode 100644
index 0000000000000..0a7419190b476
--- /dev/null
+++ b/llvm/test/Verifier/module-flags-target-abi.ll
@@ -0,0 +1,25 @@
+; RUN: split-file %s %t
+; RUN: not llvm-as < %t/not-string.ll -disable-output 2>&1 | FileCheck %s --check-prefix=NOTSTRING
+; RUN: not llvm-as < %t/empty-string.ll -disable-output 2>&1 | FileCheck %s --check-prefix=EMPTY
+; RUN: not llvm-as < %t/too-few.ll -disable-output 2>&1 | FileCheck %s --check-prefix=TOOFEW
+; RUN: not llvm-as < %t/too-many.ll -disable-output 2>&1 | FileCheck %s --check-prefix=TOOMANY
+
+;--- not-string.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", i32 1}
+; NOTSTRING: target-abi metadata requires a non-empty string argument
+
+;--- empty-string.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !""}
+; EMPTY: target-abi metadata requires a non-empty string argument
+
+;--- too-few.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi"}
+; TOOFEW: incorrect number of operands in module flag
+
+;--- too-many.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"aapcs", !"extra"}
+; TOOMANY: incorrect number of operands in module flag
More information about the llvm-commits
mailing list