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