1 //===------- VectorFunctionABITest.cpp - VFABI Unittests  ---------===//
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/Analysis/VectorUtils.h"
10 #include "gtest/gtest.h"
11 
12 using namespace llvm;
13 
14 // This test makes sure that the getFromVFABI method succeeds only on
15 // valid values of the string.
16 TEST(VectorFunctionABITests, OnlyValidNames) {
17   // Incomplete string.
18   EXPECT_FALSE(VFABI::tryDemangleForVFABI("").hasValue());
19   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGV").hasValue());
20   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVn").hasValue());
21   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN").hasValue());
22   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2").hasValue());
23   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v").hasValue());
24   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_").hasValue());
25   // Missing parameters.
26   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2_foo").hasValue());
27   // Missing _ZGV prefix.
28   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZVnN2v_foo").hasValue());
29   // Missing <isa>.
30   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVN2v_foo").hasValue());
31   // Missing <mask>.
32   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVn2v_foo").hasValue());
33   // Missing <vlen>.
34   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnNv_foo").hasValue());
35   // Missing <scalarname>.
36   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_").hasValue());
37   // Missing _ separator.
38   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2vfoo").hasValue());
39   // Missing <vectorname>.
40   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_foo()").hasValue());
41   // Unterminated name.
42   EXPECT_FALSE(VFABI::tryDemangleForVFABI("_ZGVnN2v_foo(bar").hasValue());
43 }
44 
45 TEST(VectorFunctionABITests, ParamListParsing) {
46   // Testing "vl16Ls32R3l"
47   const auto OptVFS = VFABI::tryDemangleForVFABI("_ZGVnN2vl16Ls32R3l_foo");
48   EXPECT_TRUE(OptVFS.hasValue());
49   const VFInfo VFS = OptVFS.getValue();
50   EXPECT_EQ(VFS.Shape.Parameters.size(), (unsigned)5);
51   EXPECT_EQ(VFS.Shape.Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
52   EXPECT_EQ(VFS.Shape.Parameters[1],
53             VFParameter({1, VFParamKind::OMP_Linear, 16}));
54   EXPECT_EQ(VFS.Shape.Parameters[2],
55             VFParameter({2, VFParamKind::OMP_LinearValPos, 32}));
56   EXPECT_EQ(VFS.Shape.Parameters[3],
57             VFParameter({3, VFParamKind::OMP_LinearRef, 3}));
58   EXPECT_EQ(VFS.Shape.Parameters[4],
59             VFParameter({4, VFParamKind::OMP_Linear, 1}));
60 }
61 
62 TEST(VectorFunctionABITests, ScalarNameAndVectorName) {
63   // Parse Scalar Name
64   const auto A = VFABI::tryDemangleForVFABI("_ZGVnM2v_sin");
65   const auto B = VFABI::tryDemangleForVFABI("_ZGVnM2v_sin(UserFunc)");
66   const auto C = VFABI::tryDemangleForVFABI("_ZGVnM2v___sin_sin_sin");
67   EXPECT_TRUE(A.hasValue());
68   EXPECT_TRUE(B.hasValue());
69   EXPECT_TRUE(C.hasValue());
70   EXPECT_EQ(A.getValue().ScalarName, "sin");
71   EXPECT_EQ(B.getValue().ScalarName, "sin");
72   EXPECT_EQ(C.getValue().ScalarName, "__sin_sin_sin");
73   EXPECT_EQ(A.getValue().VectorName, "_ZGVnM2v_sin");
74   EXPECT_EQ(B.getValue().VectorName, "UserFunc");
75   EXPECT_EQ(C.getValue().VectorName, "_ZGVnM2v___sin_sin_sin");
76 }
77 
78 namespace {
79 // Test fixture needed that holds the veariables needed by the parser.
80 class VFABIParserTest : public ::testing::Test {
81 private:
82   // Parser output.
83   VFInfo Info;
84   // Reset the parser output references.
85   void reset() { Info = VFInfo(); }
86 
87 protected:
88   // Referencies to the parser output field.
89   unsigned &VF = Info.Shape.VF;
90   VFISAKind &ISA = Info.Shape.ISA;
91   SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters;
92   StringRef &ScalarName = Info.ScalarName;
93   StringRef &VectorName = Info.VectorName;
94   bool &IsScalable = Info.Shape.IsScalable;
95   // Invoke the parser.
96   bool invokeParser(const StringRef MangledName) {
97     reset();
98     const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName);
99     if (OptInfo.hasValue()) {
100       Info = OptInfo.getValue();
101       return true;
102     }
103 
104     return false;
105   }
106   // Checks that 1. the last Parameter in the Shape is of type
107   // VFParamKind::GlobalPredicate and 2. it is the only one of such
108   // type.
109   bool IsMasked() const {
110     const auto NGlobalPreds =
111         std::count_if(Info.Shape.Parameters.begin(),
112                       Info.Shape.Parameters.end(), [](const VFParameter PK) {
113                         return PK.ParamKind == VFParamKind::GlobalPredicate;
114                       });
115     return NGlobalPreds == 1 && Info.Shape.Parameters.back().ParamKind ==
116                                     VFParamKind::GlobalPredicate;
117   }
118 };
119 } // unnamed namespace
120 
121 TEST_F(VFABIParserTest, Parse) {
122   EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin"));
123   EXPECT_EQ(VF, (unsigned)2);
124   EXPECT_FALSE(IsMasked());
125   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
126   EXPECT_FALSE(IsScalable);
127   EXPECT_EQ(Parameters.size(), (unsigned)9);
128   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
129   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearPos, 2}));
130   EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 27}));
131   EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}));
132   EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}));
133   EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_Linear, 1}));
134   EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearVal, 10}));
135   EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, 100}));
136   EXPECT_EQ(Parameters[8], VFParameter({8, VFParamKind::OMP_LinearRef, 1000}));
137   EXPECT_EQ(ScalarName, "sin");
138   EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin");
139 }
140 
141 TEST_F(VFABIParserTest, ParseVectorName) {
142   EXPECT_TRUE(invokeParser("_ZGVnN2v_sin(my_v_sin)"));
143   EXPECT_EQ(VF, (unsigned)2);
144   EXPECT_FALSE(IsMasked());
145   EXPECT_FALSE(IsScalable);
146   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
147   EXPECT_EQ(Parameters.size(), (unsigned)1);
148   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
149   EXPECT_EQ(ScalarName, "sin");
150   EXPECT_EQ(VectorName, "my_v_sin");
151 }
152 
153 TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) {
154   EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin"));
155   EXPECT_EQ(VF, (unsigned)2);
156   EXPECT_FALSE(IsMasked());
157   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
158   EXPECT_FALSE(IsScalable);
159   EXPECT_EQ(Parameters.size(), (unsigned)4);
160   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, -1}));
161   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, -10}));
162   EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearUVal, -100}));
163   EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, -1000}));
164   EXPECT_EQ(ScalarName, "sin");
165   EXPECT_EQ(VectorName, "_ZGVnN2ln1Ln10Un100Rn1000_sin");
166 }
167 
168 TEST_F(VFABIParserTest, ParseScalableSVE) {
169   EXPECT_TRUE(invokeParser("_ZGVsMxv_sin"));
170   EXPECT_EQ(VF, (unsigned)0);
171   EXPECT_TRUE(IsMasked());
172   EXPECT_TRUE(IsScalable);
173   EXPECT_EQ(ISA, VFISAKind::SVE);
174   EXPECT_EQ(ScalarName, "sin");
175   EXPECT_EQ(VectorName, "_ZGVsMxv_sin");
176 }
177 
178 TEST_F(VFABIParserTest, ParseFixedWidthSVE) {
179   EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
180   EXPECT_EQ(VF, (unsigned)2);
181   EXPECT_TRUE(IsMasked());
182   EXPECT_FALSE(IsScalable);
183   EXPECT_EQ(ISA, VFISAKind::SVE);
184   EXPECT_EQ(ScalarName, "sin");
185   EXPECT_EQ(VectorName, "_ZGVsM2v_sin");
186 }
187 
188 TEST_F(VFABIParserTest, NotAVectorFunctionABIName) {
189   // Vector names should start with `_ZGV`.
190   EXPECT_FALSE(invokeParser("ZGVnN2v_sin"));
191 }
192 
193 TEST_F(VFABIParserTest, LinearWithRuntimeStep) {
194   EXPECT_FALSE(invokeParser("_ZGVnN2ls_sin"))
195       << "A number should be present after \"ls\".";
196   EXPECT_TRUE(invokeParser("_ZGVnN2ls2_sin"));
197   EXPECT_FALSE(invokeParser("_ZGVnN2Rs_sin"))
198       << "A number should be present after \"Rs\".";
199   EXPECT_TRUE(invokeParser("_ZGVnN2Rs4_sin"));
200   EXPECT_FALSE(invokeParser("_ZGVnN2Ls_sin"))
201       << "A number should be present after \"Ls\".";
202   EXPECT_TRUE(invokeParser("_ZGVnN2Ls6_sin"));
203   EXPECT_FALSE(invokeParser("_ZGVnN2Us_sin"))
204       << "A number should be present after \"Us\".";
205   EXPECT_TRUE(invokeParser("_ZGVnN2Us8_sin"));
206 }
207 
208 TEST_F(VFABIParserTest, LinearWithoutCompileTime) {
209   EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_sin"));
210   EXPECT_EQ(Parameters.size(), (unsigned)8);
211   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, 1}));
212   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, 1}));
213   EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearRef, 1}));
214   EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUVal, 1}));
215   EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, -1}));
216   EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_LinearVal, -1}));
217   EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearRef, -1}));
218   EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, -1}));
219 }
220 
221 TEST_F(VFABIParserTest, ISA) {
222   EXPECT_TRUE(invokeParser("_ZGVqN2v_sin"));
223   EXPECT_EQ(ISA, VFISAKind::Unknown);
224 
225   EXPECT_TRUE(invokeParser("_ZGVnN2v_sin"));
226   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
227 
228   EXPECT_TRUE(invokeParser("_ZGVsN2v_sin"));
229   EXPECT_EQ(ISA, VFISAKind::SVE);
230 
231   EXPECT_TRUE(invokeParser("_ZGVbN2v_sin"));
232   EXPECT_EQ(ISA, VFISAKind::SSE);
233 
234   EXPECT_TRUE(invokeParser("_ZGVcN2v_sin"));
235   EXPECT_EQ(ISA, VFISAKind::AVX);
236 
237   EXPECT_TRUE(invokeParser("_ZGVdN2v_sin"));
238   EXPECT_EQ(ISA, VFISAKind::AVX2);
239 
240   EXPECT_TRUE(invokeParser("_ZGVeN2v_sin"));
241   EXPECT_EQ(ISA, VFISAKind::AVX512);
242 }
243 
244 TEST_F(VFABIParserTest, InvalidMask) {
245   EXPECT_FALSE(invokeParser("_ZGVsK2v_sin"));
246 }
247 
248 TEST_F(VFABIParserTest, InvalidParameter) {
249   EXPECT_FALSE(invokeParser("_ZGVsM2vX_sin"));
250 }
251 
252 TEST_F(VFABIParserTest, Align) {
253   EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_sin"));
254   EXPECT_EQ(Parameters.size(), (unsigned)1);
255   EXPECT_EQ(Parameters[0].Alignment, Align(2));
256 
257   // Missing alignement value.
258   EXPECT_FALSE(invokeParser("_ZGVsM2l2a_sin"));
259   // Invalid alignment token "x".
260   EXPECT_FALSE(invokeParser("_ZGVsM2l2ax_sin"));
261   // Alignment MUST be associated to a paramater.
262   EXPECT_FALSE(invokeParser("_ZGVsM2a2_sin"));
263   // Alignment must be a power of 2.
264   EXPECT_FALSE(invokeParser("_ZGVsN2l2a0_sin"));
265   EXPECT_TRUE(invokeParser("_ZGVsN2l2a1_sin"));
266   EXPECT_FALSE(invokeParser("_ZGVsN2l2a3_sin"));
267   EXPECT_FALSE(invokeParser("_ZGVsN2l2a6_sin"));
268 }
269 
270 TEST_F(VFABIParserTest, ParseUniform) {
271   EXPECT_TRUE(invokeParser("_ZGVnN2u0_sin"));
272   EXPECT_EQ(VF, (unsigned)2);
273   EXPECT_FALSE(IsMasked());
274   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
275   EXPECT_FALSE(IsScalable);
276   EXPECT_EQ(Parameters.size(), (unsigned)1);
277   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Uniform, 0}));
278   EXPECT_EQ(ScalarName, "sin");
279   EXPECT_EQ(VectorName, "_ZGVnN2u0_sin");
280 
281   EXPECT_FALSE(invokeParser("_ZGVnN2u_sin"));
282   EXPECT_FALSE(invokeParser("_ZGVnN2ul_sin"));
283 }
284 
285 TEST_F(VFABIParserTest, ISAIndependentMangling) {
286   // This test makes sure that the mangling of the parameters in
287   // independent on the <isa> token.
288   const SmallVector<VFParameter, 8> ExpectedParams = {
289       VFParameter({0, VFParamKind::Vector, 0}),
290       VFParameter({1, VFParamKind::OMP_LinearPos, 2}),
291       VFParameter({2, VFParamKind::OMP_LinearValPos, 27}),
292       VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}),
293       VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}),
294       VFParameter({5, VFParamKind::OMP_Linear, 1}),
295       VFParameter({6, VFParamKind::OMP_LinearVal, 10}),
296       VFParameter({7, VFParamKind::OMP_LinearUVal, 100}),
297       VFParameter({8, VFParamKind::OMP_LinearRef, 1000}),
298       VFParameter({9, VFParamKind::OMP_Uniform, 2}),
299   };
300 
301 #define __COMMON_CHECKS                                                        \
302   do {                                                                         \
303     EXPECT_EQ(VF, (unsigned)2);                                                \
304     EXPECT_FALSE(IsMasked());                                                  \
305     EXPECT_FALSE(IsScalable);                                                  \
306     EXPECT_EQ(Parameters.size(), (unsigned)10);                                \
307     EXPECT_EQ(Parameters, ExpectedParams);                                     \
308     EXPECT_EQ(ScalarName, "sin");                                              \
309   } while (0)
310 
311   // Advanced SIMD: <isa> = "n"
312   EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
313   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
314   __COMMON_CHECKS;
315   EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
316 
317   // SVE: <isa> = "s"
318   EXPECT_TRUE(invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
319   EXPECT_EQ(ISA, VFISAKind::SVE);
320   __COMMON_CHECKS;
321   EXPECT_EQ(VectorName, "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
322 
323   // SSE: <isa> = "b"
324   EXPECT_TRUE(invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
325   EXPECT_EQ(ISA, VFISAKind::SSE);
326   __COMMON_CHECKS;
327   EXPECT_EQ(VectorName, "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
328 
329   // AVX: <isa> = "c"
330   EXPECT_TRUE(invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
331   EXPECT_EQ(ISA, VFISAKind::AVX);
332   __COMMON_CHECKS;
333   EXPECT_EQ(VectorName, "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
334 
335   // AVX2: <isa> = "d"
336   EXPECT_TRUE(invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
337   EXPECT_EQ(ISA, VFISAKind::AVX2);
338   __COMMON_CHECKS;
339   EXPECT_EQ(VectorName, "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
340 
341   // AVX512: <isa> = "e"
342   EXPECT_TRUE(invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
343   EXPECT_EQ(ISA, VFISAKind::AVX512);
344   __COMMON_CHECKS;
345   EXPECT_EQ(VectorName, "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
346 
347   // Unknown ISA (randomly using "q"). This test will need update if
348   // some targets decide to use "q" as their ISA token.
349   EXPECT_TRUE(invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin"));
350   EXPECT_EQ(ISA, VFISAKind::Unknown);
351   __COMMON_CHECKS;
352   EXPECT_EQ(VectorName, "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u2_sin");
353 
354 #undef __COMMON_CHECKS
355 }
356 
357 TEST_F(VFABIParserTest, MissingScalarName) {
358   EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
359 }
360 
361 TEST_F(VFABIParserTest, MissingVectorName) {
362   EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()"));
363 }
364 
365 TEST_F(VFABIParserTest, MissingVectorNameTermination) {
366   EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar"));
367 }
368 
369 TEST_F(VFABIParserTest, ParseMaskingNEON) {
370   EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
371   EXPECT_EQ(VF, (unsigned)2);
372   EXPECT_TRUE(IsMasked());
373   EXPECT_FALSE(IsScalable);
374   EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
375   EXPECT_EQ(Parameters.size(), (unsigned)2);
376   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
377   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
378   EXPECT_EQ(ScalarName, "sin");
379 }
380 
381 TEST_F(VFABIParserTest, ParseMaskingSVE) {
382   EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
383   EXPECT_EQ(VF, (unsigned)2);
384   EXPECT_TRUE(IsMasked());
385   EXPECT_FALSE(IsScalable);
386   EXPECT_EQ(ISA, VFISAKind::SVE);
387   EXPECT_EQ(Parameters.size(), (unsigned)2);
388   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
389   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
390   EXPECT_EQ(ScalarName, "sin");
391 }
392 
393 TEST_F(VFABIParserTest, ParseMaskingSSE) {
394   EXPECT_TRUE(invokeParser("_ZGVbM2v_sin"));
395   EXPECT_EQ(VF, (unsigned)2);
396   EXPECT_TRUE(IsMasked());
397   EXPECT_FALSE(IsScalable);
398   EXPECT_EQ(ISA, VFISAKind::SSE);
399   EXPECT_EQ(Parameters.size(), (unsigned)2);
400   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
401   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
402   EXPECT_EQ(ScalarName, "sin");
403 }
404 
405 TEST_F(VFABIParserTest, ParseMaskingAVX) {
406   EXPECT_TRUE(invokeParser("_ZGVcM2v_sin"));
407   EXPECT_EQ(VF, (unsigned)2);
408   EXPECT_TRUE(IsMasked());
409   EXPECT_FALSE(IsScalable);
410   EXPECT_EQ(ISA, VFISAKind::AVX);
411   EXPECT_EQ(Parameters.size(), (unsigned)2);
412   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
413   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
414   EXPECT_EQ(ScalarName, "sin");
415 }
416 
417 TEST_F(VFABIParserTest, ParseMaskingAVX2) {
418   EXPECT_TRUE(invokeParser("_ZGVdM2v_sin"));
419   EXPECT_EQ(VF, (unsigned)2);
420   EXPECT_TRUE(IsMasked());
421   EXPECT_FALSE(IsScalable);
422   EXPECT_EQ(ISA, VFISAKind::AVX2);
423   EXPECT_EQ(Parameters.size(), (unsigned)2);
424   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
425   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
426   EXPECT_EQ(ScalarName, "sin");
427 }
428 
429 TEST_F(VFABIParserTest, ParseMaskingAVX512) {
430   EXPECT_TRUE(invokeParser("_ZGVeM2v_sin"));
431   EXPECT_EQ(VF, (unsigned)2);
432   EXPECT_TRUE(IsMasked());
433   EXPECT_FALSE(IsScalable);
434   EXPECT_EQ(ISA, VFISAKind::AVX512);
435   EXPECT_EQ(Parameters.size(), (unsigned)2);
436   EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
437   EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
438   EXPECT_EQ(ScalarName, "sin");
439 }
440