[llvm] 674fd8d - RISCV: Don't use MCTargetOptions::ABIName in the ELF target streamer (#224704)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 14:02:15 PDT 2026


Author: Matt Arsenault
Date: 2026-09-23T23:02:06+02:00
New Revision: 674fd8d37e9b5806bc1a7ff31dc56bf3a0839c6b

URL: https://github.com/llvm/llvm-project/commit/674fd8d37e9b5806bc1a7ff31dc56bf3a0839c6b
DIFF: https://github.com/llvm/llvm-project/commit/674fd8d37e9b5806bc1a7ff31dc56bf3a0839c6b.diff

LOG: RISCV: Don't use MCTargetOptions::ABIName in the ELF target streamer (#224704)

The abi name should come from the target-abi module flag in codegen,
which should be set up in the AsmPrinter. The ABI name field should
only be of practical use in the assembler, which reads the flag in
onBeginOfFile.

Co-Authored-By: Claude <noreply at anthropic.com> (Claude Opus 4.8)

Added: 
    llvm/test/CodeGen/RISCV/target-abi-synthesize-flag.ll

Modified: 
    llvm/lib/CodeGen/CommandFlags.cpp
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
    llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
    llvm/test/CodeGen/RISCV/target-abi-invalid.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 4ab005f11e0e0..1bebecda62166 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -747,6 +747,16 @@ void codegen::setFunctionAttributes(Module &M, StringRef CPU,
     }
   }
 
+  // Synthesize the "target-abi" module flag from the -target-abi option.
+  //
+  // FIXME: verifyOptionsConsistency validates consistency for target-abi. We
+  // should consistently handle all ABI module flags either here or there.
+  StringRef ABIName = mc::getABIName();
+  if (!ABIName.empty() && !M.getModuleFlag("target-abi")) {
+    M.addModuleFlag(Module::Error, "target-abi",
+                    MDString::get(M.getContext(), ABIName));
+  }
+
   for (Function &F : M)
     setFunctionAttributes(F, CPU, Features, TuneCPU);
 }

diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index e9e8ffe6171f3..478a2c785819b 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -344,7 +344,6 @@ class RISCVAsmParser : public MCTargetAsmParser {
   // location instead of being printed with no location information.
   void onBeginOfFile() override {
     // If the target streamer already has a resolved ABI (e.g. set by
-    // RISCVTargetELFStreamer for a valid -target-abi, or set by
     // RISCVAsmPrinter during codegen), skip ABI validation.
     if (getTargetStreamer().hasTargetABI())
       return;

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 1fb45627a1d03..524d0bb79d5f8 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -11,7 +11,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "RISCVELFStreamer.h"
-#include "RISCVAsmBackend.h"
 #include "RISCVBaseInfo.h"
 #include "RISCVMCTargetDesc.h"
 #include "llvm/BinaryFormat/ELF.h"
@@ -28,23 +27,6 @@ using namespace llvm;
 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
                                                const MCSubtargetInfo &STI)
     : RISCVTargetStreamer(S), CurrentVendor("riscv") {
-  MCAssembler &MCA = getStreamer().getAssembler();
-  auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
-  StringRef ABIName = MAB.getTargetOptions().getABIName();
-  // We have to recompute the ABI rather than casting STI to RISCVSubtarget
-  // since MC tools like llvm-mc call this when STI is MCSubtargetInfo instead.
-  // Using RISCVSubtarget requires a TargetMachine, which the MC-only tools
-  // deliberately don't link.
-  // TODO: Might be cleaner to have callers set the ABI instead of computing
-  // it twice which introduces a chance of it being out of sync.
-  if (auto ABIOrErr = RISCVABI::computeTargetABI(STI, ABIName)) {
-    setTargetABI(*ABIOrErr);
-  } else {
-    // Do not set TargetABI here if invalid: RISCVSubtarget/RISCVAsmPrinter
-    // (in codegen) or RISCVAsmParser::onBeginOfFile() (in llvm-mc) will
-    // resolve or diagnose it with proper contexts.
-    consumeError(ABIOrErr.takeError());
-  }
   setFlagsFromFeatures(STI);
 
   // Compute the initial ISA string.  This serves two purposes:
@@ -157,7 +139,7 @@ void RISCVTargetELFStreamer::finish() {
     EFlags |= ELF::EF_RISCV_RVE;
     break;
   case RISCVABI::ABI_Unknown:
-    llvm_unreachable("Improperly initialised target ABI");
+    break;
   }
 
   W.setELFHeaderEFlags(EFlags);

diff  --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 04da2ce2b2bfe..c2cadf361a0cd 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -646,12 +646,19 @@ void RISCVAsmPrinter::emitStartOfAsmFile(Module &M) {
   assert(OutStreamer->getTargetStreamer() &&
          "target streamer is uninitialized");
   RISCVTargetStreamer &RTS = getTargetStreamer();
-  if (const MDString *ModuleTargetABI =
-          dyn_cast_or_null<MDString>(M.getModuleFlag("target-abi")))
-    RTS.setTargetABI(RISCVABI::getTargetABI(ModuleTargetABI->getString()));
-  else if (!RTS.hasTargetABI())
+  StringRef ABIName = M.getTargetABIFromMD();
+  if (!ABIName.empty()) {
+    RISCVABI::ABI ABI = RISCVABI::getTargetABI(ABIName);
+    if (ABI == RISCVABI::ABI_Unknown) {
+      M.getContext().emitError(Twine('\'') + ABIName +
+                               "' is not a recognized ABI for this target");
+    } else {
+      RTS.setTargetABI(ABI);
+    }
+  } else if (!RTS.hasTargetABI()) {
     RTS.setTargetABI(
         cantFail(RISCVABI::computeTargetABI(TM.getMCSubtargetInfo(), "")));
+  }
 
   MCSubtargetInfo SubtargetInfo = TM.getMCSubtargetInfo();
 

diff  --git a/llvm/test/CodeGen/RISCV/target-abi-invalid.ll b/llvm/test/CodeGen/RISCV/target-abi-invalid.ll
index 72e3cba6d8d00..994136d5fd748 100644
--- a/llvm/test/CodeGen/RISCV/target-abi-invalid.ll
+++ b/llvm/test/CodeGen/RISCV/target-abi-invalid.ll
@@ -1,10 +1,10 @@
-; RUN: llc -mtriple=riscv32 -target-abi foo < %s 2>&1 \
+; RUN: not llc -mtriple=riscv32 -target-abi foo < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV32I-FOO %s
-; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32foof < %s 2>&1 \
+; RUN: not llc -mtriple=riscv32 -mattr=+f -target-abi ilp32foof < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV32IF-ILP32FOOF %s
 
-; RV32I-FOO: note: 'foo' is not a recognized ABI for this target (ignoring target-abi)
-; RV32IF-ILP32FOOF: note: 'ilp32foof' is not a recognized ABI for this target (ignoring target-abi)
+; RV32I-FOO: error: 'foo' is not a recognized ABI for this target
+; RV32IF-ILP32FOOF: error: 'ilp32foof' is not a recognized ABI for this target
 
 ; RUN: llc -mtriple=riscv64 -target-abi ilp32 < %s 2>&1 \
 ; RUN:   | FileCheck -check-prefix=RV64I-ILP32 %s

diff  --git a/llvm/test/CodeGen/RISCV/target-abi-synthesize-flag.ll b/llvm/test/CodeGen/RISCV/target-abi-synthesize-flag.ll
new file mode 100644
index 0000000000000..50abdebc89c87
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/target-abi-synthesize-flag.ll
@@ -0,0 +1,45 @@
+; Check behavior of the -target-abi command-line option; it should
+; synthesize the "target-abi" module flag, unless one is already
+; present. A conflict is diagnosed by verifyOptionsConsistency.
+
+; RUN: split-file %s %t
+
+; -target-abi synthesizes the flag and selects the ABI, overriding the
+; extension default (lp64d).
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64f -filetype=obj < %t/none.ll | llvm-readelf -h - | FileCheck %s --check-prefix=LP64F
+
+; Without -target-abi, the extension-default ABI is used.
+; RUN: llc -mtriple=riscv64 -mattr=+d -filetype=obj < %t/none.ll | llvm-readelf -h - | FileCheck %s --check-prefix=LP64D
+
+; An unrecognized ABI name in the module flag is an error
+; RUN: not llc -mtriple=riscv64 -mattr=+d -filetype=null < %t/bogus.ll 2>&1 | FileCheck %s --check-prefix=BADABI
+
+; -target-abi matching an existing in-IR flag is accepted.
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64f -filetype=obj < %t/lp64f.ll | llvm-readelf -h - | FileCheck %s --check-prefix=LP64F
+
+; -target-abi conflicting with an existing in-IR flag is an error.
+; RUN: not llc -mtriple=riscv64 -mattr=+d -target-abi lp64d -filetype=null < %t/lp64f.ll 2>&1 | FileCheck %s --check-prefix=CONFLICT
+
+; LP64F: Flags: 0x2, single-float ABI
+; LP64D: Flags: 0x4, double-float ABI
+; BADABI: error: 'bogus' is not a recognized ABI for this target
+; CONFLICT: error: -target-abi option != target-abi module flag
+
+;--- none.ll
+define void @f() {
+  ret void
+}
+
+;--- lp64f.ll
+define void @f() {
+  ret void
+}
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"lp64f"}
+
+;--- bogus.ll
+define void @f() {
+  ret void
+}
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"target-abi", !"bogus"}


        


More information about the llvm-commits mailing list