https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/213410
>From 3d7fc37b5bd2d433fca65446959f06ed65bc162e Mon Sep 17 00:00:00 2001 From: Alexander Richardson <[email protected]> Date: Fri, 31 Jul 2026 22:51:42 -0700 Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.8-beta.1-arichardson --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 26 ++-- .../RISCV/MCTargetDesc/RISCVBaseInfo.cpp | 66 +++++----- .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 5 +- .../RISCV/MCTargetDesc/RISCVELFStreamer.cpp | 12 +- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 22 ++-- llvm/lib/Target/RISCV/RISCVSubtarget.cpp | 11 +- .../RISCV/subtarget-features-std-ext.ll | 2 +- llvm/test/CodeGen/RISCV/target-abi-invalid.ll | 12 +- llvm/test/MC/RISCV/target-abi-invalid.s | 120 +++++++++--------- .../Target/RISCV/RISCVBaseInfoTest.cpp | 43 ++++++- 10 files changed, 187 insertions(+), 132 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 8563f678464a6..591ea72d5e857 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -330,28 +330,22 @@ class RISCVAsmParser : public MCTargetAsmParser { Parser.addAliasForDirective(".dword", ".8byte"); setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); - auto ABIName = StringRef(getTargetOptions().ABIName); - if (ABIName.ends_with("f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) { - errs() << "Hard-float 'f' ABI can't be used for a target that " - "doesn't support the F instruction set extension (ignoring " - "target-abi)\n"; - } else if (ABIName.ends_with("d") && - !getSTI().hasFeature(RISCV::FeatureStdExtD)) { - errs() << "Hard-float 'd' ABI can't be used for a target that " - "doesn't support the D instruction set extension (ignoring " - "target-abi)\n"; - } - - // Use computeTargetABI to check if ABIName is valid. If invalid, output - // error message. - RISCVABI::computeTargetABI(STI, ABIName); - const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo(); ParserOptions.IsPicEnabled = MOFI->isPositionIndependent(); if (AddBuildAttributes) getTargetStreamer().emitTargetAttributes(STI, /*EmitStackAlign*/ false); } + + // Validate the requested -target-abi now that the lexer has been primed + // with the first token, so diagnostics can be reported with a real source + // location instead of being printed with no location information. + void onBeginOfFile() override { + Expected<RISCVABI::ABI> ABIOrErr = + RISCVABI::computeTargetABI(getSTI(), getTargetOptions().ABIName); + if (!ABIOrErr) + getParser().printError(getLoc(), toString(ABIOrErr.takeError())); + } }; /// RISCVOperand - Instances of this class represent a parsed machine diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp index 7753a0d118eef..110dce5e3e928 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp @@ -53,7 +53,7 @@ namespace RISCV { } // namespace RISCV namespace RISCVABI { -ABI computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName) { +Expected<ABI> computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName) { const Triple &TT = STI.getTargetTriple(); const FeatureBitset &FeatureBits = STI.getFeatureBits(); auto TargetABI = getTargetABI(ABIName); @@ -62,37 +62,43 @@ ABI computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName) { bool IsXCheriot = FeatureBits[RISCV::FeatureVendorXCheriot]; if (!ABIName.empty() && TargetABI == ABI_Unknown) { - errs() - << "'" << ABIName - << "' is not a recognized ABI for this target (ignoring target-abi)\n"; - } else if (ABIName.starts_with("ilp32") && IsRV64) { - errs() << "32-bit ABIs are not supported for 64-bit targets (ignoring " - "target-abi)\n"; - TargetABI = ABI_Unknown; - } else if (ABIName.starts_with("lp64") && !IsRV64) { - errs() << "64-bit ABIs are not supported for 32-bit targets (ignoring " - "target-abi)\n"; - TargetABI = ABI_Unknown; - } else if (!IsRV64 && IsRVE && !IsXCheriot && TargetABI != ABI_ILP32E && - TargetABI != ABI_Unknown) { - // TODO: move this checking to RISCVTargetLowering and RISCVAsmParser - errs() - << "Only the ilp32e ABI is supported for RV32E (ignoring target-abi)\n"; - TargetABI = ABI_Unknown; - } else if (!IsRV64 && IsRVE && IsXCheriot && TargetABI != ABI_CHERIOT && - TargetABI != ABI_Unknown) { - errs() << "Only the cheriot ABI is supported for XCheriot (ignoring " - "target-abi)\n"; - TargetABI = ABI_Unknown; - } else if (IsRV64 && IsRVE && TargetABI != ABI_LP64E && - TargetABI != ABI_Unknown) { - // TODO: move this checking to RISCVTargetLowering and RISCVAsmParser - errs() - << "Only the lp64e ABI is supported for RV64E (ignoring target-abi)\n"; - TargetABI = ABI_Unknown; + return createStringError(Twine("'") + ABIName + + "' is not a recognized ABI for this target"); + } + if (ABIName.starts_with("ilp32") && IsRV64) { + return createStringError( + "32-bit ABIs are not supported for 64-bit targets"); + } + if (ABIName.starts_with("lp64") && !IsRV64) { + return createStringError( + "64-bit ABIs are not supported for 32-bit targets"); + } + if (ABIName.ends_with("f") && !FeatureBits[RISCV::FeatureStdExtF]) { + return createStringError( + "hard-float 'f' ABI can't be used for a target that doesn't " + "support the F instruction set extension"); + } + if (ABIName.ends_with("d") && !FeatureBits[RISCV::FeatureStdExtD]) { + return createStringError( + "hard-float 'd' ABI can't be used for a target that doesn't " + "support the D instruction set extension"); + } + if (!IsRV64 && IsRVE && !IsXCheriot && TargetABI != ABI_ILP32E && + TargetABI != ABI_Unknown) { + return createStringError("only the ilp32e ABI is supported for RV32E"); + } + if (!IsRV64 && IsRVE && IsXCheriot && TargetABI != ABI_CHERIOT && + TargetABI != ABI_Unknown) { + return createStringError( + "only the cheriot ABI is supported for XCheriot"); + } + if (IsRV64 && IsRVE && TargetABI != ABI_LP64E && + TargetABI != ABI_Unknown) { + return createStringError("only the lp64e ABI is supported for RV64E"); } - if ((TargetABI == RISCVABI::ABI::ABI_ILP32E || + // Unconditionally fatal: no sensible default ABI to fall back to here. + if ((TargetABI == ABI_ILP32E || (TargetABI == ABI_Unknown && IsRVE && !IsRV64)) && FeatureBits[RISCV::FeatureStdExtD]) reportFatalUsageError("ILP32E cannot be used with the D ISA extension"); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index e54d57d9f4451..a34db0fda3c9b 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringTable.h" #include "llvm/MC/MCInstrDesc.h" +#include "llvm/Support/Error.h" #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" #include "llvm/TargetParser/SubtargetFeature.h" @@ -733,8 +734,8 @@ enum ABI { }; // Returns the target ABI, or else a StringError if the requested ABIName is -// not supported for the subtargets triple and FeatureBits combination. -ABI computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName); +// not supported for the subtarget's triple and FeatureBits combination. +Expected<ABI> computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName); ABI getTargetABI(StringRef ABIName); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp index 032a6a014436a..9fb15105a9056 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -21,6 +21,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -30,8 +31,15 @@ RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S, : RISCVTargetStreamer(S), CurrentVendor("riscv") { MCAssembler &MCA = getStreamer().getAssembler(); auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend()); - setTargetABI( - RISCVABI::computeTargetABI(STI, MAB.getTargetOptions().getABIName())); + // See RISCVSubtarget::initializeSubtargetDependencies: can't be fatal. + auto ABIOrErr = + RISCVABI::computeTargetABI(STI, MAB.getTargetOptions().getABIName()); + if (ABIOrErr) { + setTargetABI(*ABIOrErr); + } else { + errs() << toString(ABIOrErr.takeError()) << " (ignoring target-abi)\n"; + setTargetABI(cantFail(RISCVABI::computeTargetABI(STI, ""))); + } setFlagsFromFeatures(STI); // Compute the initial ISA string. This serves two purposes: diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index aad62e7d40c54..92fc27c33c0d2 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -137,20 +137,14 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, RISCVABI::ABI ABI = Subtarget.getTargetABI(); assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI"); - - if ((ABI == RISCVABI::ABI_ILP32F || ABI == RISCVABI::ABI_LP64F) && - !Subtarget.hasStdExtF()) { - errs() << "Hard-float 'f' ABI can't be used for a target that " - "doesn't support the F instruction set extension (ignoring " - "target-abi)\n"; - ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32; - } else if ((ABI == RISCVABI::ABI_ILP32D || ABI == RISCVABI::ABI_LP64D) && - !Subtarget.hasStdExtD()) { - errs() << "Hard-float 'd' ABI can't be used for a target that " - "doesn't support the D instruction set extension (ignoring " - "target-abi)\n"; - ABI = Subtarget.is64Bit() ? RISCVABI::ABI_LP64 : RISCVABI::ABI_ILP32; - } + // Hard-float ABIs that don't match the F/D extensions are already rejected + // by RISCVABI::computeTargetABI() when the subtarget is constructed. + assert(((ABI != RISCVABI::ABI_ILP32F && ABI != RISCVABI::ABI_LP64F) || + Subtarget.hasStdExtF()) && + "F ABI without F extension"); + assert(((ABI != RISCVABI::ABI_ILP32D && ABI != RISCVABI::ABI_LP64D) || + Subtarget.hasStdExtD()) && + "D ABI without D extension"); switch (ABI) { default: diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp index b807534e986c1..e112213742bfd 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -117,7 +118,15 @@ RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU, HasStdExtC = hasFeature(RISCV::FeatureStdExtC); HasStdExtZce = hasFeature(RISCV::FeatureStdExtZce); - TargetABI = RISCVABI::computeTargetABI(*this, ABIName); + // Can't be fatal: per-function subtargets mean this one may just be the + // module-level default with no matching function, e.g. -target-abi ilp32f + // with no global -mattr=+f but all functions have their own "+f" attribute. + if (auto ABIOrErr = RISCVABI::computeTargetABI(*this, ABIName)) { + TargetABI = *ABIOrErr; + } else { + errs() << toString(ABIOrErr.takeError()) << " (ignoring target-abi)\n"; + TargetABI = cantFail(RISCVABI::computeTargetABI(*this, "")); + } RISCVFeatures::validate(TT, getFeatureBits()); return *this; } diff --git a/llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll b/llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll index 5893ae275e3b1..e7bab947b3507 100644 --- a/llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll +++ b/llvm/test/CodeGen/RISCV/subtarget-features-std-ext.ll @@ -5,7 +5,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=-f -target-abi ilp32f <%s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV32I-ILP32F-FAILED %s -; RV32I-ILP32F-FAILED: Hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension +; RV32I-ILP32F-FAILED: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension define float @foo(i32 %a) nounwind #0 { diff --git a/llvm/test/CodeGen/RISCV/target-abi-invalid.ll b/llvm/test/CodeGen/RISCV/target-abi-invalid.ll index 41c08f1f19d19..e383a16dcb345 100644 --- a/llvm/test/CodeGen/RISCV/target-abi-invalid.ll +++ b/llvm/test/CodeGen/RISCV/target-abi-invalid.ll @@ -36,8 +36,8 @@ ; RUN: llc -mtriple=riscv64 -target-abi lp64f < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV64I-LP64F %s -; RV32I-ILP32F: Hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) -; RV64I-LP64F: Hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) +; RV32I-ILP32F: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) +; RV64I-LP64F: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) ; RUN: llc -mtriple=riscv32 -target-abi ilp32d < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV32I-ILP32D %s @@ -48,10 +48,10 @@ ; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64d < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV64IF-LP64D %s -; RV32I-ILP32D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) -; RV32IF-ILP32D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) -; RV64I-LP64D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) -; RV64IF-LP64D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) +; RV32I-ILP32D: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) +; RV32IF-ILP32D: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) +; RV64I-LP64D: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) +; RV64IF-LP64D: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) define void @nothing() nounwind { ret void diff --git a/llvm/test/MC/RISCV/target-abi-invalid.s b/llvm/test/MC/RISCV/target-abi-invalid.s index 35b42a88618b7..06df035a6176a 100644 --- a/llvm/test/MC/RISCV/target-abi-invalid.s +++ b/llvm/test/MC/RISCV/target-abi-invalid.s @@ -1,107 +1,109 @@ -# RUN: llvm-mc -triple=riscv32 -target-abi foo < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -target-abi foo < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32I-FOO %s -# RUN: llvm-mc -triple=riscv32 -mattr=+f -target-abi ilp32foof < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+f -target-abi ilp32foof < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32IF-ILP32FOOF %s -# RV32I-FOO: 'foo' is not a recognized ABI for this target (ignoring target-abi) -# RV32IF-ILP32FOOF: 'ilp32foof' is not a recognized ABI for this target (ignoring target-abi) +# RV32I-FOO: <stdin>:1:1: error: 'foo' is not a recognized ABI for this target +# RV32IF-ILP32FOOF: <stdin>:1:1: error: 'ilp32foof' is not a recognized ABI for this target -# RUN: llvm-mc -triple=riscv64 -target-abi ilp32 < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -target-abi ilp32 < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64I-ILP32 %s -# RUN: llvm-mc -triple=riscv64 -mattr=+f -target-abi ilp32f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+f -target-abi ilp32f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64IF-ILP32F %s -# RUN: llvm-mc -triple=riscv64 -mattr=+d -target-abi ilp32d < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+d -target-abi ilp32d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64IFD-ILP32D %s -# RUN: llvm-mc -triple=riscv64 -target-abi ilp32e < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -target-abi ilp32e < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64I-ILP32E %s -# RV64I-ILP32: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) -# RV64IF-ILP32F: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) -# RV64IFD-ILP32D: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) -# RV64I-ILP32E: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) +# RV64I-ILP32: <stdin>:1:1: error: 32-bit ABIs are not supported for 64-bit targets +# RV64IF-ILP32F: <stdin>:1:1: error: 32-bit ABIs are not supported for 64-bit targets +# RV64IFD-ILP32D: <stdin>:1:1: error: 32-bit ABIs are not supported for 64-bit targets +# RV64I-ILP32E: <stdin>:1:1: error: 32-bit ABIs are not supported for 64-bit targets -# RUN: llvm-mc -triple=riscv32 -target-abi lp64 < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -target-abi lp64 < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32I-LP64 %s -# RUN: llvm-mc -triple=riscv32 -mattr=+f -target-abi lp64f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+f -target-abi lp64f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32IF-LP64F %s -# RUN: llvm-mc -triple=riscv32 -mattr=+d -target-abi lp64d < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+d -target-abi lp64d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32IFD-LP64D %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64 < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64 < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32E-LP64 %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32EF-LP64F %s -# RUN: not llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi lp64d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32EFD-LP64D %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64e %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64e < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32E-LP64E %s -# RV32I-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32IF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32IFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32E-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32EF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32EFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32E-LP64E: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -# RV32EFD-LP64D: LLVM ERROR: ILP32E cannot be used with the D ISA extension +# RV32I-LP64: <stdin>:1:1: error: 64-bit ABIs are not supported for 32-bit targets +# RV32IF-LP64F: <stdin>:1:1: error: 64-bit ABIs are not supported for 32-bit targets +# RV32IFD-LP64D: <stdin>:1:1: error: 64-bit ABIs are not supported for 32-bit targets +# RV32E-LP64: <stdin>:1:1: error: 64-bit ABIs are not supported for 32-bit targets +# RV32EF-LP64F: <stdin>:1:1: error: 64-bit ABIs are not supported for 32-bit targets +# RV32EFD-LP64D: <stdin>:1:1: error: 64-bit ABIs are not supported for 32-bit targets +# RV32E-LP64E: <stdin>:1:1: error: 64-bit ABIs are not supported for 32-bit targets -# RUN: llvm-mc -triple=riscv32 -target-abi ilp32f < %s 2>&1 \ +# An explicit ABI that matches the RVE requirement (so it isn't rejected by earlier checks) +# RUN: not llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi ilp32e < %s 2>&1 \ +# RUN: | FileCheck -check-prefix=RV32E-ILP32E-D %s +# RV32E-ILP32E-D: LLVM ERROR: ILP32E cannot be used with the D ISA extension + +# RUN: not llvm-mc -triple=riscv32 -target-abi ilp32f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32I-ILP32F %s -# RUN: llvm-mc -triple=riscv64 -target-abi lp64f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -target-abi lp64f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64I-LP64F %s -# RV32I-ILP32F: Hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) -# RV64I-LP64F: Hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) +# RV32I-ILP32F: <stdin>:1:1: error: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension +# RV64I-LP64F: <stdin>:1:1: error: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension -# RUN: llvm-mc -triple=riscv32 -target-abi ilp32d < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -target-abi ilp32d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32I-ILP32D %s -# RUN: llvm-mc -triple=riscv32 -mattr=+f -target-abi ilp32d < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+f -target-abi ilp32d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32IF-ILP32D %s -# RUN: llvm-mc -triple=riscv64 -target-abi lp64d < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -target-abi lp64d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64I-LP64D %s -# RUN: llvm-mc -triple=riscv64 -mattr=+f -target-abi lp64d < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+f -target-abi lp64d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64IF-LP64D %s -# RV32I-ILP32D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) -# RV32IF-ILP32D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) -# RV64I-LP64D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) -# RV64IF-LP64D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi) +# RV32I-ILP32D: <stdin>:1:1: error: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension +# RV32IF-ILP32D: <stdin>:1:1: error: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension +# RV64I-LP64D: <stdin>:1:1: error: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension +# RV64IF-LP64D: <stdin>:1:1: error: hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension -# RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi ilp32 < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e -target-abi ilp32 < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32EF-ILP32F %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi ilp32f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi ilp32f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32EF-ILP32F %s # RUN: not llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi ilp32f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32EFD-ILP32F %s # RUN: not llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi ilp32d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32EFD-ILP32D %s -# RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi cheriot < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e -target-abi cheriot < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32E-CHERIOT %s -# RV32E-ILP32: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) -# RV32EF-ILP32F: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) -# RV32EFD-ILP32F: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) -# RV32EFD-ILP32F: LLVM ERROR: ILP32E cannot be used with the D ISA extension -# RV32EFD-ILP32D: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) -# RV32EFD-ILP32D: LLVM ERROR: ILP32E cannot be used with the D ISA extension -# RV32E-CHERIOT: Only the ilp32e ABI is supported for RV32E (ignoring target-abi) +# RV32E-ILP32: <stdin>:1:1: error: only the ilp32e ABI is supported for RV32E +# RV32EF-ILP32F: <stdin>:1:1: error: only the ilp32e ABI is supported for RV32E +# RV32EFD-ILP32F: <stdin>:1:1: error: only the ilp32e ABI is supported for RV32E +# RV32EFD-ILP32D: <stdin>:1:1: error: only the ilp32e ABI is supported for RV32E +# RV32E-CHERIOT: <stdin>:1:1: error: only the ilp32e ABI is supported for RV32E -# RUN: llvm-mc -triple=riscv64 -mattr=+e -target-abi lp64 < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+e -target-abi lp64 < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64EF-LP64F %s -# RUN: llvm-mc -triple=riscv64 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64EF-LP64F %s -# RUN: llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64EFD-LP64F %s -# RUN: llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64d < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv64 -mattr=+e,+d -target-abi lp64d < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV64EFD-LP64D %s -# RV64E-LP64: Only the lp64e ABI is supported for RV64E (ignoring target-abi) -# RV64EF-LP64F: Only the lp64e ABI is supported for RV64E (ignoring target-abi) -# RV64EFD-LP64F: Only the lp64e ABI is supported for RV64E (ignoring target-abi) -# RV64EFD-LP64D: Only the lp64e ABI is supported for RV64E (ignoring target-abi) +# RV64E-LP64: <stdin>:1:1: error: only the lp64e ABI is supported for RV64E +# RV64EF-LP64F: <stdin>:1:1: error: only the lp64e ABI is supported for RV64E +# RV64EFD-LP64F: <stdin>:1:1: error: only the lp64e ABI is supported for RV64E +# RV64EFD-LP64D: <stdin>:1:1: error: only the lp64e ABI is supported for RV64E -# RUN: llvm-mc -triple=riscv32 -mattr=+e,+xcheriot -target-abi ilp32e < %s 2>&1 \ +# RUN: not llvm-mc -triple=riscv32 -mattr=+e,+xcheriot -target-abi ilp32e < %s 2>&1 \ # RUN: | FileCheck -check-prefix=RV32EXCHERIOT-ILP32 %s -# RV32EXCHERIOT-ILP32: Only the cheriot ABI is supported for XCheriot (ignoring target-abi) +# RV32EXCHERIOT-ILP32: <stdin>:1:1: error: only the cheriot ABI is supported for XCheriot nop diff --git a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp b/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp index 0ad6645e52f7a..aaec27e166256 100644 --- a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp +++ b/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp @@ -32,7 +32,21 @@ std::unique_ptr<MCSubtargetInfo> createSTI(StringRef TripleName, RISCVABI::ABI computeTargetABI(StringRef TripleName, StringRef FeatureStr, StringRef ABIName = "") { auto STI = createSTI(TripleName, FeatureStr); - return RISCVABI::computeTargetABI(*STI, ABIName); + return cantFail(RISCVABI::computeTargetABI(*STI, ABIName)); +} + +// Returns the error message for a StringRef/FeatureStr/ABIName combination +// that is expected to be rejected by computeTargetABI. +std::string computeTargetABIError(StringRef TripleName, StringRef FeatureStr, + StringRef ABIName) { + auto STI = createSTI(TripleName, FeatureStr); + Expected<RISCVABI::ABI> Result = + RISCVABI::computeTargetABI(*STI, ABIName); + if (Result) { + ADD_FAILURE() << "expected an error for -target-abi " << ABIName; + return {}; + } + return toString(Result.takeError()); } TEST(ComputeTargetABI, SelectsExpectedABI) { @@ -47,4 +61,31 @@ TEST(ComputeTargetABI, SelectsExpectedABI) { EXPECT_EQ(computeTargetABI("riscv32", "+xcheriot"), RISCVABI::ABI_CHERIOT); } +TEST(ComputeTargetABI, ReportsInvalidExplicitABI) { + EXPECT_EQ(computeTargetABIError("riscv32", "", "foo"), + "'foo' is not a recognized ABI for this target"); + EXPECT_EQ(computeTargetABIError("riscv64", "", "ilp32"), + "32-bit ABIs are not supported for 64-bit targets"); + EXPECT_EQ(computeTargetABIError("riscv32", "", "lp64"), + "64-bit ABIs are not supported for 32-bit targets"); + EXPECT_EQ(computeTargetABIError("riscv32", "", "ilp32f"), + "hard-float 'f' ABI can't be used for a target that doesn't " + "support the F instruction set extension"); + EXPECT_EQ(computeTargetABIError("riscv64", "", "lp64f"), + "hard-float 'f' ABI can't be used for a target that doesn't " + "support the F instruction set extension"); + EXPECT_EQ(computeTargetABIError("riscv32", "", "ilp32d"), + "hard-float 'd' ABI can't be used for a target that doesn't " + "support the D instruction set extension"); + EXPECT_EQ(computeTargetABIError("riscv32", "+f", "ilp32d"), + "hard-float 'd' ABI can't be used for a target that doesn't " + "support the D instruction set extension"); + EXPECT_EQ(computeTargetABIError("riscv32", "+e", "ilp32"), + "only the ilp32e ABI is supported for RV32E"); + EXPECT_EQ(computeTargetABIError("riscv32", "+e,+xcheriot", "ilp32e"), + "only the cheriot ABI is supported for XCheriot"); + EXPECT_EQ(computeTargetABIError("riscv64", "+e", "lp64"), + "only the lp64e ABI is supported for RV64E"); +} + } // namespace >From 521ac0d42b577cb99a9f502209fe0ebb8846b631 Mon Sep 17 00:00:00 2001 From: Alexander Richardson <[email protected]> Date: Fri, 31 Jul 2026 22:59:28 -0700 Subject: [PATCH 2/4] clang-format Created using spr 1.3.8-beta.1-arichardson --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp | 6 ++---- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 8 ++++---- llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp | 3 +-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp index 110dce5e3e928..a12b0e70323fc 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp @@ -89,11 +89,9 @@ Expected<ABI> computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName) { } if (!IsRV64 && IsRVE && IsXCheriot && TargetABI != ABI_CHERIOT && TargetABI != ABI_Unknown) { - return createStringError( - "only the cheriot ABI is supported for XCheriot"); + return createStringError("only the cheriot ABI is supported for XCheriot"); } - if (IsRV64 && IsRVE && TargetABI != ABI_LP64E && - TargetABI != ABI_Unknown) { + if (IsRV64 && IsRVE && TargetABI != ABI_LP64E && TargetABI != ABI_Unknown) { return createStringError("only the lp64e ABI is supported for RV64E"); } diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 92fc27c33c0d2..7f3474c09ee28 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -140,11 +140,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, // Hard-float ABIs that don't match the F/D extensions are already rejected // by RISCVABI::computeTargetABI() when the subtarget is constructed. assert(((ABI != RISCVABI::ABI_ILP32F && ABI != RISCVABI::ABI_LP64F) || - Subtarget.hasStdExtF()) && - "F ABI without F extension"); + Subtarget.hasStdExtF()) && + "F ABI without F extension"); assert(((ABI != RISCVABI::ABI_ILP32D && ABI != RISCVABI::ABI_LP64D) || - Subtarget.hasStdExtD()) && - "D ABI without D extension"); + Subtarget.hasStdExtD()) && + "D ABI without D extension"); switch (ABI) { default: diff --git a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp b/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp index aaec27e166256..28ead3d5740bf 100644 --- a/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp +++ b/llvm/unittests/Target/RISCV/RISCVBaseInfoTest.cpp @@ -40,8 +40,7 @@ RISCVABI::ABI computeTargetABI(StringRef TripleName, StringRef FeatureStr, std::string computeTargetABIError(StringRef TripleName, StringRef FeatureStr, StringRef ABIName) { auto STI = createSTI(TripleName, FeatureStr); - Expected<RISCVABI::ABI> Result = - RISCVABI::computeTargetABI(*STI, ABIName); + Expected<RISCVABI::ABI> Result = RISCVABI::computeTargetABI(*STI, ABIName); if (Result) { ADD_FAILURE() << "expected an error for -target-abi " << ABIName; return {}; >From 3e1921cb666cbba10835304789330532f5508789 Mon Sep 17 00:00:00 2001 From: Alexander Richardson <[email protected]> Date: Tue, 4 Aug 2026 14:09:50 -0700 Subject: [PATCH 3/4] drop warning message that is now printed by subtarget Created using spr 1.3.8-beta.1-arichardson --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 681a765580090..e9926ebf17ec8 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -136,15 +136,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, : TargetLowering(TM, STI), Subtarget(STI) { RISCVABI::ABI ABI = Subtarget.getTargetABI(); + // Note: Hard-float ABIs that don't match the F/D extensions are already + // rejected/ by RISCVABI::computeTargetABI() during subtarget construction. assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI"); - // Hard-float ABIs that don't match the F/D extensions are already rejected - // by RISCVABI::computeTargetABI() when the subtarget is constructed. - assert(((ABI != RISCVABI::ABI_ILP32F && ABI != RISCVABI::ABI_LP64F) || - Subtarget.hasStdExtF()) && - "F ABI without F extension"); - assert(((ABI != RISCVABI::ABI_ILP32D && ABI != RISCVABI::ABI_LP64D) || - Subtarget.hasStdExtD()) && - "D ABI without D extension"); switch (ABI) { default: >From 05801eadc7e281cd55ad1e9043e911b9f913a0c0 Mon Sep 17 00:00:00 2001 From: Alexander Richardson <[email protected]> Date: Tue, 4 Aug 2026 14:58:49 -0700 Subject: [PATCH 4/4] improve tests Created using spr 1.3.8-beta.1-arichardson --- llvm/test/CodeGen/RISCV/target-abi-invalid.ll | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/llvm/test/CodeGen/RISCV/target-abi-invalid.ll b/llvm/test/CodeGen/RISCV/target-abi-invalid.ll index 92823bdffd02c..72e3cba6d8d00 100644 --- a/llvm/test/CodeGen/RISCV/target-abi-invalid.ll +++ b/llvm/test/CodeGen/RISCV/target-abi-invalid.ll @@ -3,8 +3,8 @@ ; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32foof < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV32IF-ILP32FOOF %s -; RV32I-FOO: 'foo' is not a recognized ABI for this target (ignoring target-abi) -; RV32IF-ILP32FOOF: 'ilp32foof' is not a recognized ABI for this target (ignoring target-abi) +; 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) ; RUN: llc -mtriple=riscv64 -target-abi ilp32 < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV64I-ILP32 %s @@ -15,10 +15,10 @@ ; RUN: llc -mtriple=riscv64 -target-abi ilp32e < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV64I-ILP32E %s -; RV64I-ILP32: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) -; RV64IF-ILP32F: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) -; RV64IFD-ILP32D: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) -; RV64I-ILP32E: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) +; RV64I-ILP32: note: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) +; RV64IF-ILP32F: note: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) +; RV64IFD-ILP32D: note: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) +; RV64I-ILP32E: note: 32-bit ABIs are not supported for 64-bit targets (ignoring target-abi) ; RUN: llc -mtriple=riscv32 -target-abi lp64 < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV32I-LP64 %s @@ -27,17 +27,17 @@ ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi lp64d < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV32IFD-LP64D %s -; RV32I-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -; RV32IF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) -; RV32IFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) +; RV32I-LP64: note: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) +; RV32IF-LP64F: note: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) +; RV32IFD-LP64D: note: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi) ; RUN: llc -mtriple=riscv32 -target-abi ilp32f < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV32I-ILP32F %s ; RUN: llc -mtriple=riscv64 -target-abi lp64f < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV64I-LP64F %s -; RV32I-ILP32F: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) -; RV64I-LP64F: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) +; RV32I-ILP32F: note: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) +; RV64I-LP64F: note: hard-float 'f' ABI can't be used for a target that doesn't support the F instruction set extension (ignoring target-abi) ; RUN: llc -mtriple=riscv32 -target-abi ilp32d < %s 2>&1 \ ; RUN: | FileCheck -check-prefix=RV32I-ILP32D %s _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
