[llvm] CodeGen: Consolidate target-abi validation (PR #217426)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 19 11:34:07 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/217426

LoongArch and RISCV both implemented an error if the
"target-abi" module flag was inconsistent with the -target-abi
option flag. Consolidate these into one place, and change
from a fatal error to a nonfatal context error.

One untested incidental behavior change is for garbage names.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>

>From 9f9de1f919697fc8ef235c4eb4e62b65db796446 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 19 Aug 2026 20:07:46 +0200
Subject: [PATCH] CodeGen: Consolidate target-abi validation

LoongArch and RISCV both implemented an error if the
"target-abi" module flag was inconsistent with the -target-abi
option flag. Consolidate these into one place, and change
from a fatal error to a nonfatal context error.

One untested incidental behavior change is for garbage names.

Co-authored-by: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
 llvm/include/llvm/Target/TargetMachine.h          |  5 +++++
 .../Target/LoongArch/LoongArchTargetMachine.cpp   | 11 +----------
 llvm/lib/Target/RISCV/RISCVTargetMachine.cpp      | 11 +----------
 llvm/lib/Target/TargetMachine.cpp                 | 15 +++++++++++++++
 llvm/test/CodeGen/RISCV/module-target-abi.ll      |  4 ++--
 llvm/test/CodeGen/RISCV/module-target-abi2.ll     |  4 ++--
 6 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index d8f497358f89c..d6067613cf324 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -138,6 +138,11 @@ 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.
+  StringRef getTargetABIName(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/Target/LoongArch/LoongArchTargetMachine.cpp b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
index fb0053b7077e4..0bb73a88bd6fd 100644
--- a/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchTargetMachine.cpp
@@ -121,16 +121,7 @@ LoongArchTargetMachine::getSubtargetImpl(const Function &F) const {
   std::string Key = CPU + TuneCPU + FS;
   auto &I = SubtargetMap[Key];
   if (!I) {
-    auto ABIName = Options.MCOptions.getABIName();
-    if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
-            F.getParent()->getModuleFlag("target-abi"))) {
-      auto TargetABI = LoongArchABI::getTargetABI(ABIName);
-      if (TargetABI != LoongArchABI::ABI_Unknown &&
-          ModuleTargetABI->getString() != ABIName) {
-        report_fatal_error("-target-abi option != target-abi module flag");
-      }
-      ABIName = ModuleTargetABI->getString();
-    }
+    StringRef ABIName = getTargetABIName(*F.getParent());
     I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
                                              ABIName, *this);
   }
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 37101c790ed4e..42dac72083677 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -252,16 +252,7 @@ RISCVTargetMachine::getSubtargetImpl(const Function &F) const {
                            << CPU << TuneCPU << FS;
   auto &I = SubtargetMap[Key];
   if (!I) {
-    auto ABIName = Options.MCOptions.getABIName();
-    if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
-            F.getParent()->getModuleFlag("target-abi"))) {
-      auto TargetABI = RISCVABI::getTargetABI(ABIName);
-      if (TargetABI != RISCVABI::ABI_Unknown &&
-          ModuleTargetABI->getString() != ABIName) {
-        report_fatal_error("-target-abi option != target-abi module flag");
-      }
-      ABIName = ModuleTargetABI->getString();
-    }
+    StringRef ABIName = getTargetABIName(*F.getParent());
     I = std::make_unique<RISCVSubtarget>(
         TargetTriple, CPU, TuneCPU, FS, ABIName, RVVBitsMin, RVVBitsMax, *this);
   }
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index 46c02df9e2620..4e9a90a328646 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -330,6 +330,21 @@ std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
   return Ret;
 }
 
+StringRef TargetMachine::getTargetABIName(const Module &M) const {
+  StringRef OptionABI = Options.MCOptions.getABIName();
+  const auto *MD = dyn_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 "";
+  }
+
+  return ModuleABI;
+}
+
 const MCSubtargetInfo &TargetMachine::getMCSubtargetInfo(StringRef CPU,
                                                          StringRef FS) {
   if (CPU.empty() && FS.empty())
diff --git a/llvm/test/CodeGen/RISCV/module-target-abi.ll b/llvm/test/CodeGen/RISCV/module-target-abi.ll
index 0e3f62046eb80..854d63b43a946 100644
--- a/llvm/test/CodeGen/RISCV/module-target-abi.ll
+++ b/llvm/test/CodeGen/RISCV/module-target-abi.ll
@@ -2,11 +2,11 @@
 ; RUN:   | FileCheck -check-prefix=DEFAULT %s
 ; RUN: llc -mtriple=riscv32 -target-abi ilp32 < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV32IF-ILP32 %s
-; RUN: not --crash llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \
+; RUN: not llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV32IF-ILP32F %s
 ; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s
 
-; RV32IF-ILP32F: -target-abi option != target-abi module flag
+; RV32IF-ILP32F: error: -target-abi option != target-abi module flag
 
 ; FLAGS: Flags: 0x0
 
diff --git a/llvm/test/CodeGen/RISCV/module-target-abi2.ll b/llvm/test/CodeGen/RISCV/module-target-abi2.ll
index f5fc69c2d28a2..e9eeb7f79f1d0 100644
--- a/llvm/test/CodeGen/RISCV/module-target-abi2.ll
+++ b/llvm/test/CodeGen/RISCV/module-target-abi2.ll
@@ -1,12 +1,12 @@
 ; RUN: llc -mtriple=riscv32 < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=DEFAULT %s
-; RUN: not --crash llc -mtriple=riscv32 -target-abi ilp32 < %s 2>&1 \
+; RUN: not llc -mtriple=riscv32 -target-abi ilp32 < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV32IF-ILP32 %s
 ; RUN: llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV32IF-ILP32F %s
 ; RUN: llc -mtriple=riscv32 -filetype=obj < %s | llvm-readelf -h - | FileCheck -check-prefixes=FLAGS %s
 
-; RV32IF-ILP32: -target-abi option != target-abi module flag
+; RV32IF-ILP32: error: -target-abi option != target-abi module flag
 
 ; FLAGS: Flags: 0x2, single-float ABI
 



More information about the llvm-commits mailing list