xref: /llvm-project/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (revision 2c209957819328481554e7c5929d134502b4972a)
1 //===-- unittests/RISCVISAInfoTest.cpp ------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/TargetParser/RISCVISAInfo.h"
10 #include "llvm/ADT/StringMap.h"
11 #include "llvm/Testing/Support/Error.h"
12 #include "gtest/gtest.h"
13 
14 using ::testing::ElementsAre;
15 
16 using namespace llvm;
17 
18 bool operator==(const RISCVISAUtils::ExtensionVersion &A,
19                 const RISCVISAUtils::ExtensionVersion &B) {
20   return A.Major == B.Major && A.Minor == B.Minor;
21 }
22 
23 TEST(ParseNormalizedArchString, RejectsInvalidChars) {
24   for (StringRef Input :
25        {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0", "rv32e2.0"}) {
26     EXPECT_EQ(
27         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
28         "string may only contain [a-z0-9_]");
29   }
30 }
31 
32 TEST(ParseNormalizedArchString, RejectsInvalidBaseISA) {
33   for (StringRef Input : {"rv32", "rv64", "rv32j", "rv65i"}) {
34     EXPECT_EQ(
35         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
36         "arch string must begin with valid base ISA");
37   }
38 }
39 
40 TEST(ParseNormalizedArchString, RejectsMalformedInputs) {
41   for (StringRef Input :
42        {"rv64i2p0_", "rv32i2p0__a2p0", "rv64e2p", "rv32i", "rv64ip1"}) {
43     EXPECT_EQ(
44         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
45         "extension lacks version in expected format");
46   }
47 }
48 
49 TEST(ParseNormalizedArchString, RejectsOnlyVersion) {
50   for (StringRef Input : {"rv64i2p0_1p0", "rv32i2p0_1p0"}) {
51     EXPECT_EQ(
52         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
53         "missing extension name");
54   }
55 }
56 
57 TEST(ParseNormalizedArchString, RejectsBadZ) {
58   for (StringRef Input : {"rv64i2p0_z1p0", "rv32i2p0_z2a1p0"}) {
59     EXPECT_EQ(
60         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
61         "'z' must be followed by a letter");
62   }
63 }
64 
65 TEST(ParseNormalizedArchString, RejectsBadS) {
66   for (StringRef Input : {"rv64i2p0_s1p0", "rv32i2p0_s2a1p0"}) {
67     EXPECT_EQ(
68         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
69         "'s' must be followed by a letter");
70   }
71 }
72 
73 TEST(ParseNormalizedArchString, RejectsBadX) {
74   for (StringRef Input : {"rv64i2p0_x1p0", "rv32i2p0_x2a1p0"}) {
75     EXPECT_EQ(
76         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
77         "'x' must be followed by a letter");
78   }
79 }
80 
81 TEST(ParseNormalizedArchString, DuplicateExtension) {
82   for (StringRef Input : {"rv64i2p0_a2p0_a1p0"}) {
83     EXPECT_EQ(
84         toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()),
85         "duplicate extension 'a'");
86   }
87 }
88 
89 TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) {
90   auto MaybeRV32I = RISCVISAInfo::parseNormalizedArchString("rv32i2p0");
91   ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded());
92   RISCVISAInfo &InfoRV32I = **MaybeRV32I;
93   EXPECT_EQ(InfoRV32I.getExtensions().size(), 1UL);
94   EXPECT_TRUE(InfoRV32I.getExtensions().at("i") ==
95               (RISCVISAUtils::ExtensionVersion{2, 0}));
96   EXPECT_EQ(InfoRV32I.getXLen(), 32U);
97 
98   auto MaybeRV32E = RISCVISAInfo::parseNormalizedArchString("rv32e2p0");
99   ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded());
100   RISCVISAInfo &InfoRV32E = **MaybeRV32E;
101   EXPECT_EQ(InfoRV32E.getExtensions().size(), 1UL);
102   EXPECT_TRUE(InfoRV32E.getExtensions().at("e") ==
103               (RISCVISAUtils::ExtensionVersion{2, 0}));
104   EXPECT_EQ(InfoRV32E.getXLen(), 32U);
105 
106   auto MaybeRV64I = RISCVISAInfo::parseNormalizedArchString("rv64i2p0");
107   ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded());
108   RISCVISAInfo &InfoRV64I = **MaybeRV64I;
109   EXPECT_EQ(InfoRV64I.getExtensions().size(), 1UL);
110   EXPECT_TRUE(InfoRV64I.getExtensions().at("i") ==
111               (RISCVISAUtils::ExtensionVersion{2, 0}));
112   EXPECT_EQ(InfoRV64I.getXLen(), 64U);
113 
114   auto MaybeRV64E = RISCVISAInfo::parseNormalizedArchString("rv64e2p0");
115   ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded());
116   RISCVISAInfo &InfoRV64E = **MaybeRV64E;
117   EXPECT_EQ(InfoRV64E.getExtensions().size(), 1UL);
118   EXPECT_TRUE(InfoRV64E.getExtensions().at("e") ==
119               (RISCVISAUtils::ExtensionVersion{2, 0}));
120   EXPECT_EQ(InfoRV64E.getXLen(), 64U);
121 }
122 
123 TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) {
124   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
125       "rv64i5p1_m3p2_zmadeup11p12_sfoo2p0_xbar3p0");
126   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
127   RISCVISAInfo &Info = **MaybeISAInfo;
128   EXPECT_EQ(Info.getExtensions().size(), 5UL);
129   EXPECT_TRUE(Info.getExtensions().at("i") ==
130               (RISCVISAUtils::ExtensionVersion{5, 1}));
131   EXPECT_TRUE(Info.getExtensions().at("m") ==
132               (RISCVISAUtils::ExtensionVersion{3, 2}));
133   EXPECT_TRUE(Info.getExtensions().at("zmadeup") ==
134               (RISCVISAUtils::ExtensionVersion{11, 12}));
135   EXPECT_TRUE(Info.getExtensions().at("sfoo") ==
136               (RISCVISAUtils::ExtensionVersion{2, 0}));
137   EXPECT_TRUE(Info.getExtensions().at("xbar") ==
138               (RISCVISAUtils::ExtensionVersion{3, 0}));
139 }
140 
141 TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) {
142   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
143       "rv64i2p0_d2p0_zvl64b1p0_zve64d1p0");
144   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
145   RISCVISAInfo &Info = **MaybeISAInfo;
146   EXPECT_EQ(Info.getXLen(), 64U);
147   EXPECT_EQ(Info.getFLen(), 64U);
148   EXPECT_EQ(Info.getMinVLen(), 64U);
149   EXPECT_EQ(Info.getMaxELen(), 64U);
150   EXPECT_EQ(Info.getMaxELenFp(), 64U);
151 }
152 
153 TEST(ParseArchString, RejectsInvalidChars) {
154   for (StringRef Input : {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0"}) {
155     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
156               "string may only contain [a-z0-9_]");
157   }
158 }
159 
160 TEST(ParseArchString, RejectsInvalidBaseISA) {
161   for (StringRef Input : {"rv32", "rv64", "rv65i"}) {
162     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
163               "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
164               "profile name");
165   }
166 
167   for (StringRef Input : {"rv32j", "rv32_i"}) {
168     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
169               "first letter after 'rv32' should be 'e', 'i' or 'g'");
170   }
171 
172   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64k", true).takeError()),
173             "first letter after 'rv64' should be 'e', 'i' or 'g'");
174 }
175 
176 TEST(ParseArchString, RejectsUnsupportedBaseISA) {
177   for (StringRef Input : {"rv128i", "rv128g"}) {
178     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
179               "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
180               "profile name");
181   }
182 }
183 
184 TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) {
185   auto MaybeRV32I = RISCVISAInfo::parseArchString("rv32i", true);
186   ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded());
187   RISCVISAInfo &InfoRV32I = **MaybeRV32I;
188   const auto &ExtsRV32I = InfoRV32I.getExtensions();
189   EXPECT_EQ(ExtsRV32I.size(), 1UL);
190   EXPECT_TRUE(ExtsRV32I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
191   EXPECT_EQ(InfoRV32I.getXLen(), 32U);
192   EXPECT_EQ(InfoRV32I.getFLen(), 0U);
193   EXPECT_EQ(InfoRV32I.getMinVLen(), 0U);
194   EXPECT_EQ(InfoRV32I.getMaxELen(), 0U);
195   EXPECT_EQ(InfoRV32I.getMaxELenFp(), 0U);
196 
197   auto MaybeRV32E = RISCVISAInfo::parseArchString("rv32e", true);
198   ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded());
199   RISCVISAInfo &InfoRV32E = **MaybeRV32E;
200   const auto &ExtsRV32E = InfoRV32E.getExtensions();
201   EXPECT_EQ(ExtsRV32E.size(), 1UL);
202   EXPECT_TRUE(ExtsRV32E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
203   EXPECT_EQ(InfoRV32E.getXLen(), 32U);
204   EXPECT_EQ(InfoRV32E.getFLen(), 0U);
205   EXPECT_EQ(InfoRV32E.getMinVLen(), 0U);
206   EXPECT_EQ(InfoRV32E.getMaxELen(), 0U);
207   EXPECT_EQ(InfoRV32E.getMaxELenFp(), 0U);
208 
209   auto MaybeRV32G = RISCVISAInfo::parseArchString("rv32g", true);
210   ASSERT_THAT_EXPECTED(MaybeRV32G, Succeeded());
211   RISCVISAInfo &InfoRV32G = **MaybeRV32G;
212   const auto &ExtsRV32G = InfoRV32G.getExtensions();
213   EXPECT_EQ(ExtsRV32G.size(), 7UL);
214   EXPECT_TRUE(ExtsRV32G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
215   EXPECT_TRUE(ExtsRV32G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
216   EXPECT_TRUE(ExtsRV32G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
217   EXPECT_TRUE(ExtsRV32G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
218   EXPECT_TRUE(ExtsRV32G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
219   EXPECT_TRUE(ExtsRV32G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
220   EXPECT_TRUE(ExtsRV32G.at("zifencei") ==
221               (RISCVISAUtils::ExtensionVersion{2, 0}));
222   EXPECT_EQ(InfoRV32G.getXLen(), 32U);
223   EXPECT_EQ(InfoRV32G.getFLen(), 64U);
224   EXPECT_EQ(InfoRV32G.getMinVLen(), 0U);
225   EXPECT_EQ(InfoRV32G.getMaxELen(), 0U);
226   EXPECT_EQ(InfoRV32G.getMaxELenFp(), 0U);
227 
228   auto MaybeRV64I = RISCVISAInfo::parseArchString("rv64i", true);
229   ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded());
230   RISCVISAInfo &InfoRV64I = **MaybeRV64I;
231   const auto &ExtsRV64I = InfoRV64I.getExtensions();
232   EXPECT_EQ(ExtsRV64I.size(), 1UL);
233   EXPECT_TRUE(ExtsRV64I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
234   EXPECT_EQ(InfoRV64I.getXLen(), 64U);
235   EXPECT_EQ(InfoRV64I.getFLen(), 0U);
236   EXPECT_EQ(InfoRV64I.getMinVLen(), 0U);
237   EXPECT_EQ(InfoRV64I.getMaxELen(), 0U);
238   EXPECT_EQ(InfoRV64I.getMaxELenFp(), 0U);
239 
240   auto MaybeRV64E = RISCVISAInfo::parseArchString("rv64e", true);
241   ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded());
242   RISCVISAInfo &InfoRV64E = **MaybeRV64E;
243   const auto &ExtsRV64E = InfoRV64E.getExtensions();
244   EXPECT_EQ(ExtsRV64E.size(), 1UL);
245   EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
246   EXPECT_EQ(InfoRV64E.getXLen(), 64U);
247   EXPECT_EQ(InfoRV64E.getFLen(), 0U);
248   EXPECT_EQ(InfoRV64E.getMinVLen(), 0U);
249   EXPECT_EQ(InfoRV64E.getMaxELen(), 0U);
250   EXPECT_EQ(InfoRV64E.getMaxELenFp(), 0U);
251 
252   auto MaybeRV64G = RISCVISAInfo::parseArchString("rv64g", true);
253   ASSERT_THAT_EXPECTED(MaybeRV64G, Succeeded());
254   RISCVISAInfo &InfoRV64G = **MaybeRV64G;
255   const auto &ExtsRV64G = InfoRV64G.getExtensions();
256   EXPECT_EQ(ExtsRV64G.size(), 7UL);
257   EXPECT_TRUE(ExtsRV64G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
258   EXPECT_TRUE(ExtsRV64G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
259   EXPECT_TRUE(ExtsRV64G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
260   EXPECT_TRUE(ExtsRV64G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
261   EXPECT_TRUE(ExtsRV64G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
262   EXPECT_TRUE(ExtsRV64G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
263   EXPECT_TRUE(ExtsRV64G.at("zifencei") ==
264               (RISCVISAUtils::ExtensionVersion{2, 0}));
265   EXPECT_EQ(InfoRV64G.getXLen(), 64U);
266   EXPECT_EQ(InfoRV64G.getFLen(), 64U);
267   EXPECT_EQ(InfoRV64G.getMinVLen(), 0U);
268   EXPECT_EQ(InfoRV64G.getMaxELen(), 0U);
269   EXPECT_EQ(InfoRV64G.getMaxELenFp(), 0U);
270 
271   auto MaybeRV64GCV = RISCVISAInfo::parseArchString("rv64gcv", true);
272   ASSERT_THAT_EXPECTED(MaybeRV64GCV, Succeeded());
273   RISCVISAInfo &InfoRV64GCV = **MaybeRV64GCV;
274   const auto &ExtsRV64GCV = InfoRV64GCV.getExtensions();
275   EXPECT_EQ(ExtsRV64GCV.size(), 17UL);
276   EXPECT_TRUE(ExtsRV64GCV.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
277   EXPECT_TRUE(ExtsRV64GCV.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0}));
278   EXPECT_TRUE(ExtsRV64GCV.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1}));
279   EXPECT_TRUE(ExtsRV64GCV.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2}));
280   EXPECT_TRUE(ExtsRV64GCV.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2}));
281   EXPECT_TRUE(ExtsRV64GCV.at("c") == (RISCVISAUtils::ExtensionVersion{2, 0}));
282   EXPECT_TRUE(ExtsRV64GCV.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0}));
283   EXPECT_TRUE(ExtsRV64GCV.at("zifencei") ==
284               (RISCVISAUtils::ExtensionVersion{2, 0}));
285   EXPECT_TRUE(ExtsRV64GCV.at("v") == (RISCVISAUtils::ExtensionVersion{1, 0}));
286   EXPECT_TRUE(ExtsRV64GCV.at("zve32x") == (RISCVISAUtils::ExtensionVersion{1, 0}));
287   EXPECT_TRUE(ExtsRV64GCV.at("zve32f") == (RISCVISAUtils::ExtensionVersion{1, 0}));
288   EXPECT_TRUE(ExtsRV64GCV.at("zve64x") == (RISCVISAUtils::ExtensionVersion{1, 0}));
289   EXPECT_TRUE(ExtsRV64GCV.at("zve64f") == (RISCVISAUtils::ExtensionVersion{1, 0}));
290   EXPECT_TRUE(ExtsRV64GCV.at("zve64d") == (RISCVISAUtils::ExtensionVersion{1, 0}));
291   EXPECT_TRUE(ExtsRV64GCV.at("zvl32b") == (RISCVISAUtils::ExtensionVersion{1, 0}));
292   EXPECT_TRUE(ExtsRV64GCV.at("zvl64b") == (RISCVISAUtils::ExtensionVersion{1, 0}));
293   EXPECT_TRUE(ExtsRV64GCV.at("zvl128b") == (RISCVISAUtils::ExtensionVersion{1, 0}));
294   EXPECT_EQ(InfoRV64GCV.getXLen(), 64U);
295   EXPECT_EQ(InfoRV64GCV.getFLen(), 64U);
296   EXPECT_EQ(InfoRV64GCV.getMinVLen(), 128U);
297   EXPECT_EQ(InfoRV64GCV.getMaxELen(), 64U);
298   EXPECT_EQ(InfoRV64GCV.getMaxELenFp(), 64U);
299 }
300 
301 TEST(ParseArchString, RejectsUnrecognizedExtensionNamesByDefault) {
302   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ib", true).takeError()),
303             "unsupported standard user-level extension 'b'");
304   EXPECT_EQ(
305       toString(
306           RISCVISAInfo::parseArchString("rv32i_zmadeup", true).takeError()),
307       "unsupported standard user-level extension 'zmadeup'");
308   EXPECT_EQ(
309       toString(
310           RISCVISAInfo::parseArchString("rv64g_smadeup", true).takeError()),
311       "unsupported standard supervisor-level extension 'smadeup'");
312   EXPECT_EQ(
313       toString(
314           RISCVISAInfo::parseArchString("rv64g_xmadeup", true).takeError()),
315       "unsupported non-standard user-level extension 'xmadeup'");
316   EXPECT_EQ(
317       toString(RISCVISAInfo::parseArchString("rv64ib1p0", true).takeError()),
318       "unsupported standard user-level extension 'b'");
319   EXPECT_EQ(
320       toString(
321           RISCVISAInfo::parseArchString("rv32i_zmadeup1p0", true).takeError()),
322       "unsupported standard user-level extension 'zmadeup'");
323   EXPECT_EQ(
324       toString(
325           RISCVISAInfo::parseArchString("rv64g_smadeup1p0", true).takeError()),
326       "unsupported standard supervisor-level extension 'smadeup'");
327   EXPECT_EQ(
328       toString(
329           RISCVISAInfo::parseArchString("rv64g_xmadeup1p0", true).takeError()),
330       "unsupported non-standard user-level extension 'xmadeup'");
331 }
332 
333 TEST(ParseArchString, IgnoresUnrecognizedExtensionNamesWithIgnoreUnknown) {
334   for (StringRef Input : {"rv32ib", "rv32i_zmadeup",
335                           "rv64i_smadeup", "rv64i_xmadeup"}) {
336     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true);
337     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
338     RISCVISAInfo &Info = **MaybeISAInfo;
339     const auto &Exts = Info.getExtensions();
340     EXPECT_EQ(Exts.size(), 1UL);
341     EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
342   }
343 
344   // Checks that supported extensions aren't incorrectly ignored when a
345   // version is present (an early version of the patch had this mistake).
346   auto MaybeISAInfo =
347       RISCVISAInfo::parseArchString("rv32i_zbc1p0_xmadeup", true, false, true);
348   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
349   const auto &Exts = (*MaybeISAInfo)->getExtensions();
350   EXPECT_TRUE(Exts.at("zbc") == (RISCVISAUtils::ExtensionVersion{1, 0}));
351 }
352 
353 TEST(ParseArchString, AcceptsVersionInLongOrShortForm) {
354   for (StringRef Input : {"rv64i2p1"}) {
355     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
356     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
357     const auto &Exts = (*MaybeISAInfo)->getExtensions();
358     EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
359   }
360   for (StringRef Input : {"rv32i_zfinx1", "rv32i_zfinx1p0"}) {
361     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
362     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
363     const auto &Exts = (*MaybeISAInfo)->getExtensions();
364     EXPECT_TRUE(Exts.at("zfinx") == (RISCVISAUtils::ExtensionVersion{1, 0}));
365   }
366 }
367 
368 TEST(ParseArchString, RejectsUnrecognizedExtensionVersionsByDefault) {
369   EXPECT_EQ(
370       toString(RISCVISAInfo::parseArchString("rv64i2p", true).takeError()),
371       "minor version number missing after 'p' for extension 'i'");
372   EXPECT_EQ(
373       toString(RISCVISAInfo::parseArchString("rv64i1p0", true).takeError()),
374       "unsupported version number 1.0 for extension 'i'");
375   EXPECT_EQ(
376       toString(RISCVISAInfo::parseArchString("rv64i9p9", true).takeError()),
377       "unsupported version number 9.9 for extension 'i'");
378   EXPECT_EQ(
379       toString(RISCVISAInfo::parseArchString("rv32im0p1", true).takeError()),
380       "unsupported version number 0.1 for extension 'm'");
381   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32izifencei10p10", true)
382                          .takeError()),
383             "unsupported version number 10.10 for extension 'zifencei'");
384 }
385 
386 TEST(ParseArchString,
387      UsesDefaultVersionForUnrecognisedBaseISAVersionWithIgnoreUnknown) {
388   for (StringRef Input : {"rv32i0p1", "rv32i99p99", "rv64i0p1", "rv64i99p99"}) {
389     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true);
390     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
391     const auto &Exts = (*MaybeISAInfo)->getExtensions();
392     EXPECT_EQ(Exts.size(), 1UL);
393     EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
394   }
395   for (StringRef Input : {"rv32e0p1", "rv32e99p99", "rv64e0p1", "rv64e99p99"}) {
396     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true);
397     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
398     const auto &Exts = (*MaybeISAInfo)->getExtensions();
399     EXPECT_EQ(Exts.size(), 1UL);
400     EXPECT_TRUE(Exts.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0}));
401   }
402 }
403 
404 TEST(ParseArchString,
405      IgnoresExtensionsWithUnrecognizedVersionsWithIgnoreUnknown) {
406   for (StringRef Input : {"rv32im1p1", "rv64i_svnapot10p9", "rv32i_zicsr0p5"}) {
407     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true);
408     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
409     const auto &Exts = (*MaybeISAInfo)->getExtensions();
410     EXPECT_EQ(Exts.size(), 1UL);
411     EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1}));
412   }
413 }
414 
415 TEST(ParseArchString, AcceptsUnderscoreSplittingExtensions) {
416   for (StringRef Input : {"rv32imafdczifencei", "rv32i_m_a_f_d_c_zifencei"}) {
417     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
418     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
419     const auto &Exts = (*MaybeISAInfo)->getExtensions();
420     EXPECT_EQ(Exts.size(), 8UL);
421     EXPECT_EQ(Exts.count("i"), 1U);
422     EXPECT_EQ(Exts.count("m"), 1U);
423     EXPECT_EQ(Exts.count("a"), 1U);
424     EXPECT_EQ(Exts.count("f"), 1U);
425     EXPECT_EQ(Exts.count("d"), 1U);
426     EXPECT_EQ(Exts.count("c"), 1U);
427     EXPECT_EQ(Exts.count("zicsr"), 1U);
428     EXPECT_EQ(Exts.count("zifencei"), 1U);
429   }
430 }
431 
432 TEST(ParseArchString, AcceptsRelaxSingleLetterExtensions) {
433   for (StringRef Input :
434        {"rv32imfad", "rv32im_fa_d", "rv32im2p0fad", "rv32i2p1m2p0fad"}) {
435     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
436     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
437     const auto &Exts = (*MaybeISAInfo)->getExtensions();
438     EXPECT_EQ(Exts.size(), 6UL);
439     EXPECT_EQ(Exts.count("i"), 1U);
440     EXPECT_EQ(Exts.count("m"), 1U);
441     EXPECT_EQ(Exts.count("f"), 1U);
442     EXPECT_EQ(Exts.count("a"), 1U);
443     EXPECT_EQ(Exts.count("d"), 1U);
444     EXPECT_EQ(Exts.count("zicsr"), 1U);
445   }
446 }
447 
448 TEST(ParseArchString, AcceptsRelaxMixedLetterExtensions) {
449   for (StringRef Input :
450        {"rv32i_zihintntl_m_a_f_d_svinval", "rv32izihintntl_mafdsvinval",
451         "rv32i_zihintntl_mafd_svinval"}) {
452     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
453     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
454     const auto &Exts = (*MaybeISAInfo)->getExtensions();
455     EXPECT_EQ(Exts.size(), 8UL);
456     EXPECT_EQ(Exts.count("i"), 1U);
457     EXPECT_EQ(Exts.count("m"), 1U);
458     EXPECT_EQ(Exts.count("a"), 1U);
459     EXPECT_EQ(Exts.count("f"), 1U);
460     EXPECT_EQ(Exts.count("d"), 1U);
461     EXPECT_EQ(Exts.count("zihintntl"), 1U);
462     EXPECT_EQ(Exts.count("svinval"), 1U);
463     EXPECT_EQ(Exts.count("zicsr"), 1U);
464   }
465 }
466 
467 TEST(ParseArchString, AcceptsAmbiguousFromRelaxExtensions) {
468   for (StringRef Input : {"rv32i_zba_m", "rv32izba_m", "rv32izba1p0_m2p0"}) {
469     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
470     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
471     const auto &Exts = (*MaybeISAInfo)->getExtensions();
472     EXPECT_EQ(Exts.size(), 3UL);
473     EXPECT_EQ(Exts.count("i"), 1U);
474     EXPECT_EQ(Exts.count("zba"), 1U);
475     EXPECT_EQ(Exts.count("m"), 1U);
476   }
477   for (StringRef Input :
478        {"rv32ia_zba_m", "rv32iazba_m", "rv32ia2p1zba1p0_m2p0"}) {
479     auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true);
480     ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
481     const auto &Exts = (*MaybeISAInfo)->getExtensions();
482     EXPECT_EQ(Exts.size(), 4UL);
483     EXPECT_EQ(Exts.count("i"), 1U);
484     EXPECT_EQ(Exts.count("zba"), 1U);
485     EXPECT_EQ(Exts.count("m"), 1U);
486     EXPECT_EQ(Exts.count("a"), 1U);
487   }
488 }
489 
490 TEST(ParseArchString, RejectsRelaxExtensionsNotStartWithEorIorG) {
491   EXPECT_EQ(
492       toString(RISCVISAInfo::parseArchString("rv32zba_im", true).takeError()),
493       "first letter after 'rv32' should be 'e', 'i' or 'g'");
494 }
495 
496 TEST(ParseArchString,
497      RejectsMultiLetterExtensionFollowBySingleLetterExtensions) {
498   for (StringRef Input : {"rv32izbam", "rv32i_zbam"})
499     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
500               "unsupported standard user-level extension 'zbam'");
501   EXPECT_EQ(
502       toString(RISCVISAInfo::parseArchString("rv32izbai_m", true).takeError()),
503       "unsupported standard user-level extension 'zbai'");
504   EXPECT_EQ(
505       toString(RISCVISAInfo::parseArchString("rv32izbaim", true).takeError()),
506       "unsupported standard user-level extension 'zbaim'");
507   EXPECT_EQ(
508       toString(
509           RISCVISAInfo::parseArchString("rv32i_zba1p0m", true).takeError()),
510       "unsupported standard user-level extension 'zba1p0m'");
511 }
512 
513 TEST(ParseArchString, RejectsDoubleOrTrailingUnderscore) {
514   EXPECT_EQ(
515       toString(RISCVISAInfo::parseArchString("rv64i__m", true).takeError()),
516       "extension name missing after separator '_'");
517 
518   for (StringRef Input :
519        {"rv32ezicsr__zifencei", "rv32i_", "rv32izicsr_", "rv64im_"}) {
520     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
521               "extension name missing after separator '_'");
522   }
523 }
524 
525 TEST(ParseArchString, RejectsDuplicateExtensionNames) {
526   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ii", true).takeError()),
527             "invalid standard user-level extension 'i'");
528   EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32ee", true).takeError()),
529             "invalid standard user-level extension 'e'");
530   EXPECT_EQ(
531       toString(RISCVISAInfo::parseArchString("rv64imm", true).takeError()),
532       "duplicated standard user-level extension 'm'");
533   EXPECT_EQ(
534       toString(
535           RISCVISAInfo::parseArchString("rv32i_zicsr_zicsr", true).takeError()),
536       "duplicated standard user-level extension 'zicsr'");
537 }
538 
539 TEST(ParseArchString,
540      RejectsExperimentalExtensionsIfNotEnableExperimentalExtension) {
541   EXPECT_EQ(
542       toString(RISCVISAInfo::parseArchString("rv64iztso", false).takeError()),
543       "requires '-menable-experimental-extensions' for experimental extension "
544       "'ztso'");
545 }
546 
547 TEST(ParseArchString,
548      AcceptsExperimentalExtensionsIfEnableExperimentalExtension) {
549   // Note: If ztso becomes none-experimental, this test will need
550   // updating (and unfortunately, it will still pass). The failure of
551   // RejectsExperimentalExtensionsIfNotEnableExperimentalExtension will
552   // hopefully serve as a reminder to update.
553   auto MaybeISAInfo = RISCVISAInfo::parseArchString("rv64iztso", true, false);
554   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
555   const auto &Exts = (*MaybeISAInfo)->getExtensions();
556   EXPECT_EQ(Exts.size(), 2UL);
557   EXPECT_EQ(Exts.count("ztso"), 1U);
558   auto MaybeISAInfo2 = RISCVISAInfo::parseArchString("rv64iztso0p1", true);
559   ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
560   const auto &Exts2 = (*MaybeISAInfo2)->getExtensions();
561   EXPECT_EQ(Exts2.size(), 2UL);
562   EXPECT_EQ(Exts2.count("ztso"), 1U);
563 }
564 
565 TEST(ParseArchString,
566      RequiresExplicitVersionNumberForExperimentalExtensionByDefault) {
567   EXPECT_EQ(
568       toString(RISCVISAInfo::parseArchString("rv64iztso", true).takeError()),
569       "experimental extension requires explicit version number `ztso`");
570 }
571 
572 TEST(ParseArchString,
573      AcceptsUnrecognizedVersionIfNotExperimentalExtensionVersionCheck) {
574   auto MaybeISAInfo =
575       RISCVISAInfo::parseArchString("rv64iztso9p9", true, false);
576   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
577   const auto &Exts = (*MaybeISAInfo)->getExtensions();
578   EXPECT_EQ(Exts.size(), 2UL);
579   EXPECT_TRUE(Exts.at("ztso") == (RISCVISAUtils::ExtensionVersion{9, 9}));
580 }
581 
582 TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) {
583   EXPECT_EQ(
584       toString(RISCVISAInfo::parseArchString("rv64iztso9p9", true).takeError()),
585       "unsupported version number 9.9 for experimental extension 'ztso' "
586       "(this compiler supports 0.1)");
587 }
588 
589 TEST(ParseArchString, RejectsExtensionVersionForG) {
590   for (StringRef Input : {"rv32g1c", "rv64g2p0"}) {
591     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
592               "version not supported for 'g'");
593   }
594 }
595 
596 TEST(ParseArchString, AddsImpliedExtensions) {
597   // Does not attempt to exhaustively test all implications.
598   auto MaybeRV64ID = RISCVISAInfo::parseArchString("rv64id", true);
599   ASSERT_THAT_EXPECTED(MaybeRV64ID, Succeeded());
600   const auto &ExtsRV64ID = (*MaybeRV64ID)->getExtensions();
601   EXPECT_EQ(ExtsRV64ID.size(), 4UL);
602   EXPECT_EQ(ExtsRV64ID.count("i"), 1U);
603   EXPECT_EQ(ExtsRV64ID.count("f"), 1U);
604   EXPECT_EQ(ExtsRV64ID.count("d"), 1U);
605   EXPECT_EQ(ExtsRV64ID.count("zicsr"), 1U);
606 
607   auto MaybeRV32IZKN = RISCVISAInfo::parseArchString("rv64izkn", true);
608   ASSERT_THAT_EXPECTED(MaybeRV32IZKN, Succeeded());
609   const auto &ExtsRV32IZKN = (*MaybeRV32IZKN)->getExtensions();
610   EXPECT_EQ(ExtsRV32IZKN.size(), 8UL);
611   EXPECT_EQ(ExtsRV32IZKN.count("i"), 1U);
612   EXPECT_EQ(ExtsRV32IZKN.count("zbkb"), 1U);
613   EXPECT_EQ(ExtsRV32IZKN.count("zbkc"), 1U);
614   EXPECT_EQ(ExtsRV32IZKN.count("zbkx"), 1U);
615   EXPECT_EQ(ExtsRV32IZKN.count("zkne"), 1U);
616   EXPECT_EQ(ExtsRV32IZKN.count("zknd"), 1U);
617   EXPECT_EQ(ExtsRV32IZKN.count("zknh"), 1U);
618   EXPECT_EQ(ExtsRV32IZKN.count("zkn"), 1U);
619 }
620 
621 TEST(ParseArchString, RejectsConflictingExtensions) {
622   for (StringRef Input : {"rv32ifzfinx", "rv64gzdinx"}) {
623     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
624               "'f' and 'zfinx' extensions are incompatible");
625   }
626 
627   for (StringRef Input : {"rv32idc_zcmp1p0", "rv64idc_zcmp1p0"}) {
628     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
629               "'zcmp' extension is incompatible with 'c' extension when 'd' "
630               "extension is enabled");
631   }
632 
633   for (StringRef Input : {"rv32id_zcd1p0_zcmp1p0", "rv64id_zcd1p0_zcmp1p0"}) {
634     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
635               "'zcmp' extension is incompatible with 'zcd' extension when 'd' "
636               "extension is enabled");
637   }
638 
639   for (StringRef Input : {"rv32idc_zcmt1p0", "rv64idc_zcmt1p0"}) {
640     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
641               "'zcmt' extension is incompatible with 'c' extension when 'd' "
642               "extension is enabled");
643   }
644 
645   for (StringRef Input : {"rv32id_zcd1p0_zcmt1p0", "rv64id_zcd1p0_zcmt1p0"}) {
646     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
647               "'zcmt' extension is incompatible with 'zcd' extension when 'd' "
648               "extension is enabled");
649   }
650 
651   for (StringRef Input : {"rv64if_zcf"}) {
652     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
653               "'zcf' is only supported for 'rv32'");
654   }
655 }
656 
657 TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) {
658   auto MaybeISAInfo1 =
659       RISCVISAInfo::parseArchString("rv64im_ztso", true, false);
660   ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded());
661   EXPECT_THAT((*MaybeISAInfo1)->toFeatures(),
662               ElementsAre("+m", "+experimental-ztso"));
663 
664   auto MaybeISAInfo2 =
665       RISCVISAInfo::parseArchString("rv32e_ztso_xventanacondops", true, false);
666   ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded());
667   EXPECT_THAT((*MaybeISAInfo2)->toFeatures(),
668               ElementsAre("+e", "+experimental-ztso", "+xventanacondops"));
669 }
670 
671 TEST(ToFeatures, UnsupportedExtensionsAreDropped) {
672   auto MaybeISAInfo =
673       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
674   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
675   EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m"));
676 }
677 
678 TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) {
679   auto MaybeISAInfo =
680       RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0");
681   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
682   EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false),
683               ElementsAre("+m", "+xmadeup"));
684 }
685 
686 TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) {
687   auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0");
688   ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
689 
690   auto Features = (*MaybeISAInfo)->toFeatures(true);
691   EXPECT_GT(Features.size(), 1UL);
692   EXPECT_EQ(Features.front(), "+m");
693   // Every feature after should be a negative feature
694   for (auto &NegativeExt : llvm::drop_begin(Features))
695     EXPECT_TRUE(NegativeExt.substr(0, 1) == "-");
696 }
697 
698 TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) {
699   RISCVISAUtils::OrderedExtensionMap Exts;
700   for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar",
701                        "zmfoo", "zzfoo", "zfinx", "zicsr"})
702     Exts[ExtName] = {1, 0};
703 
704   std::vector<std::string> ExtNames;
705   for (const auto &Ext : Exts)
706     ExtNames.push_back(Ext.first);
707 
708   // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'.
709   EXPECT_THAT(ExtNames,
710               ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx",
711                            "zzfoo", "sbar", "sfoo", "xbar", "xfoo"));
712 }
713 
714 TEST(ParseArchString, ZceImplication) {
715   auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true);
716   ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded());
717   const auto &ExtsRV32IZce = (*MaybeRV32IZce)->getExtensions();
718   EXPECT_EQ(ExtsRV32IZce.size(), 7UL);
719   EXPECT_EQ(ExtsRV32IZce.count("i"), 1U);
720   EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U);
721   EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U);
722   EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U);
723   EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U);
724   EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U);
725   EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U);
726 
727   auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true);
728   ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded());
729   const auto &ExtsRV32IFZce = (*MaybeRV32IFZce)->getExtensions();
730   EXPECT_EQ(ExtsRV32IFZce.size(), 9UL);
731   EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U);
732   EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U);
733   EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U);
734   EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U);
735   EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U);
736   EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U);
737   EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U);
738   EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U);
739   EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U);
740 
741   auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true);
742   ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded());
743   const auto &ExtsRV32IDZce = (*MaybeRV32IDZce)->getExtensions();
744   EXPECT_EQ(ExtsRV32IDZce.size(), 10UL);
745   EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U);
746   EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U);
747   EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U);
748   EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U);
749   EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U);
750   EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U);
751   EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U);
752   EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U);
753   EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U);
754   EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U);
755 
756   auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true);
757   ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded());
758   const auto &ExtsRV64IZce = (*MaybeRV64IZce)->getExtensions();
759   EXPECT_EQ(ExtsRV64IZce.size(), 7UL);
760   EXPECT_EQ(ExtsRV64IZce.count("i"), 1U);
761   EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U);
762   EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U);
763   EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U);
764   EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U);
765   EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U);
766   EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U);
767 
768   auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true);
769   ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded());
770   const auto &ExtsRV64IFZce = (*MaybeRV64IFZce)->getExtensions();
771   EXPECT_EQ(ExtsRV64IFZce.size(), 8UL);
772   EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U);
773   EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U);
774   EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U);
775   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
776   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
777   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
778   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
779   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
780 
781   EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
782   EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
783   EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
784   EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
785   EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
786 
787   auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true);
788   ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded());
789   const auto &ExtsRV64IDZce = (*MaybeRV64IDZce)->getExtensions();
790   EXPECT_EQ(ExtsRV64IDZce.size(), 9UL);
791   EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U);
792   EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U);
793   EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U);
794   EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U);
795   EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U);
796   EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U);
797   EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U);
798   EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U);
799   EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U);
800 }
801 
802 TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) {
803   EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0"));
804   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb"));
805   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0"));
806   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo"));
807   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion(""));
808   EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0"));
809 }
810 
811 TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) {
812   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb");
813   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso0p1"),
814             "experimental-ztso");
815   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"),
816             "experimental-ztso");
817   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"),
818             "");
819   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), "");
820   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), "");
821   EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), "");
822 }
823 
824 TEST(RiscvExtensionsHelp, CheckExtensions) {
825   // clang-format off
826   std::string ExpectedOutput =
827 R"(All available -march extensions for RISC-V
828 
829     Name                 Version   Description
830     i                    2.1       This is a long dummy description
831     e                    2.0
832     m                    2.0
833     a                    2.1
834     f                    2.2
835     d                    2.2
836     c                    2.0
837     v                    1.0
838     h                    1.0
839     zic64b               1.0
840     zicbom               1.0
841     zicbop               1.0
842     zicboz               1.0
843     ziccamoa             1.0
844     ziccif               1.0
845     zicclsm              1.0
846     ziccrse              1.0
847     zicntr               2.0
848     zicond               1.0
849     zicsr                2.0
850     zifencei             2.0
851     zihintntl            1.0
852     zihintpause          2.0
853     zihpm                2.0
854     zimop                1.0
855     zmmul                1.0
856     za128rs              1.0
857     za64rs               1.0
858     zacas                1.0
859     zama16b              1.0
860     zawrs                1.0
861     zfa                  1.0
862     zfh                  1.0
863     zfhmin               1.0
864     zfinx                1.0
865     zdinx                1.0
866     zca                  1.0
867     zcb                  1.0
868     zcd                  1.0
869     zce                  1.0
870     zcf                  1.0
871     zcmop                1.0
872     zcmp                 1.0
873     zcmt                 1.0
874     zba                  1.0
875     zbb                  1.0
876     zbc                  1.0
877     zbkb                 1.0
878     zbkc                 1.0
879     zbkx                 1.0
880     zbs                  1.0
881     zk                   1.0
882     zkn                  1.0
883     zknd                 1.0
884     zkne                 1.0
885     zknh                 1.0
886     zkr                  1.0
887     zks                  1.0
888     zksed                1.0
889     zksh                 1.0
890     zkt                  1.0
891     zvbb                 1.0
892     zvbc                 1.0
893     zve32f               1.0
894     zve32x               1.0
895     zve64d               1.0
896     zve64f               1.0
897     zve64x               1.0
898     zvfh                 1.0
899     zvfhmin              1.0
900     zvkb                 1.0
901     zvkg                 1.0
902     zvkn                 1.0
903     zvknc                1.0
904     zvkned               1.0
905     zvkng                1.0
906     zvknha               1.0
907     zvknhb               1.0
908     zvks                 1.0
909     zvksc                1.0
910     zvksed               1.0
911     zvksg                1.0
912     zvksh                1.0
913     zvkt                 1.0
914     zvl1024b             1.0
915     zvl128b              1.0
916     zvl16384b            1.0
917     zvl2048b             1.0
918     zvl256b              1.0
919     zvl32768b            1.0
920     zvl32b               1.0
921     zvl4096b             1.0
922     zvl512b              1.0
923     zvl64b               1.0
924     zvl65536b            1.0
925     zvl8192b             1.0
926     zhinx                1.0
927     zhinxmin             1.0
928     shcounterenw         1.0
929     shgatpa              1.0
930     shtvala              1.0
931     shvsatpa             1.0
932     shvstvala            1.0
933     shvstvecd            1.0
934     smaia                1.0
935     smepmp               1.0
936     smstateen            1.0
937     ssaia                1.0
938     ssccptr              1.0
939     sscofpmf             1.0
940     sscounterenw         1.0
941     ssstateen            1.0
942     ssstrict             1.0
943     sstc                 1.0
944     sstvala              1.0
945     sstvecd              1.0
946     ssu64xl              1.0
947     svade                1.0
948     svadu                1.0
949     svbare               1.0
950     svinval              1.0
951     svnapot              1.0
952     svpbmt               1.0
953     xcvalu               1.0
954     xcvbi                1.0
955     xcvbitmanip          1.0
956     xcvelw               1.0
957     xcvmac               1.0
958     xcvmem               1.0
959     xcvsimd              1.0
960     xsfcease             1.0
961     xsfvcp               1.0
962     xsfvfnrclipxfqf      1.0
963     xsfvfwmaccqqq        1.0
964     xsfvqmaccdod         1.0
965     xsfvqmaccqoq         1.0
966     xsifivecdiscarddlone 1.0
967     xsifivecflushdlone   1.0
968     xtheadba             1.0
969     xtheadbb             1.0
970     xtheadbs             1.0
971     xtheadcmo            1.0
972     xtheadcondmov        1.0
973     xtheadfmemidx        1.0
974     xtheadmac            1.0
975     xtheadmemidx         1.0
976     xtheadmempair        1.0
977     xtheadsync           1.0
978     xtheadvdot           1.0
979     xventanacondops      1.0
980 
981 Experimental extensions
982     zicfilp              0.4       This is a long dummy description
983     zicfiss              0.4
984     zaamo                0.2
985     zabha                1.0
986     zalasr               0.1
987     zalrsc               0.2
988     zfbfmin              1.0
989     ztso                 0.1
990     zvfbfmin             1.0
991     zvfbfwma             1.0
992     smmpm                0.8
993     smnpm                0.8
994     ssnpm                0.8
995     sspm                 0.8
996     ssqosid              1.0
997     supm                 0.8
998 
999 Supported Profiles
1000     rva20s64
1001     rva20u64
1002     rva22s64
1003     rva22u64
1004     rva23s64
1005     rva23u64
1006     rvb23s64
1007     rvb23u64
1008     rvi20u32
1009     rvi20u64
1010     rvm23u32
1011 
1012 Use -march to specify the target's extension.
1013 For example, clang -march=rv32i_v1p0)";
1014   // clang-format on
1015 
1016   StringMap<StringRef> DummyMap;
1017   DummyMap["i"] = "This is a long dummy description";
1018   DummyMap["experimental-zicfilp"] = "This is a long dummy description";
1019 
1020   outs().flush();
1021   testing::internal::CaptureStdout();
1022   riscvExtensionsHelp(DummyMap);
1023   outs().flush();
1024 
1025   std::string CapturedOutput = testing::internal::GetCapturedStdout();
1026   EXPECT_TRUE([](std::string &Captured, std::string &Expected) {
1027                 return Captured.find(Expected) != std::string::npos;
1028               }(CapturedOutput, ExpectedOutput));
1029 }
1030