https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/227865
>From 47c03528cd0595bc454c6a183604968f228f6ea9 Mon Sep 17 00:00:00 2001 From: Alex Richardson <[email protected]> Date: Tue, 20 Oct 2026 10:24:07 -0700 Subject: [PATCH] [nspr] initial commit --- .../Driver/print-supported-extensions-riscv.c | 2 +- lld/test/ELF/riscv-attributes.s | 4 +- llvm/lib/Support/RISCVISAUtils.cpp | 6 +- llvm/lib/TargetParser/RISCVISAInfo.cpp | 38 ++++---- llvm/test/CodeGen/RISCV/attributes.ll | 2 +- llvm/test/MC/RISCV/rvy-build-attributes.s | 37 +++++--- .../ELF/RISCV/unknown-arch-attr.test | 6 +- .../TargetParser/RISCVISAInfoTest.cpp | 95 ++++++++++++++++--- 8 files changed, 135 insertions(+), 55 deletions(-) diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index f916bef0a6519a..1d1714314d6e26 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -247,8 +247,8 @@ // CHECK-NEXT: xwchc 2.2 'Xwchc' (WCH/QingKe additional compressed opcodes) // CHECK-EMPTY: // CHECK-NEXT: Experimental extensions -// CHECK-NEXT: p 0.21 'P' ('Base P' (Packed SIMD)) // CHECK-NEXT: y 0.910 'Y' ('Base Y' (CHERI)) +// CHECK-NEXT: p 0.21 'P' ('Base P' (Packed SIMD)) // CHECK-NEXT: zibi 0.1 'Zibi' (Branch with Immediate) // CHECK-NEXT: zicfilp 1.0 'Zicfilp' (Landing pad) // CHECK-NEXT: zilx 0.1 'Zilx' (Indexed Integer Load Instructions) diff --git a/lld/test/ELF/riscv-attributes.s b/lld/test/ELF/riscv-attributes.s index c6666063396d46..02a83dc9afd743 100644 --- a/lld/test/ELF/riscv-attributes.s +++ b/lld/test/ELF/riscv-attributes.s @@ -220,7 +220,7 @@ # UNRECOGNIZED_EXT1-NEXT: Attribute { # UNRECOGNIZED_EXT1-NEXT: Tag: 5 # UNRECOGNIZED_EXT1-NEXT: TagName: arch -# UNRECOGNIZED_EXT1-NEXT: Value: rv64i2p1_y2p0{{$}} +# UNRECOGNIZED_EXT1-NEXT: Value: rv64i2p1_w2p0{{$}} # UNRECOGNIZED_EXT1-NEXT: } # UNRECOGNIZED_EXT1-NEXT: } # UNRECOGNIZED_EXT1-NEXT: } @@ -233,7 +233,7 @@ .byte 1 # Tag_File .long .Lend-.Lbegin .byte 5 # Tag_RISCV_arch -.asciz "rv64i2p1_y2p0" +.asciz "rv64i2p1_w2p0" .Lend: #--- unrecognized_ext2.s diff --git a/llvm/lib/Support/RISCVISAUtils.cpp b/llvm/lib/Support/RISCVISAUtils.cpp index d6b002e66e7ab2..2166d2f30bbb96 100644 --- a/llvm/lib/Support/RISCVISAUtils.cpp +++ b/llvm/lib/Support/RISCVISAUtils.cpp @@ -44,15 +44,17 @@ static unsigned singleLetterExtensionRank(char Ext) { return 0; case 'e': return 1; + case 'y': + return 2; } size_t Pos = RISCVISAUtils::AllStdExts.find(Ext); if (Pos != StringRef::npos) - return Pos + 2; // Skip 'e' and 'i' from above. + return Pos + 3; // Skip 'e', 'i', and 'y' from above. // If we got an unknown extension letter, then give it an alphabetical // order, but after all known standard extensions. - return 2 + RISCVISAUtils::AllStdExts.size() + (Ext - 'a'); + return 3 + RISCVISAUtils::AllStdExts.size() + (Ext - 'a'); } // Get the rank for multi-letter extension, lower value meaning higher diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index a8f4d3469ef20c..ca2e269386be71 100644 --- a/llvm/lib/TargetParser/RISCVISAInfo.cpp +++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include <atomic> @@ -483,7 +484,7 @@ RISCVISAInfo::parseNormalizedArchString(StringRef Arch) { else if (Arch.consume_front("rv64")) XLen = 64; - auto IsBaseISA = [](char C) { return C == 'i' || C == 'e'; }; + auto IsBaseISA = [](char C) { return C == 'i' || C == 'e' || C == 'y'; }; if (XLen == 0 || Arch.empty() || !IsBaseISA(Arch[0])) return getError("arch string must begin with valid base ISA"); char BaseISA = Arch[0]; @@ -556,6 +557,10 @@ RISCVISAInfo::parseNormalizedArchString(StringRef Arch) { .second) return getError("duplicate extension '" + ExtName + "'"); } + // Plain 'y' always implies 'i' (which is omitted in the normalized arch + // string). Y+E requires a long base name arch string. + if (BaseISA == "y") + ISAInfo->Exts["i"] = *findDefaultVersion("i"); ISAInfo->updateImpliedLengths(); return std::move(ISAInfo); } @@ -628,7 +633,11 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension, "\' should be 'e', 'i', 'g' or 'y'"); case 'e': case 'i': - // Baseline is `i` or `e` + case 'y': + // Baseline is 'i', 'e', or 'y' (which implies 'i' in updateImplication). + // TODO: arch string syntax for RVE+RVY (and y in non-first position) will + // be included following conclusion of "long base name" syntax + // https://lists.riscv.org/g/tech-unprivileged/message/1134 if (auto E = getExtensionVersion( StringRef(&Baseline, 1), Arch, Major, Minor, ConsumeLength, EnableExperimentalExtension, ExperimentalExtensionVersionCheck)) @@ -636,22 +645,6 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension, ISAInfo->Exts[std::string(1, Baseline)] = {Major, Minor}; break; - case 'y': { - // If the first character is 'y', this is equivalent to "iy". - // TODO: arch string syntax for RVE+RVY (and y in non-first position) will - // be included following conclusion of "long base name" syntax - // https://lists.riscv.org/g/tech-unprivileged/message/1134 - if (auto E = getExtensionVersion("y", Arch, Major, Minor, ConsumeLength, - EnableExperimentalExtension, - ExperimentalExtensionVersionCheck)) - return std::move(E); - - ISAInfo->Exts["y"] = {Major, Minor}; - auto IVersion = findDefaultVersion("i"); - assert(IVersion && "Default 'i' extension version not found?"); - ISAInfo->Exts["i"] = {IVersion->Major, IVersion->Minor}; - break; - } case 'g': // g expands to extensions in RISCVGImplications. if (!Arch.empty() && isDigit(Arch.front())) @@ -1075,9 +1068,18 @@ std::string RISCVISAInfo::toString() const { Arch << "rv" << XLen; + bool HasY = Exts.count("y") != 0; ListSeparator LS("_"); for (auto const &Ext : Exts) { StringRef ExtName = Ext.first; + if (HasY) { + // Plain 'y' always implies 'i' (which is omitted in the normalized arch + // string). Y+E requires a long base name arch string. + if (ExtName == "i") + continue; + if (ExtName == "e") + reportFatalUsageError("Y+E is not supported yet"); + } auto ExtInfo = Ext.second; Arch << LS << ExtName; Arch << ExtInfo.Major << "p" << ExtInfo.Minor; diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll index 765245ef4db725..554188c084a270 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -711,7 +711,7 @@ ; RV64SDEXT: .attribute 5, "rv64i2p1_sdext1p0" ; RV64SDTRIG: .attribute 5, "rv64i2p1_sdtrig1p0" ; RV64P: .attribute 5, "rv64i2p1_p0p21_zicsr2p0_zmmul1p0_zba1p0_zbb1p0" -; RV64Y: .attribute 5, "rv64i2p1_y0p910" +; RV64Y: .attribute 5, "rv64y0p910" ; RV64ZIBI: .attribute 5, "rv64i2p1_zibi0p1" ; RV64ZVQWBDOTA8I: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvqwbdota8i0p2" ; RV64ZVQWBDOTA16I: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_zvqwbdota16i0p2" diff --git a/llvm/test/MC/RISCV/rvy-build-attributes.s b/llvm/test/MC/RISCV/rvy-build-attributes.s index f7db55b382ec81..512db1e95f5291 100644 --- a/llvm/test/MC/RISCV/rvy-build-attributes.s +++ b/llvm/test/MC/RISCV/rvy-build-attributes.s @@ -1,35 +1,44 @@ +## Pipe the assembly output through a second llvm-mc invocation to ensure the +## emitted '.attribute 5, "..."' arch string round-trips cleanly. # RUN: llvm-mc %s -triple=riscv64 -filetype=asm -riscv-add-build-attributes \ -# RUN: -mattr=+experimental-y,+d,+c | FileCheck %s --check-prefix=RV64YDC +# RUN: -mattr=+experimental-y,+d,+c | llvm-mc -triple=riscv64 -filetype=asm \ +# RUN: | FileCheck %s --check-prefix=RV64YDC # RUN: llvm-mc %s -triple=riscv32 -filetype=asm -riscv-add-build-attributes \ -# RUN: -mattr=+experimental-y,+f,+c | FileCheck %s --check-prefix=RV32YFC +# RUN: -mattr=+experimental-y,+f,+c | llvm-mc -triple=riscv32 -filetype=asm \ +# RUN: | FileCheck %s --check-prefix=RV32YFC # RUN: llvm-mc %s -triple=riscv32 -filetype=asm -riscv-add-build-attributes \ -# RUN: -mattr=+experimental-y,+zca,+f | FileCheck %s --check-prefix=RV32Y-ZCA-F +# RUN: -mattr=+experimental-y,+zca,+f | llvm-mc -triple=riscv32 -filetype=asm \ +# RUN: | FileCheck %s --check-prefix=RV32Y-ZCA-F # RUN: llvm-mc %s -triple=riscv64 -filetype=asm -riscv-add-build-attributes \ -# RUN: -mattr=+experimental-y,+zca,+d | FileCheck %s --check-prefix=RV64Y-ZCA-D +# RUN: -mattr=+experimental-y,+zca,+d | llvm-mc -triple=riscv64 -filetype=asm \ +# RUN: | FileCheck %s --check-prefix=RV64Y-ZCA-D # RUN: llvm-mc %s -triple=riscv64 -filetype=asm -riscv-add-build-attributes \ -# RUN: -mattr=+experimental-y,+zca,+zcb | FileCheck %s --check-prefix=RV64Y-ZCA-ZCB +# RUN: -mattr=+experimental-y,+zca,+zcb | llvm-mc -triple=riscv64 -filetype=asm \ +# RUN: | FileCheck %s --check-prefix=RV64Y-ZCA-ZCB # RUN: llvm-mc %s -triple=riscv32 -filetype=asm -riscv-add-build-attributes \ -# RUN: -mattr=+experimental-y,+zce | FileCheck %s --check-prefix=RV32Y-ZCE +# RUN: -mattr=+experimental-y,+zce | llvm-mc -triple=riscv32 -filetype=asm \ +# RUN: | FileCheck %s --check-prefix=RV32Y-ZCE # RUN: llvm-mc %s -triple=riscv32 -filetype=asm -riscv-add-build-attributes \ -# RUN: -mattr=+experimental-y,+zce,+f | FileCheck %s --check-prefix=RV32Y-ZCE-F +# RUN: -mattr=+experimental-y,+zce,+f | llvm-mc -triple=riscv32 -filetype=asm \ +# RUN: | FileCheck %s --check-prefix=RV32Y-ZCE-F ## RV64Y + D + C: y is enabled, so zcd is not implied. -# RV64YDC: .attribute 5, "rv64i2p1_f2p2_d2p2_c2p0_y0p910_zicsr2p0_zca1p0" +# RV64YDC: .attribute 5, "rv64y0p910_f2p2_d2p2_c2p0_zicsr2p0_zca1p0" ## RV32Y + F + C: y is enabled, so zcf is not implied. -# RV32YFC: .attribute 5, "rv32i2p1_f2p2_c2p0_y0p910_zicsr2p0_zca1p0" +# RV32YFC: .attribute 5, "rv32y0p910_f2p2_c2p0_zicsr2p0_zca1p0" ## RV32Y + ZCA + F: zca + y implies c on RV32 (y replaces zcf in the implication). -# RV32Y-ZCA-F: .attribute 5, "rv32i2p1_f2p2_c2p0_y0p910_zicsr2p0_zca1p0" +# RV32Y-ZCA-F: .attribute 5, "rv32y0p910_f2p2_c2p0_zicsr2p0_zca1p0" ## RV64Y + ZCA + D: zca + y implies c on RV64 (y replaces zcd in the implication). -# RV64Y-ZCA-D: .attribute 5, "rv64i2p1_f2p2_d2p2_c2p0_y0p910_zicsr2p0_zca1p0" +# RV64Y-ZCA-D: .attribute 5, "rv64y0p910_f2p2_d2p2_c2p0_zicsr2p0_zca1p0" ## RV64Y + ZCA + ZCB: zca + zcb + y does NOT imply zce on RV64Y because Zce is incompatible. zca also implies c. -# RV64Y-ZCA-ZCB: .attribute 5, "rv64i2p1_c2p0_y0p910_zca1p0_zcb1p0" +# RV64Y-ZCA-ZCB: .attribute 5, "rv64y0p910_c2p0_zca1p0_zcb1p0" ## RV32Y + ZCE: zce implies zca, zcb, zcmp, zcmt. zca implies c. -# RV32Y-ZCE: .attribute 5, "rv32i2p1_c2p0_y0p910_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0" +# RV32Y-ZCE: .attribute 5, "rv32y0p910_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0" ## RV32Y + ZCE + F: y is enabled, so zcf is not implied by zce + f. zca + y + f implies c. -# RV32Y-ZCE-F: .attribute 5, "rv32i2p1_f2p2_c2p0_y0p910_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0" +# RV32Y-ZCE-F: .attribute 5, "rv32y0p910_f2p2_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0" diff --git a/llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test b/llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test index 704c9d4add0d1d..59750e867c4e23 100644 --- a/llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test +++ b/llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test @@ -3,7 +3,7 @@ ## The expected behavior is to ignore the unrecognized arch feature and ## continue to process the following arch features. ## -## The object file has the "rv32i2p0_m2p0_y1p0" arch feature. "y1p0" is an +## The object file has the "rv32i2p0_m2p0_w1p0" arch feature. "w1p0" is an ## unrecognized architecture extension. llvm-objdump will ignore it and decode ## "mul" instruction correctly according to "m2p0" in the arch feature. ## @@ -34,5 +34,5 @@ Sections: Content: 3385C502 - Name: .riscv.attributes Type: SHT_RISCV_ATTRIBUTES -## The content is the encoding of the arch feature "rv32i2p0_m2p0_y1p0" - Content: 412300000072697363760001190000000572763332693270305F6D3270305F7931703000 +## The content is the encoding of the arch feature "rv32i2p0_m2p0_w1p0" + Content: 412300000072697363760001190000000572763332693270305F6D3270305F7731703000 diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index fc258241d0ef98..978c8fb3c9f315 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -48,6 +48,26 @@ TEST(ParseNormalizedArchString, RejectsConflictingBaseISAs) { toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), "conflicting base ISAs 'e' and 'i'"); } + for (StringRef Input : {"rv32y0p910_i2p1", "rv64y0p910_m2p0_i2p1"}) { + EXPECT_EQ( + toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), + "conflicting base ISAs 'y' and 'i'"); + } + for (StringRef Input : {"rv32y0p910_e2p0", "rv64y0p910_m2p0_e2p0"}) { + EXPECT_EQ( + toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), + "conflicting base ISAs 'y' and 'e'"); + } + for (StringRef Input : {"rv32i2p0_y0p910", "rv32i2p0_m2p0_y1p0"}) { + EXPECT_EQ( + toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), + "conflicting base ISAs 'i' and 'y'"); + } + for (StringRef Input : {"rv32e2p0_y0p910", "rv64e2p0_m2p0_y0p910"}) { + EXPECT_EQ( + toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), + "conflicting base ISAs 'e' and 'y'"); + } } TEST(ParseNormalizedArchString, RejectsMalformedInputs) { @@ -69,6 +89,12 @@ TEST(ParseNormalizedArchString, RejectsMalformedInputs) { "base ISA 'e' is missing version number"); } + for (StringRef Input : {"rv64ya2p0", "rv32i2p0_ym2p0"}) { + EXPECT_EQ( + toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), + "base ISA 'y' is missing version number"); + } + EXPECT_EQ(toString(RISCVISAInfo::parseNormalizedArchString("rv32i2p0_ma2p0") .takeError()), "extension 'm' is missing version number"); @@ -121,6 +147,10 @@ TEST(ParseNormalizedArchString, DuplicateExtension) { toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), "duplicate extension 'a'"); } + EXPECT_EQ( + toString(RISCVISAInfo::parseNormalizedArchString("rv64y0p910_y0p910") + .takeError()), + "duplicate extension 'y'"); } TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) { @@ -140,6 +170,17 @@ TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) { (RISCVISAUtils::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV32E.getXLen(), 32U); + auto MaybeRV32Y = RISCVISAInfo::parseNormalizedArchString("rv32y0p910"); + ASSERT_THAT_EXPECTED(MaybeRV32Y, Succeeded()); + RISCVISAInfo &InfoRV32Y = **MaybeRV32Y; + EXPECT_EQ(InfoRV32Y.getExtensions().size(), 2UL); + EXPECT_TRUE(InfoRV32Y.getExtensions().at("i") == + (RISCVISAUtils::ExtensionVersion{2, 1})); + EXPECT_TRUE(InfoRV32Y.getExtensions().at("y") == + (RISCVISAUtils::ExtensionVersion{0, 910})); + EXPECT_EQ(InfoRV32Y.getXLen(), 32U); + EXPECT_EQ(InfoRV32Y.toString(), "rv32y0p910"); + auto MaybeRV64I = RISCVISAInfo::parseNormalizedArchString("rv64i2p0"); ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded()); RISCVISAInfo &InfoRV64I = **MaybeRV64I; @@ -155,6 +196,17 @@ TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) { EXPECT_TRUE(InfoRV64E.getExtensions().at("e") == (RISCVISAUtils::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV64E.getXLen(), 64U); + + auto MaybeRV64Y = RISCVISAInfo::parseNormalizedArchString("rv64y0p910"); + ASSERT_THAT_EXPECTED(MaybeRV64Y, Succeeded()); + RISCVISAInfo &InfoRV64Y = **MaybeRV64Y; + EXPECT_EQ(InfoRV64Y.getExtensions().size(), 2UL); + EXPECT_TRUE(InfoRV64Y.getExtensions().at("i") == + (RISCVISAUtils::ExtensionVersion{2, 1})); + EXPECT_TRUE(InfoRV64Y.getExtensions().at("y") == + (RISCVISAUtils::ExtensionVersion{0, 910})); + EXPECT_EQ(InfoRV64Y.getXLen(), 64U); + EXPECT_EQ(InfoRV64Y.toString(), "rv64y0p910"); } TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) { @@ -189,10 +241,10 @@ TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) { TEST(ParseNormalizedArchString, AcceptsUnknownMultiletter) { auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString( - "rv64i2p0_f2p0_d2p0_zicsr2p0_ykk1p0"); + "rv64i2p0_f2p0_d2p0_zicsr2p0_wkk1p0"); ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo &Info = **MaybeISAInfo; - EXPECT_EQ(Info.toString(), "rv64i2p0_f2p0_d2p0_zicsr2p0_ykk1p0"); + EXPECT_EQ(Info.toString(), "rv64i2p0_f2p0_d2p0_zicsr2p0_wkk1p0"); } TEST(ParseArchString, RejectsInvalidChars) { @@ -244,20 +296,24 @@ TEST(ParseArchString, RejectsInvalidBaseISA) { } TEST(ParseArchString, RejectsInvalidYPosition) { - // y in non-first position is rejected. + // 'y' is only allowed as a base ISA ('rv32y' or 'rv64y'). Anything else + // should be rejected as an invalid extension. for (StringRef Input : - {"rv32ey0p910", "rv64ey0p910", "rv32iy0p910", "rv64iy0p910"}) { + {"rv32ey0p910", "rv64ey0p910", "rv32iy0p910", "rv64iy0p910", + "rv32gy0p910", "rv64gy0p910", "rv32imy0p910", "rv64imy0p910", + "rv32i2p1_y0p910", "rv32i_m_y0p910", "rv64y0p910_y0p910"}) { EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), "invalid standard user-level extension 'y'"); } - for (StringRef Input : {"rv32ey", "rv64ey", "rv32iy", "rv64iy"}) { + for (StringRef Input : {"rv32ey", "rv64ey", "rv32iy", "rv64iy", "rv32gy", + "rv64gy", "rv32imy", "rv64imy", "rv32yy", "rv64yy"}) { EXPECT_EQ( toString(RISCVISAInfo::parseArchString(Input, true, false).takeError()), "invalid standard user-level extension 'y'"); } } -TEST(ParseArchString, MissingBaseISA) { +TEST(ParseArchString, AcceptsRVYBaseISA) { // With version check enabled (default), we must specify the version for // experimental extension 'y'. auto MaybeRV32Y = RISCVISAInfo::parseArchString("rv32y0p910", true); @@ -268,8 +324,10 @@ TEST(ParseArchString, MissingBaseISA) { EXPECT_TRUE(ExtsRV32Y.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); EXPECT_TRUE(ExtsRV32Y.at("y") == (RISCVISAUtils::ExtensionVersion{0, 910})); EXPECT_EQ(InfoRV32Y.getXLen(), 32U); + EXPECT_EQ(InfoRV32Y.toString(), "rv32y0p910"); - // rv32y0p910m should succeed and contain i, m, y0p910, zmmul + // rv32y0p910m should succeed and contain i, m, y0p910, zmmul, with 'i' + // omitted and 'y' ordered before 'm', round-tripping through both parsers. auto MaybeRV32YM = RISCVISAInfo::parseArchString("rv32y0p910m", true); ASSERT_THAT_EXPECTED(MaybeRV32YM, Succeeded()); RISCVISAInfo &InfoRV32YM = **MaybeRV32YM; @@ -280,11 +338,19 @@ TEST(ParseArchString, MissingBaseISA) { (RISCVISAUtils::ExtensionVersion{2, 0})); EXPECT_TRUE(InfoRV32YM.getExtensions().at("y") == (RISCVISAUtils::ExtensionVersion{0, 910})); + std::string RV32YMStr = InfoRV32YM.toString(); + EXPECT_EQ(RV32YMStr, "rv32y0p910_m2p0_zmmul1p0"); + auto RoundTripArch = RISCVISAInfo::parseArchString(RV32YMStr, true); + ASSERT_THAT_EXPECTED(RoundTripArch, Succeeded()); + EXPECT_EQ((*RoundTripArch)->toString(), RV32YMStr); + auto RoundTripNorm = RISCVISAInfo::parseNormalizedArchString(RV32YMStr); + ASSERT_THAT_EXPECTED(RoundTripNorm, Succeeded()); + EXPECT_EQ((*RoundTripNorm)->toString(), RV32YMStr); // We can also parse it without version if we disable the version check. - auto MaybeRV32YNoVal = RISCVISAInfo::parseArchString("rv32y", true, false); - ASSERT_THAT_EXPECTED(MaybeRV32YNoVal, Succeeded()); - EXPECT_EQ((*MaybeRV32YNoVal)->getExtensions().size(), 2UL); + auto MaybeNoVal = RISCVISAInfo::parseArchString("rv32y", true, false); + ASSERT_THAT_EXPECTED(MaybeNoVal, Succeeded()); + EXPECT_EQ((*MaybeNoVal)->getExtensions().size(), 2UL); auto MaybeRV64Y = RISCVISAInfo::parseArchString("rv64y0p910", true); ASSERT_THAT_EXPECTED(MaybeRV64Y, Succeeded()); @@ -294,6 +360,7 @@ TEST(ParseArchString, MissingBaseISA) { EXPECT_TRUE(ExtsRV64Y.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); EXPECT_TRUE(ExtsRV64Y.at("y") == (RISCVISAUtils::ExtensionVersion{0, 910})); EXPECT_EQ(InfoRV64Y.getXLen(), 64U); + EXPECT_EQ(InfoRV64Y.toString(), "rv64y0p910"); } TEST(ParseArchString, RejectsUnsupportedBaseISA) { @@ -1036,10 +1103,10 @@ TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) { for (const auto &Ext : Exts) ExtNames.push_back(Ext.first); - // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'. + // FIXME: 'l' should be ordered after 'i', 'm', 'c'. EXPECT_THAT(ExtNames, - ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx", - "zzfoo", "sbar", "sfoo", "xbar", "xfoo")); + ElementsAre("i", "y", "m", "l", "c", "zicsr", "zmfoo", "zfinx", + "zzfoo", "sbar", "sfoo", "xbar", "xfoo")); } TEST(ParseArchString, ZceImplication) { @@ -1705,8 +1772,8 @@ R"(All available -march extensions for RISC-V xwchc 2.2 Experimental extensions - p 0.21 y 0.910 + p 0.21 zibi 0.1 zicfilp 1.0 This is a long dummy description zilx 0.1 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
