[llvm] [RISC-V][RVY] Initial ISAInfo support for RVY (PR #201931)
Alexander Richardson via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 6 11:44:23 PDT 2026
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/201931
>From 07852a54eb40726f0659f276079e9000da16e600 Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Fri, 5 Jun 2026 13:21:37 -0700
Subject: [PATCH 1/2] =?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
---
llvm/lib/TargetParser/RISCVISAInfo.cpp | 82 +++++--
.../TargetParser/RISCVISAInfoTest.cpp | 200 ++++++++++++++++--
2 files changed, 252 insertions(+), 30 deletions(-)
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 7b04b42f8d000..363ae4148a621 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -593,7 +593,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
if (XLen == 0 || Arch.empty())
return getError(
- "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
+ "string must begin with rv32{i,e,g,y}, rv64{i,e,g,y}, or a supported "
"profile name");
std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
@@ -606,11 +606,11 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
unsigned Major, Minor, ConsumeLength;
- // First letter should be 'e', 'i' or 'g'.
+ // First letter should be 'e', 'i', 'g' or 'y'.
switch (Baseline) {
default:
return getError("first letter after \'rv" + Twine(XLen) +
- "\' should be 'e', 'i' or 'g'");
+ "\' should be 'e', 'i', 'g' or 'y'");
case 'e':
case 'i':
// Baseline is `i` or `e`
@@ -621,6 +621,23 @@ 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};
+ if (auto IVersion = findDefaultVersion("i")) {
+ ISAInfo->Exts["i"] = {IVersion->Major, IVersion->Minor};
+ } else {
+ llvm_unreachable("Default 'i' extension version not found?");
+ }
+ break;
case 'g':
// g expands to extensions in RISCVGImplications.
if (!Arch.empty() && isDigit(Arch.front()))
@@ -730,6 +747,10 @@ static Error getIncompatibleError(StringRef Ext1, StringRef Ext2) {
"' extensions are incompatible");
}
+static Error getBaseIncompatibleError(StringRef Ext, StringRef Base) {
+ return getError("'" + Ext + "' is incompatible with " + Base + " base");
+}
+
static Error getExtensionRequiresError(StringRef Ext, StringRef ReqExt) {
return getError("'" + Ext + "' requires '" + ReqExt +
"' extension to also be specified");
@@ -795,6 +816,20 @@ Error RISCVISAInfo::checkDependency() {
if (Exts.count("zclsd") != 0 && Exts.count("zcf") != 0)
return getIncompatibleError("zclsd", "zcf");
+ if (Exts.count("y") != 0) {
+ if (XLen == 32) {
+ // On RVY32 systems the zclsd/zcf encodings are used for y load/stores.
+ if (Exts.count("zclsd") != 0)
+ return getBaseIncompatibleError("zclsd", "rv32y");
+ if (Exts.count("zcf") != 0)
+ return getBaseIncompatibleError("zcf", "rv32y");
+ } else {
+ // On RVY64 systems the zcd encodings are used for y load/stores.
+ if (Exts.count("zcd") != 0)
+ return getBaseIncompatibleError("zcd", "rv64y");
+ }
+ }
+
if (HasZcmp && HasXqccmp)
return getIncompatibleError("zcmp", "xqccmp");
@@ -848,21 +883,23 @@ void RISCVISAInfo::updateImplication() {
}
}
- // Add Zcd if C and D are enabled.
- if (Exts.count("c") && Exts.count("d") && !Exts.count("zcd")) {
+ // Add Zcd if C and D are enabled and we aren't targeting 64-bit RVY.
+ if (Exts.count("c") && Exts.count("d") && !Exts.count("zcd") &&
+ (XLen == 32 || !Exts.count("y"))) {
auto Version = findDefaultVersion("zcd");
Exts["zcd"] = *Version;
}
- // Add Zcf if C and F are enabled on RV32.
- if (XLen == 32 && Exts.count("c") && Exts.count("f") && !Exts.count("zcf")) {
+ // Add Zcf if C and F are enabled on RV32 and Y is not enabled.
+ if (XLen == 32 && Exts.count("c") && Exts.count("f") && !Exts.count("zcf") &&
+ !Exts.count("y")) {
auto Version = findDefaultVersion("zcf");
Exts["zcf"] = *Version;
}
- // Add Zcf if Zce and F are enabled on RV32.
+ // Add Zcf if Zce and F are enabled on RV32 and Y is not enabled.
if (XLen == 32 && Exts.count("zce") && Exts.count("f") &&
- !Exts.count("zcf")) {
+ !Exts.count("zcf") && !Exts.count("y")) {
auto Version = findDefaultVersion("zcf");
Exts["zcf"] = *Version;
}
@@ -877,18 +914,24 @@ void RISCVISAInfo::updateImplication() {
// For RV64:
// - No D: Zca alone implies C
// - D: Zca + Zcd implies C
+ // For RV32Y (Zcf incompatible):
+ // - No D (but maybe F): Zca alone implies C
+ // - F and D: Zca + Zcd implies C
+ // For RV64Y (Zcf and Zcd incompatible):
+ // - Zca alone implies C
if (Exts.count("zca") && !Exts.count("c")) {
bool ShouldAddC = false;
if (XLen == 32) {
if (Exts.count("d"))
- ShouldAddC = Exts.count("zcf") && Exts.count("zcd");
+ ShouldAddC =
+ Exts.count("zcd") && (Exts.count("y") || Exts.count("zcf"));
else if (Exts.count("f"))
- ShouldAddC = Exts.count("zcf");
+ ShouldAddC = Exts.count("y") || Exts.count("zcf");
else
ShouldAddC = true;
} else if (XLen == 64) {
if (Exts.count("d"))
- ShouldAddC = Exts.count("zcd");
+ ShouldAddC = Exts.count("y") || Exts.count("zcd");
else
ShouldAddC = true;
}
@@ -898,13 +941,16 @@ void RISCVISAInfo::updateImplication() {
}
}
- if (!Exts.count("zce") && Exts.count("zca") && Exts.count("zcb") &&
- Exts.count("zcmp") && Exts.count("zcmt")) {
+ if (!Exts.count("zce") && Exts.count("zca") && Exts.count("zcb")) {
bool ShouldAddZce = false;
- if (XLen == 32) {
- ShouldAddZce = !Exts.count("f") || Exts.count("zcf");
- } else if (XLen == 64) {
- ShouldAddZce = true;
+ if (Exts.count("zcmp") && Exts.count("zcmt")) {
+ if (XLen == 32) {
+ ShouldAddZce = !Exts.count("f") || Exts.count("zcf") || Exts.count("y");
+ } else if (XLen == 64) {
+ ShouldAddZce = true;
+ }
+ } else if (Exts.count("y") && XLen == 64) {
+ ShouldAddZce = true; // For RV64Y only Zce only includes Zca and Zcb
}
if (ShouldAddZce)
Exts["zce"] = *findDefaultVersion("zce");
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 9e7f23e2b4f76..5e32d56d89d28 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -172,25 +172,104 @@ TEST(ParseArchString, RejectsInvalidChars) {
TEST(ParseArchString, RejectsInvalidBaseISA) {
for (StringRef Input : {"rv32", "rv64", "rv65i"}) {
- EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
- "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
- "profile name");
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "string must begin with rv32{i,e,g,y}, rv64{i,e,g,y}, or a supported "
+ "profile name");
}
for (StringRef Input : {"rv32j", "rv32_i"}) {
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
- "first letter after 'rv32' should be 'e', 'i' or 'g'");
+ "first letter after 'rv32' should be 'e', 'i', 'g' or 'y'");
}
EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64k", true).takeError()),
- "first letter after 'rv64' should be 'e', 'i' or 'g'");
+ "first letter after 'rv64' should be 'e', 'i', 'g' or 'y'");
+
+ // rv32yi/ye fail because rv32y implicitly enables i, and i/e are not valid
+ // extensions to follow it.
+ for (StringRef Input : {"rv32yi", "rv64yi"}) {
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseArchString(Input, true, false).takeError()),
+ "invalid standard user-level extension 'i'");
+ }
+ // TODO: arch string syntax for RVE+RVY (and y in non-first position) will be
+ // included following conclusion of
+ // https://lists.riscv.org/g/tech-unprivileged/message/1134
+ for (StringRef Input : {"rv32ye", "rv64ye"}) {
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseArchString(Input, true, false).takeError()),
+ "invalid standard user-level extension 'e'");
+ }
+ for (StringRef Input : {"rv32y0p98i", "rv64y0p98i"}) {
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "invalid standard user-level extension 'i'");
+ }
+ for (StringRef Input : {"rv32y0p98e", "rv64y0p98e"}) {
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "invalid standard user-level extension 'e'");
+ }
+}
+
+TEST(ParseArchString, RejectsInvalidYPosition) {
+ // y in non-first position is rejected.
+ for (StringRef Input :
+ {"rv32ey0p98", "rv64ey0p98", "rv32iy0p98", "rv64iy0p98"}) {
+ EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "invalid standard user-level extension 'y'");
+ }
+ for (StringRef Input : {"rv32ey", "rv64ey", "rv32iy", "rv64iy"}) {
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseArchString(Input, true, false).takeError()),
+ "invalid standard user-level extension 'y'");
+ }
+}
+
+TEST(ParseArchString, MissingBaseISA) {
+ // With version check enabled (default), we must specify the version for
+ // experimental extension 'y'.
+ auto MaybeRV32Y = RISCVISAInfo::parseArchString("rv32y0p98", true);
+ ASSERT_THAT_EXPECTED(MaybeRV32Y, Succeeded());
+ RISCVISAInfo &InfoRV32Y = **MaybeRV32Y;
+ const auto &ExtsRV32Y = InfoRV32Y.getExtensions();
+ EXPECT_EQ(ExtsRV32Y.size(), 2UL); // i, y
+ EXPECT_TRUE(ExtsRV32Y.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
+ EXPECT_TRUE(ExtsRV32Y.at("y") == (RISCVISAUtils::ExtensionVersion{0, 98}));
+ EXPECT_EQ(InfoRV32Y.getXLen(), 32U);
+
+ // rv32y0p98m should succeed and contain i, m, y0p98, zmmul
+ auto MaybeRV32YM = RISCVISAInfo::parseArchString("rv32y0p98m", true);
+ ASSERT_THAT_EXPECTED(MaybeRV32YM, Succeeded());
+ RISCVISAInfo &InfoRV32YM = **MaybeRV32YM;
+ EXPECT_EQ(InfoRV32YM.getExtensions().size(), 4UL); // i, m, y, zmmul
+ EXPECT_TRUE(InfoRV32YM.getExtensions().at("i") ==
+ (RISCVISAUtils::ExtensionVersion{2, 1}));
+ EXPECT_TRUE(InfoRV32YM.getExtensions().at("m") ==
+ (RISCVISAUtils::ExtensionVersion{2, 0}));
+ EXPECT_TRUE(InfoRV32YM.getExtensions().at("y") ==
+ (RISCVISAUtils::ExtensionVersion{0, 98}));
+
+ // 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 MaybeRV64Y = RISCVISAInfo::parseArchString("rv64y0p98", true);
+ ASSERT_THAT_EXPECTED(MaybeRV64Y, Succeeded());
+ RISCVISAInfo &InfoRV64Y = **MaybeRV64Y;
+ const auto &ExtsRV64Y = InfoRV64Y.getExtensions();
+ EXPECT_EQ(ExtsRV64Y.size(), 2UL); // i, y
+ EXPECT_TRUE(ExtsRV64Y.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
+ EXPECT_TRUE(ExtsRV64Y.at("y") == (RISCVISAUtils::ExtensionVersion{0, 98}));
+ EXPECT_EQ(InfoRV64Y.getXLen(), 64U);
}
TEST(ParseArchString, RejectsUnsupportedBaseISA) {
for (StringRef Input : {"rv128i", "rv128g"}) {
- EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
- "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
- "profile name");
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "string must begin with rv32{i,e,g,y}, rv64{i,e,g,y}, or a supported "
+ "profile name");
}
}
@@ -479,7 +558,7 @@ TEST(ParseArchString, AcceptsAmbiguousFromRelaxExtensions) {
TEST(ParseArchString, RejectsRelaxExtensionsNotStartWithEorIorG) {
EXPECT_EQ(
toString(RISCVISAInfo::parseArchString("rv32zba_im", true).takeError()),
- "first letter after 'rv32' should be 'e', 'i' or 'g'");
+ "first letter after 'rv32' should be 'e', 'i', 'g' or 'y'");
}
TEST(ParseArchString,
@@ -581,6 +660,10 @@ TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) {
toString(RISCVISAInfo::parseArchString("rv64izibi9p9", true).takeError()),
"unsupported version number 9.9 for experimental extension 'zibi' "
"(this compiler supports 0.1)");
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseArchString("rv64y0p97", true).takeError()),
+ "unsupported version number 0.97 for experimental extension 'y' "
+ "(this compiler supports 0.98)");
}
TEST(ParseArchString, RejectsExtensionVersionForG) {
@@ -674,6 +757,18 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
EXPECT_THAT(Error, ::testing::EndsWith("' is only supported for 'rv32'"));
EXPECT_THAT(Error, ::testing::HasSubstr(ConflictingExt));
}
+ EXPECT_EQ(
+ toString(
+ RISCVISAInfo::parseArchString("rv32y0p98_zcf", true).takeError()),
+ "'zcf' is incompatible with rv32y base");
+ EXPECT_EQ(
+ toString(
+ RISCVISAInfo::parseArchString("rv32y0p98_zclsd", true).takeError()),
+ "'zclsd' is incompatible with rv32y base");
+ EXPECT_EQ(
+ toString(
+ RISCVISAInfo::parseArchString("rv64y0p98_zcd", true).takeError()),
+ "'zcd' is incompatible with rv64y base");
// In these ISA strings, the non-zcd extension should be last, after an
// underscore.
@@ -740,9 +835,10 @@ TEST(ParseArchString, MissingDepency) {
TEST(ParseArchString, RejectsUnrecognizedProfileNames) {
for (StringRef Input : {"rvi23u99", "rvz23u64", "rva99u32"}) {
- EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
- "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
- "profile name");
+ EXPECT_EQ(
+ toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+ "string must begin with rv32{i,e,g,y}, rv64{i,e,g,y}, or a supported "
+ "profile name");
}
}
@@ -1028,6 +1124,51 @@ TEST(ParseArchString, ZcaImpliesC) {
EXPECT_EQ(ExtsRV64IDZca.count("c"), 0U);
}
+TEST(ParseArchString, RVYZcaImpliesC) {
+ // RV32Y without D (maybe with F): Zca implies C (Zcf opcodes remapped in Y).
+ for (StringRef Input : {"rv32y_zca", "rv32yf_zca"}) {
+ auto ISAInfo = RISCVISAInfo::parseArchString(Input, true, false);
+ ASSERT_THAT_EXPECTED(ISAInfo, Succeeded());
+ const auto &Exts = (*ISAInfo)->getExtensions();
+ EXPECT_EQ(Exts.count("c"), 1U);
+ EXPECT_EQ(Exts.count("zca"), 1U);
+ EXPECT_EQ(Exts.count("zcf"), 0U);
+ EXPECT_EQ(Exts.count("zcd"), 0U);
+ }
+ // RV32Y with D: Zca+Zcd implies C (Zcf opcodes remapped in Y)
+ for (StringRef Input : {"rv32yfd_zca_zcd"}) {
+ auto MaybeRV32YDZcaZcd = RISCVISAInfo::parseArchString(Input, true, false);
+ ASSERT_THAT_EXPECTED(MaybeRV32YDZcaZcd, Succeeded());
+ const auto &ExtsRV32YDZcaZcd = (*MaybeRV32YDZcaZcd)->getExtensions();
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("c"), 1U);
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("zca"), 1U);
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("zcf"), 0U);
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("zcd"), 1U);
+ }
+ // RV32Y with D but no Zcd: no C
+ for (StringRef Input : {"rv32yfd_zca"}) {
+ auto MaybeRV32YDZcaZcd = RISCVISAInfo::parseArchString(Input, true, false);
+ ASSERT_THAT_EXPECTED(MaybeRV32YDZcaZcd, Succeeded());
+ const auto &ExtsRV32YDZcaZcd = (*MaybeRV32YDZcaZcd)->getExtensions();
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("c"), 0U);
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("zca"), 1U);
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("zcf"), 0U);
+ EXPECT_EQ(ExtsRV32YDZcaZcd.count("zcd"), 0U);
+ }
+
+ // RV64Y: Zca always implies C (regardless of F/D) since Zcf opcodes are
+ // repurposed for 64-bit loads/stores and Zcd for capability loads/stores.
+ for (StringRef Input : {"rv64y_zca", "rv64yf_zca", "rv64yfd_zca"}) {
+ auto ISAInfo = RISCVISAInfo::parseArchString(Input, true, false);
+ ASSERT_THAT_EXPECTED(ISAInfo, Succeeded());
+ const auto &Exts = (*ISAInfo)->getExtensions();
+ EXPECT_EQ(Exts.count("c"), 1U);
+ EXPECT_EQ(Exts.count("zca"), 1U);
+ EXPECT_EQ(Exts.count("zcf"), 0U);
+ EXPECT_EQ(Exts.count("zcd"), 0U);
+ }
+}
+
TEST(ParseArchString, ZcaZcbZcmpZcmtImpliesZce) {
// Test Zca+Zcb+Zcmp+Zcmt implies Zce behavior.
@@ -1112,6 +1253,41 @@ TEST(ParseArchString, ZcaZcbZcmpZcmtImpliesZce) {
EXPECT_EQ(ExtsRV64IFZcaZcbZcmpZcmt.count("zce"), 1U);
EXPECT_EQ(ExtsRV64IFZcaZcbZcmpZcmt.count("zcmp"), 1U);
EXPECT_EQ(ExtsRV64IFZcaZcbZcmpZcmt.count("zcmt"), 1U);
+
+ // RV32Y Zca+Zcb+Zcmp+Zcmt implies Zce regardless of F (Zcf incompatible)
+ for (StringRef Input : {"rv32y_zca_zcb_zcmp_zcmt", "rv32yf_zca_zcb_zcmp_zcmt",
+ "rv32yfd_zca_zcb_zcmp_zcmt"}) {
+ auto ISAInfo = RISCVISAInfo::parseArchString(Input, true, false);
+ ASSERT_THAT_EXPECTED(ISAInfo, Succeeded());
+ const auto &Exts = (*ISAInfo)->getExtensions();
+ EXPECT_EQ(Exts.count("i"), 1U);
+ EXPECT_EQ(Exts.count("y"), 1U);
+ EXPECT_EQ(Exts.count("c"), !Exts.count("d")); // Zcd missing
+ EXPECT_EQ(Exts.count("zicsr"), 1U);
+ EXPECT_EQ(Exts.count("zca"), 1U);
+ EXPECT_EQ(Exts.count("zcb"), 1U);
+ EXPECT_EQ(Exts.count("zce"), 1U);
+ EXPECT_EQ(Exts.count("zcmp"), 1U);
+ EXPECT_EQ(Exts.count("zcmt"), 1U);
+ EXPECT_EQ(Exts.size(), 9UL + Exts.count("f"));
+ }
+ // RV64Y Zca+Zcb implies Zce regardless of F (Zcf+Zcmp+Zcmt incompatible)
+ for (StringRef Input :
+ {"rv64y_zca_zcb", "rv64yf_zca_zcb", "rv64yfd_zca_zcb"}) {
+ auto ISAInfo = RISCVISAInfo::parseArchString(Input, true, false);
+ ASSERT_THAT_EXPECTED(ISAInfo, Succeeded());
+ const auto &Exts = (*ISAInfo)->getExtensions();
+ EXPECT_EQ(Exts.count("i"), 1U);
+ EXPECT_EQ(Exts.count("y"), 1U);
+ EXPECT_EQ(Exts.count("c"), 1U);
+ EXPECT_EQ(Exts.count("zicsr"), Exts.count("f"));
+ EXPECT_EQ(Exts.count("zca"), 1U);
+ EXPECT_EQ(Exts.count("zcb"), 1U);
+ EXPECT_EQ(Exts.count("zce"), 1U);
+ EXPECT_EQ(Exts.count("zcmp"), 0U);
+ EXPECT_EQ(Exts.count("zcmt"), 0U);
+ EXPECT_EQ(Exts.size(), 6UL + Exts.count("d") + 2 * Exts.count("f"));
+ }
}
TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) {
>From 62889d409f21b5d4cfe1dd8c7d0debc882c1b306 Mon Sep 17 00:00:00 2001
From: Alexander Richardson <alexrichardson at google.com>
Date: Sat, 6 Jun 2026 11:44:14 -0700
Subject: [PATCH 2/2] Update llvm/lib/TargetParser/RISCVISAInfo.cpp
Co-authored-by: Craig Topper <craig.topper at sifive.com>
---
llvm/lib/TargetParser/RISCVISAInfo.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 363ae4148a621..09bbf7cd93a10 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -632,11 +632,9 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
return std::move(E);
ISAInfo->Exts["y"] = {Major, Minor};
- if (auto IVersion = findDefaultVersion("i")) {
- ISAInfo->Exts["i"] = {IVersion->Major, IVersion->Minor};
- } else {
- llvm_unreachable("Default 'i' extension version not found?");
- }
+ 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.
More information about the llvm-commits
mailing list