1cb032aa2SFrancesco Petrogalli //===------- VectorFunctionABITest.cpp - VFABI Unittests ---------===//
2cb032aa2SFrancesco Petrogalli //
3cb032aa2SFrancesco Petrogalli // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cb032aa2SFrancesco Petrogalli // See https://llvm.org/LICENSE.txt for license information.
5cb032aa2SFrancesco Petrogalli // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cb032aa2SFrancesco Petrogalli //
7cb032aa2SFrancesco Petrogalli //===----------------------------------------------------------------------===//
8cb032aa2SFrancesco Petrogalli
9cb032aa2SFrancesco Petrogalli #include "llvm/Analysis/VectorUtils.h"
10e9a06e06SFrancesco Petrogalli #include "llvm/AsmParser/Parser.h"
11e9a06e06SFrancesco Petrogalli #include "llvm/IR/InstIterator.h"
12cb032aa2SFrancesco Petrogalli #include "gtest/gtest.h"
13cb032aa2SFrancesco Petrogalli
14cb032aa2SFrancesco Petrogalli using namespace llvm;
15cb032aa2SFrancesco Petrogalli
16cb032aa2SFrancesco Petrogalli namespace {
17cb032aa2SFrancesco Petrogalli // Test fixture needed that holds the veariables needed by the parser.
18cb032aa2SFrancesco Petrogalli class VFABIParserTest : public ::testing::Test {
19cb032aa2SFrancesco Petrogalli private:
20cb032aa2SFrancesco Petrogalli // Parser output.
21cb032aa2SFrancesco Petrogalli VFInfo Info;
22623cff81SFrancesco Petrogalli // Reset the data needed for the test.
reset(const StringRef Name,const StringRef IRType)23623cff81SFrancesco Petrogalli void reset(const StringRef Name, const StringRef IRType) {
24623cff81SFrancesco Petrogalli M = parseAssemblyString("declare void @dummy()", Err, Ctx);
25623cff81SFrancesco Petrogalli EXPECT_NE(M.get(), nullptr) << "Loading an invalid module.\n "
26623cff81SFrancesco Petrogalli << Err.getMessage() << "\n";
27623cff81SFrancesco Petrogalli Type *Ty = parseType(IRType, Err, *(M.get()));
28623cff81SFrancesco Petrogalli FunctionType *FTy = dyn_cast<FunctionType>(Ty);
29623cff81SFrancesco Petrogalli EXPECT_NE(FTy, nullptr) << "Invalid function type string: " << IRType
30623cff81SFrancesco Petrogalli << "\n"
31623cff81SFrancesco Petrogalli << Err.getMessage() << "\n";
32623cff81SFrancesco Petrogalli FunctionCallee F = M->getOrInsertFunction(Name, FTy);
33623cff81SFrancesco Petrogalli EXPECT_NE(F.getCallee(), nullptr)
34623cff81SFrancesco Petrogalli << "The function must be present in the module\n";
35623cff81SFrancesco Petrogalli // Reset the VFInfo
36623cff81SFrancesco Petrogalli Info = VFInfo();
37623cff81SFrancesco Petrogalli }
38cb032aa2SFrancesco Petrogalli
39623cff81SFrancesco Petrogalli // Data needed to load the optional IR passed to invokeParser
40623cff81SFrancesco Petrogalli LLVMContext Ctx;
41623cff81SFrancesco Petrogalli SMDiagnostic Err;
42623cff81SFrancesco Petrogalli std::unique_ptr<Module> M;
43623cff81SFrancesco Petrogalli // CallInst *CI;
44cb032aa2SFrancesco Petrogalli protected:
45cb032aa2SFrancesco Petrogalli // Referencies to the parser output field.
468a8d01d5SPaul Walker ElementCount &VF = Info.Shape.VF;
47eac93757SFrancesco Petrogalli VFISAKind &ISA = Info.ISA;
48cb032aa2SFrancesco Petrogalli SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters;
4966c120f0SFrancesco Petrogalli std::string &ScalarName = Info.ScalarName;
5066c120f0SFrancesco Petrogalli std::string &VectorName = Info.VectorName;
51623cff81SFrancesco Petrogalli // Invoke the parser. We need to make sure that a function exist in
52623cff81SFrancesco Petrogalli // the module because the parser fails if such function don't
53623cff81SFrancesco Petrogalli // exists. Every time this method is invoked the state of the test
54623cff81SFrancesco Petrogalli // is reset.
55623cff81SFrancesco Petrogalli //
56623cff81SFrancesco Petrogalli // \p MangledName -> the string the parser has to demangle.
57623cff81SFrancesco Petrogalli //
58623cff81SFrancesco Petrogalli // \p VectorName -> optional vector name that the method needs to
59623cff81SFrancesco Petrogalli // use to create the function in the module if it differs from the
60623cff81SFrancesco Petrogalli // standard mangled name.
61623cff81SFrancesco Petrogalli //
62623cff81SFrancesco Petrogalli // \p IRType -> FunctionType string to be used for the signature of
63623cff81SFrancesco Petrogalli // the vector function. The correct signature is needed by the
64623cff81SFrancesco Petrogalli // parser only for scalable functions. For the sake of testing, the
65623cff81SFrancesco Petrogalli // generic fixed-length case can use as signature `void()`.
66623cff81SFrancesco Petrogalli //
invokeParser(const StringRef MangledName,const StringRef VectorName="",const StringRef IRType="void()")67623cff81SFrancesco Petrogalli bool invokeParser(const StringRef MangledName,
68623cff81SFrancesco Petrogalli const StringRef VectorName = "",
69623cff81SFrancesco Petrogalli const StringRef IRType = "void()") {
70623cff81SFrancesco Petrogalli StringRef Name = MangledName;
71623cff81SFrancesco Petrogalli if (!VectorName.empty())
72623cff81SFrancesco Petrogalli Name = VectorName;
73623cff81SFrancesco Petrogalli // Reset the VFInfo and the Module to be able to invoke
74623cff81SFrancesco Petrogalli // `invokeParser` multiple times in the same test.
75623cff81SFrancesco Petrogalli reset(Name, IRType);
76623cff81SFrancesco Petrogalli
77623cff81SFrancesco Petrogalli const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, *(M.get()));
78a7938c74SKazu Hirata if (OptInfo) {
79*611ffcf4SKazu Hirata Info = OptInfo.value();
80cb032aa2SFrancesco Petrogalli return true;
81cb032aa2SFrancesco Petrogalli }
82cb032aa2SFrancesco Petrogalli
83cb032aa2SFrancesco Petrogalli return false;
84cb032aa2SFrancesco Petrogalli }
857cc3769aSAnna Thomas
86cb032aa2SFrancesco Petrogalli // Checks that 1. the last Parameter in the Shape is of type
87cb032aa2SFrancesco Petrogalli // VFParamKind::GlobalPredicate and 2. it is the only one of such
88cb032aa2SFrancesco Petrogalli // type.
IsMasked() const89cb032aa2SFrancesco Petrogalli bool IsMasked() const {
90cb032aa2SFrancesco Petrogalli const auto NGlobalPreds =
91cb032aa2SFrancesco Petrogalli std::count_if(Info.Shape.Parameters.begin(),
92cb032aa2SFrancesco Petrogalli Info.Shape.Parameters.end(), [](const VFParameter PK) {
93cb032aa2SFrancesco Petrogalli return PK.ParamKind == VFParamKind::GlobalPredicate;
94cb032aa2SFrancesco Petrogalli });
95cb032aa2SFrancesco Petrogalli return NGlobalPreds == 1 && Info.Shape.Parameters.back().ParamKind ==
96cb032aa2SFrancesco Petrogalli VFParamKind::GlobalPredicate;
97cb032aa2SFrancesco Petrogalli }
98cb032aa2SFrancesco Petrogalli };
99cb032aa2SFrancesco Petrogalli } // unnamed namespace
100cb032aa2SFrancesco Petrogalli
1017cc3769aSAnna Thomas // This test makes sure correct mangling occurs for given string.
TEST_F(VFABIParserTest,ManglingVectorTLINames)1027cc3769aSAnna Thomas TEST_F(VFABIParserTest, ManglingVectorTLINames) {
1039700228aSDavid Sherwood EXPECT_EQ(
1049700228aSDavid Sherwood VFABI::mangleTLIVectorName("vec", "scalar", 3, ElementCount::getFixed(4)),
1057cc3769aSAnna Thomas "_ZGV_LLVM_N4vvv_scalar(vec)");
1069700228aSDavid Sherwood EXPECT_EQ(VFABI::mangleTLIVectorName("vec", "scalar", 3,
1079700228aSDavid Sherwood ElementCount::getScalable(4)),
1089700228aSDavid Sherwood "_ZGV_LLVM_Nxvvv_scalar(vec)");
1099700228aSDavid Sherwood EXPECT_EQ(VFABI::mangleTLIVectorName("custom.call.v5", "custom.call", 1,
1109700228aSDavid Sherwood ElementCount::getFixed(5)),
1117cc3769aSAnna Thomas "_ZGV_LLVM_N5v_custom.call(custom.call.v5)");
1127cc3769aSAnna Thomas }
1137cc3769aSAnna Thomas
114623cff81SFrancesco Petrogalli // This test makes sure that the demangling method succeeds only on
115623cff81SFrancesco Petrogalli // valid values of the string.
TEST_F(VFABIParserTest,OnlyValidNames)116623cff81SFrancesco Petrogalli TEST_F(VFABIParserTest, OnlyValidNames) {
117623cff81SFrancesco Petrogalli // Incomplete string.
118623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser(""));
119623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGV"));
120623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVn"));
121623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN"));
122623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2"));
123623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v"));
124623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
125623cff81SFrancesco Petrogalli // Missing parameters.
126623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2_foo"));
127623cff81SFrancesco Petrogalli // Missing _ZGV prefix.
128623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZVnN2v_foo"));
129623cff81SFrancesco Petrogalli // Missing <isa>.
130623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVN2v_foo"));
131623cff81SFrancesco Petrogalli // Missing <mask>.
132623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVn2v_foo"));
133623cff81SFrancesco Petrogalli // Missing <vlen>.
134623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnNv_foo"));
135623cff81SFrancesco Petrogalli // Missing <scalarname>.
136623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
137623cff81SFrancesco Petrogalli // Missing _ separator.
138623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2vfoo"));
139623cff81SFrancesco Petrogalli // Missing <vectorname>. Using `fakename` because the string being
140623cff81SFrancesco Petrogalli // parsed is not a valid function name that `invokeParser` can add.
141623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()", "fakename"));
142623cff81SFrancesco Petrogalli // Unterminated name. Using `fakename` because the string being
143623cff81SFrancesco Petrogalli // parsed is not a valid function name that `invokeParser` can add.
144623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar", "fakename"));
145623cff81SFrancesco Petrogalli }
146623cff81SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParamListParsing)147623cff81SFrancesco Petrogalli TEST_F(VFABIParserTest, ParamListParsing) {
148623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo"));
149623cff81SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)5);
150623cff81SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
151623cff81SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_Linear, 16}));
152623cff81SFrancesco Petrogalli EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 32}));
153623cff81SFrancesco Petrogalli EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, 3}));
154623cff81SFrancesco Petrogalli EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, 1}));
155623cff81SFrancesco Petrogalli }
156623cff81SFrancesco Petrogalli
TEST_F(VFABIParserTest,ScalarNameAndVectorName_01)157623cff81SFrancesco Petrogalli TEST_F(VFABIParserTest, ScalarNameAndVectorName_01) {
158623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
159623cff81SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
160623cff81SFrancesco Petrogalli EXPECT_EQ(VectorName, "_ZGVnM2v_sin");
161623cff81SFrancesco Petrogalli }
162623cff81SFrancesco Petrogalli
TEST_F(VFABIParserTest,ScalarNameAndVectorName_02)163623cff81SFrancesco Petrogalli TEST_F(VFABIParserTest, ScalarNameAndVectorName_02) {
164623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnM2v_sin(UserFunc)", "UserFunc"));
165623cff81SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
166623cff81SFrancesco Petrogalli EXPECT_EQ(VectorName, "UserFunc");
167623cff81SFrancesco Petrogalli }
168623cff81SFrancesco Petrogalli
TEST_F(VFABIParserTest,ScalarNameAndVectorName_03)169623cff81SFrancesco Petrogalli TEST_F(VFABIParserTest, ScalarNameAndVectorName_03) {
170623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnM2v___sin_sin_sin"));
171623cff81SFrancesco Petrogalli EXPECT_EQ(ScalarName, "__sin_sin_sin");
172623cff81SFrancesco Petrogalli EXPECT_EQ(VectorName, "_ZGVnM2v___sin_sin_sin");
173623cff81SFrancesco Petrogalli }
174623cff81SFrancesco Petrogalli
TEST_F(VFABIParserTest,Parse)175cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, Parse) {
176cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin"));
1778a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
178cb032aa2SFrancesco Petrogalli EXPECT_FALSE(IsMasked());
179cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
180cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)9);
181cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
182cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearPos, 2}));
183cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 27}));
184cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}));
185cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}));
186cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_Linear, 1}));
187cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearVal, 10}));
188cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, 100}));
189cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[8], VFParameter({8, VFParamKind::OMP_LinearRef, 1000}));
190cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
191cb032aa2SFrancesco Petrogalli EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin");
192cb032aa2SFrancesco Petrogalli }
193cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseVectorName)194cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseVectorName) {
195623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2v_sin(my_v_sin)", "my_v_sin"));
1968a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
197cb032aa2SFrancesco Petrogalli EXPECT_FALSE(IsMasked());
198cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
199cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)1);
200cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
201cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
202cb032aa2SFrancesco Petrogalli EXPECT_EQ(VectorName, "my_v_sin");
203cb032aa2SFrancesco Petrogalli }
204cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,LinearWithCompileTimeNegativeStep)205cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) {
206cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin"));
2078a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
208cb032aa2SFrancesco Petrogalli EXPECT_FALSE(IsMasked());
209cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
210cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)4);
211cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, -1}));
212cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, -10}));
213cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearUVal, -100}));
214cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, -1000}));
215cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
216cb032aa2SFrancesco Petrogalli EXPECT_EQ(VectorName, "_ZGVnN2ln1Ln10Un100Rn1000_sin");
217cb032aa2SFrancesco Petrogalli }
218cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseScalableSVE)219cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseScalableSVE) {
220623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser(
221623cff81SFrancesco Petrogalli "_ZGVsMxv_sin(custom_vg)", "custom_vg",
222623cff81SFrancesco Petrogalli "<vscale x 2 x i32>(<vscale x 2 x i32>, <vscale x 2 x i1>)"));
2238a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getScalable(2));
224cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
225cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SVE);
226cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
227623cff81SFrancesco Petrogalli EXPECT_EQ(VectorName, "custom_vg");
228cb032aa2SFrancesco Petrogalli }
229cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseFixedWidthSVE)230cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseFixedWidthSVE) {
231cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
2328a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
233cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
234cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SVE);
235cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
236cb032aa2SFrancesco Petrogalli EXPECT_EQ(VectorName, "_ZGVsM2v_sin");
237cb032aa2SFrancesco Petrogalli }
238cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,NotAVectorFunctionABIName)239cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, NotAVectorFunctionABIName) {
240cb032aa2SFrancesco Petrogalli // Vector names should start with `_ZGV`.
241cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("ZGVnN2v_sin"));
242cb032aa2SFrancesco Petrogalli }
243cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,LinearWithRuntimeStep)244cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, LinearWithRuntimeStep) {
245cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2ls_sin"))
246cb032aa2SFrancesco Petrogalli << "A number should be present after \"ls\".";
247cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2ls2_sin"));
248cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2Rs_sin"))
249cb032aa2SFrancesco Petrogalli << "A number should be present after \"Rs\".";
250cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2Rs4_sin"));
251cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2Ls_sin"))
252cb032aa2SFrancesco Petrogalli << "A number should be present after \"Ls\".";
253cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2Ls6_sin"));
254cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2Us_sin"))
255cb032aa2SFrancesco Petrogalli << "A number should be present after \"Us\".";
256cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2Us8_sin"));
257cb032aa2SFrancesco Petrogalli }
258cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,LinearWithoutCompileTime)259cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, LinearWithoutCompileTime) {
260cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_sin"));
261cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)8);
262cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, 1}));
263cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, 1}));
264cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearRef, 1}));
265cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUVal, 1}));
266cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, -1}));
267cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_LinearVal, -1}));
268cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearRef, -1}));
269cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, -1}));
270cb032aa2SFrancesco Petrogalli }
271cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ISA)272cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ISA) {
273cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVqN2v_sin"));
274cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::Unknown);
275cb032aa2SFrancesco Petrogalli
276cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnN2v_sin"));
277cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
278cb032aa2SFrancesco Petrogalli
279cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVsN2v_sin"));
280cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SVE);
281cb032aa2SFrancesco Petrogalli
282cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVbN2v_sin"));
283cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SSE);
284cb032aa2SFrancesco Petrogalli
285cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVcN2v_sin"));
286cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX);
287cb032aa2SFrancesco Petrogalli
288cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVdN2v_sin"));
289cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX2);
290cb032aa2SFrancesco Petrogalli
291cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVeN2v_sin"));
292cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX512);
293cb032aa2SFrancesco Petrogalli }
294cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,LLVM_ISA)29566c120f0SFrancesco Petrogalli TEST_F(VFABIParserTest, LLVM_ISA) {
29666c120f0SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
297623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name"));
29866c120f0SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::LLVM);
29966c120f0SFrancesco Petrogalli }
30066c120f0SFrancesco Petrogalli
TEST_F(VFABIParserTest,InvalidMask)301cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, InvalidMask) {
302cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsK2v_sin"));
303cb032aa2SFrancesco Petrogalli }
304cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,InvalidParameter)305cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, InvalidParameter) {
306cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsM2vX_sin"));
307cb032aa2SFrancesco Petrogalli }
308cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,Align)309cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, Align) {
310cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_sin"));
311cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)1);
312cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0].Alignment, Align(2));
313cb032aa2SFrancesco Petrogalli
314d68904f9SJames Henderson // Missing alignment value.
315cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsM2l2a_sin"));
316cb032aa2SFrancesco Petrogalli // Invalid alignment token "x".
317cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsM2l2ax_sin"));
318cb032aa2SFrancesco Petrogalli // Alignment MUST be associated to a paramater.
319cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsM2a2_sin"));
320cb032aa2SFrancesco Petrogalli // Alignment must be a power of 2.
321cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsN2l2a0_sin"));
322cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVsN2l2a1_sin"));
323cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsN2l2a3_sin"));
324cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsN2l2a6_sin"));
325cb032aa2SFrancesco Petrogalli }
326cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseUniform)327cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseUniform) {
328495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVnN2u_sin"));
3298a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
330cb032aa2SFrancesco Petrogalli EXPECT_FALSE(IsMasked());
331cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
332cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)1);
333cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Uniform, 0}));
334cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
335495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVnN2u_sin");
336cb032aa2SFrancesco Petrogalli
337495f1829SPaul Walker // Uniform doesn't expect extra data.
338495f1829SPaul Walker EXPECT_FALSE(invokeParser("_ZGVnN2u0_sin"));
339cb032aa2SFrancesco Petrogalli }
340cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ISAIndependentMangling)341cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ISAIndependentMangling) {
342cb032aa2SFrancesco Petrogalli // This test makes sure that the mangling of the parameters in
343cb032aa2SFrancesco Petrogalli // independent on the <isa> token.
344cb032aa2SFrancesco Petrogalli const SmallVector<VFParameter, 8> ExpectedParams = {
345cb032aa2SFrancesco Petrogalli VFParameter({0, VFParamKind::Vector, 0}),
346cb032aa2SFrancesco Petrogalli VFParameter({1, VFParamKind::OMP_LinearPos, 2}),
347cb032aa2SFrancesco Petrogalli VFParameter({2, VFParamKind::OMP_LinearValPos, 27}),
348cb032aa2SFrancesco Petrogalli VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}),
349cb032aa2SFrancesco Petrogalli VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}),
350cb032aa2SFrancesco Petrogalli VFParameter({5, VFParamKind::OMP_Linear, 1}),
351cb032aa2SFrancesco Petrogalli VFParameter({6, VFParamKind::OMP_LinearVal, 10}),
352cb032aa2SFrancesco Petrogalli VFParameter({7, VFParamKind::OMP_LinearUVal, 100}),
353cb032aa2SFrancesco Petrogalli VFParameter({8, VFParamKind::OMP_LinearRef, 1000}),
354495f1829SPaul Walker VFParameter({9, VFParamKind::OMP_Uniform, 0}),
355cb032aa2SFrancesco Petrogalli };
356cb032aa2SFrancesco Petrogalli
357cb032aa2SFrancesco Petrogalli #define __COMMON_CHECKS \
358cb032aa2SFrancesco Petrogalli do { \
3598a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2)); \
360cb032aa2SFrancesco Petrogalli EXPECT_FALSE(IsMasked()); \
361cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)10); \
362cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters, ExpectedParams); \
363cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin"); \
364cb032aa2SFrancesco Petrogalli } while (0)
365cb032aa2SFrancesco Petrogalli
366cb032aa2SFrancesco Petrogalli // Advanced SIMD: <isa> = "n"
367495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
368cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
369cb032aa2SFrancesco Petrogalli __COMMON_CHECKS;
370495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
371cb032aa2SFrancesco Petrogalli
372cb032aa2SFrancesco Petrogalli // SVE: <isa> = "s"
373495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
374cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SVE);
375cb032aa2SFrancesco Petrogalli __COMMON_CHECKS;
376495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
377cb032aa2SFrancesco Petrogalli
378cb032aa2SFrancesco Petrogalli // SSE: <isa> = "b"
379495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
380cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SSE);
381cb032aa2SFrancesco Petrogalli __COMMON_CHECKS;
382495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
383cb032aa2SFrancesco Petrogalli
384cb032aa2SFrancesco Petrogalli // AVX: <isa> = "c"
385495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
386cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX);
387cb032aa2SFrancesco Petrogalli __COMMON_CHECKS;
388495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
389cb032aa2SFrancesco Petrogalli
390cb032aa2SFrancesco Petrogalli // AVX2: <isa> = "d"
391495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
392cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX2);
393cb032aa2SFrancesco Petrogalli __COMMON_CHECKS;
394495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
395cb032aa2SFrancesco Petrogalli
396cb032aa2SFrancesco Petrogalli // AVX512: <isa> = "e"
397495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
398cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX512);
399cb032aa2SFrancesco Petrogalli __COMMON_CHECKS;
400495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
401cb032aa2SFrancesco Petrogalli
402d8b6b111SFrancesco Petrogalli // LLVM: <isa> = "_LLVM_" internal vector function.
403623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser(
404495f1829SPaul Walker "_ZGV_LLVM_N2vls2Ls27Us4Rs5l1L10U100R1000u_sin(vectorf)", "vectorf"));
405d8b6b111SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::LLVM);
406d8b6b111SFrancesco Petrogalli __COMMON_CHECKS;
407d8b6b111SFrancesco Petrogalli EXPECT_EQ(VectorName, "vectorf");
408d8b6b111SFrancesco Petrogalli
409cb032aa2SFrancesco Petrogalli // Unknown ISA (randomly using "q"). This test will need update if
410cb032aa2SFrancesco Petrogalli // some targets decide to use "q" as their ISA token.
411495f1829SPaul Walker EXPECT_TRUE(invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
412cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::Unknown);
413cb032aa2SFrancesco Petrogalli __COMMON_CHECKS;
414495f1829SPaul Walker EXPECT_EQ(VectorName, "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
415cb032aa2SFrancesco Petrogalli
416cb032aa2SFrancesco Petrogalli #undef __COMMON_CHECKS
417cb032aa2SFrancesco Petrogalli }
418cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,MissingScalarName)419cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, MissingScalarName) {
420cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
421cb032aa2SFrancesco Petrogalli }
422cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,MissingVectorName)423cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, MissingVectorName) {
424cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()"));
425cb032aa2SFrancesco Petrogalli }
426cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,MissingVectorNameTermination)427cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, MissingVectorNameTermination) {
428cb032aa2SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar"));
429cb032aa2SFrancesco Petrogalli }
430cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseMaskingNEON)431cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseMaskingNEON) {
432cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
4338a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
434cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
435cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
436cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
437cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
438cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
439cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
440cb032aa2SFrancesco Petrogalli }
441cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseMaskingSVE)442cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseMaskingSVE) {
443cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
4448a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
445cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
446cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SVE);
447cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
448cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
449cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
450cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
451cb032aa2SFrancesco Petrogalli }
452cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseMaskingSSE)453cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseMaskingSSE) {
454cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVbM2v_sin"));
4558a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
456cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
457cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::SSE);
458cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
459cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
460cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
461cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
462cb032aa2SFrancesco Petrogalli }
463cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseMaskingAVX)464cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseMaskingAVX) {
465cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVcM2v_sin"));
4668a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
467cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
468cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX);
469cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
470cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
471cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
472cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
473cb032aa2SFrancesco Petrogalli }
474cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseMaskingAVX2)475cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseMaskingAVX2) {
476cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVdM2v_sin"));
4778a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
478cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
479cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX2);
480cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
481cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
482cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
483cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
484cb032aa2SFrancesco Petrogalli }
485cb032aa2SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseMaskingAVX512)486cb032aa2SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseMaskingAVX512) {
487cb032aa2SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGVeM2v_sin"));
4888a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
489cb032aa2SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
490cb032aa2SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::AVX512);
491cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
492cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
493cb032aa2SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
494cb032aa2SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
495cb032aa2SFrancesco Petrogalli }
496e9a06e06SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseMaskingLLVM)4972ea6ab67SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseMaskingLLVM) {
498623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGV_LLVM_M2v_sin(custom_vector_sin)",
499623cff81SFrancesco Petrogalli "custom_vector_sin"));
5008a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(2));
5012ea6ab67SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
5022ea6ab67SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::LLVM);
5032ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
5042ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
5052ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
5062ea6ab67SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
5072ea6ab67SFrancesco Petrogalli EXPECT_EQ(VectorName, "custom_vector_sin");
5082ea6ab67SFrancesco Petrogalli }
5092ea6ab67SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseScalableMaskingLLVM)5102ea6ab67SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseScalableMaskingLLVM) {
511623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser(
512623cff81SFrancesco Petrogalli "_ZGV_LLVM_Mxv_sin(custom_vector_sin)", "custom_vector_sin",
513623cff81SFrancesco Petrogalli "<vscale x 2 x i32> (<vscale x 2 x i32>, <vscale x 2 x i1>)"));
5142ea6ab67SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
5158a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getScalable(2));
5162ea6ab67SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::LLVM);
5172ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
5182ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
5192ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
5202ea6ab67SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sin");
5212ea6ab67SFrancesco Petrogalli EXPECT_EQ(VectorName, "custom_vector_sin");
5222ea6ab67SFrancesco Petrogalli }
5232ea6ab67SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseScalableMaskingLLVMSincos)5242ea6ab67SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseScalableMaskingLLVMSincos) {
525623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGV_LLVM_Mxvl8l8_sincos(custom_vector_sincos)",
526623cff81SFrancesco Petrogalli "custom_vector_sincos",
527623cff81SFrancesco Petrogalli "void(<vscale x 2 x double>, double *, double *)"));
5288a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getScalable(2));
5292ea6ab67SFrancesco Petrogalli EXPECT_TRUE(IsMasked());
5302ea6ab67SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::LLVM);
5312ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)4);
5322ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
5332ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_Linear, 8}));
5342ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_Linear, 8}));
5352ea6ab67SFrancesco Petrogalli EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::GlobalPredicate}));
5362ea6ab67SFrancesco Petrogalli EXPECT_EQ(ScalarName, "sincos");
5372ea6ab67SFrancesco Petrogalli EXPECT_EQ(VectorName, "custom_vector_sincos");
5382ea6ab67SFrancesco Petrogalli }
5392ea6ab67SFrancesco Petrogalli
540e9a06e06SFrancesco Petrogalli class VFABIAttrTest : public testing::Test {
541e9a06e06SFrancesco Petrogalli protected:
SetUp()542e9a06e06SFrancesco Petrogalli void SetUp() override {
543e9a06e06SFrancesco Petrogalli M = parseAssemblyString(IR, Err, Ctx);
544e9a06e06SFrancesco Petrogalli // Get the only call instruction in the block, which is the first
545e9a06e06SFrancesco Petrogalli // instruction.
546e9a06e06SFrancesco Petrogalli CI = dyn_cast<CallInst>(&*(instructions(M->getFunction("f")).begin()));
547e9a06e06SFrancesco Petrogalli }
548e9a06e06SFrancesco Petrogalli const char *IR = "define i32 @f(i32 %a) {\n"
549e9a06e06SFrancesco Petrogalli " %1 = call i32 @g(i32 %a) #0\n"
550e9a06e06SFrancesco Petrogalli " ret i32 %1\n"
551e9a06e06SFrancesco Petrogalli "}\n"
552e9a06e06SFrancesco Petrogalli "declare i32 @g(i32)\n"
553e9a06e06SFrancesco Petrogalli "declare <2 x i32> @custom_vg(<2 x i32>)"
554e9a06e06SFrancesco Petrogalli "declare <4 x i32> @_ZGVnN4v_g(<4 x i32>)"
555e9a06e06SFrancesco Petrogalli "declare <8 x i32> @_ZGVnN8v_g(<8 x i32>)"
556e9a06e06SFrancesco Petrogalli "attributes #0 = { "
557e9a06e06SFrancesco Petrogalli "\"vector-function-abi-variant\"=\""
558e9a06e06SFrancesco Petrogalli "_ZGVnN2v_g(custom_vg),_ZGVnN4v_g\" }";
559e9a06e06SFrancesco Petrogalli LLVMContext Ctx;
560e9a06e06SFrancesco Petrogalli SMDiagnostic Err;
561e9a06e06SFrancesco Petrogalli std::unique_ptr<Module> M;
562e9a06e06SFrancesco Petrogalli CallInst *CI;
563e9a06e06SFrancesco Petrogalli SmallVector<std::string, 8> Mappings;
564e9a06e06SFrancesco Petrogalli };
565e9a06e06SFrancesco Petrogalli
TEST_F(VFABIAttrTest,Read)566e9a06e06SFrancesco Petrogalli TEST_F(VFABIAttrTest, Read) {
567e9a06e06SFrancesco Petrogalli VFABI::getVectorVariantNames(*CI, Mappings);
568e9a06e06SFrancesco Petrogalli SmallVector<std::string, 8> Exp;
569e9a06e06SFrancesco Petrogalli Exp.push_back("_ZGVnN2v_g(custom_vg)");
570e9a06e06SFrancesco Petrogalli Exp.push_back("_ZGVnN4v_g");
571e9a06e06SFrancesco Petrogalli EXPECT_EQ(Mappings, Exp);
572e9a06e06SFrancesco Petrogalli }
573d8b6b111SFrancesco Petrogalli
TEST_F(VFABIParserTest,LLVM_InternalISA)574d8b6b111SFrancesco Petrogalli TEST_F(VFABIParserTest, LLVM_InternalISA) {
575d8b6b111SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
576623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name"));
577d8b6b111SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::LLVM);
578d8b6b111SFrancesco Petrogalli }
57966c120f0SFrancesco Petrogalli
TEST_F(VFABIParserTest,IntrinsicsInLLVMIsa)58066c120f0SFrancesco Petrogalli TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) {
581623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser("_ZGV_LLVM_N4vv_llvm.pow.f32(__svml_powf4)",
582623cff81SFrancesco Petrogalli "__svml_powf4"));
5838a8d01d5SPaul Walker EXPECT_EQ(VF, ElementCount::getFixed(4));
58466c120f0SFrancesco Petrogalli EXPECT_FALSE(IsMasked());
58566c120f0SFrancesco Petrogalli EXPECT_EQ(ISA, VFISAKind::LLVM);
58666c120f0SFrancesco Petrogalli EXPECT_EQ(Parameters.size(), (unsigned)2);
58766c120f0SFrancesco Petrogalli EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
58866c120f0SFrancesco Petrogalli EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::Vector}));
58966c120f0SFrancesco Petrogalli EXPECT_EQ(ScalarName, "llvm.pow.f32");
59066c120f0SFrancesco Petrogalli }
591623cff81SFrancesco Petrogalli
TEST_F(VFABIParserTest,ParseScalableRequiresDeclaration)592623cff81SFrancesco Petrogalli TEST_F(VFABIParserTest, ParseScalableRequiresDeclaration) {
593623cff81SFrancesco Petrogalli const char *MangledName = "_ZGVsMxv_sin(custom_vg)";
594623cff81SFrancesco Petrogalli // The parser succeds only when the correct function definition of
595623cff81SFrancesco Petrogalli // `custom_vg` is added to the module.
596623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser(MangledName));
597623cff81SFrancesco Petrogalli EXPECT_TRUE(invokeParser(
598623cff81SFrancesco Petrogalli MangledName, "custom_vg",
599623cff81SFrancesco Petrogalli "<vscale x 4 x double>(<vscale x 4 x double>, <vscale x 4 x i1>)"));
600623cff81SFrancesco Petrogalli }
601623cff81SFrancesco Petrogalli
TEST_F(VFABIParserTest,ZeroIsInvalidVLEN)602623cff81SFrancesco Petrogalli TEST_F(VFABIParserTest, ZeroIsInvalidVLEN) {
603623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVeM0v_sin"));
604623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVeN0v_sin"));
605623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsM0v_sin"));
606623cff81SFrancesco Petrogalli EXPECT_FALSE(invokeParser("_ZGVsN0v_sin"));
607623cff81SFrancesco Petrogalli }
6082e58004fSSanne Wouda
parseIR(LLVMContext & C,const char * IR)6092e58004fSSanne Wouda static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
6102e58004fSSanne Wouda SMDiagnostic Err;
6112e58004fSSanne Wouda std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
6122e58004fSSanne Wouda if (!Mod)
6132e58004fSSanne Wouda Err.print("VectorFunctionABITests", errs());
6142e58004fSSanne Wouda return Mod;
6152e58004fSSanne Wouda }
6162e58004fSSanne Wouda
TEST(VFABIGetMappingsTest,IndirectCallInst)6172e58004fSSanne Wouda TEST(VFABIGetMappingsTest, IndirectCallInst) {
6182e58004fSSanne Wouda LLVMContext C;
6192e58004fSSanne Wouda std::unique_ptr<Module> M = parseIR(C, R"IR(
6202e58004fSSanne Wouda define void @call(void () * %f) {
6212e58004fSSanne Wouda entry:
6222e58004fSSanne Wouda call void %f()
6232e58004fSSanne Wouda ret void
6242e58004fSSanne Wouda }
6252e58004fSSanne Wouda )IR");
6262e58004fSSanne Wouda auto F = dyn_cast_or_null<Function>(M->getNamedValue("call"));
6272e58004fSSanne Wouda ASSERT_TRUE(F);
6282e58004fSSanne Wouda auto CI = dyn_cast<CallInst>(&F->front().front());
6292e58004fSSanne Wouda ASSERT_TRUE(CI);
6302e58004fSSanne Wouda ASSERT_TRUE(CI->isIndirectCall());
6312e58004fSSanne Wouda auto Mappings = VFDatabase::getMappings(*CI);
6322e58004fSSanne Wouda EXPECT_EQ(Mappings.size(), (unsigned)0);
6332e58004fSSanne Wouda }
634