blob: 466993161fe1abf3169e483ceed1c1bdffdf3b3d [file] [log] [blame]
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +00001//===------- 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"
Francesco Petrogallic63b6db2019-10-30 19:08:21 +000010#include "llvm/AsmParser/Parser.h"
11#include "llvm/IR/InstIterator.h"
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +000012#include "gtest/gtest.h"
13
14using namespace llvm;
15
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +000016namespace {
17// Test fixture needed that holds the veariables needed by the parser.
18class VFABIParserTest : public ::testing::Test {
19private:
20 // Parser output.
21 VFInfo Info;
Francesco Petrogallica1f9f52020-01-22 22:34:27 +000022 // Reset the data needed for the test.
23 void reset(const StringRef Name, const StringRef IRType) {
24 M = parseAssemblyString("declare void @dummy()", Err, Ctx);
25 EXPECT_NE(M.get(), nullptr) << "Loading an invalid module.\n "
26 << Err.getMessage() << "\n";
27 Type *Ty = parseType(IRType, Err, *(M.get()));
28 FunctionType *FTy = dyn_cast<FunctionType>(Ty);
29 EXPECT_NE(FTy, nullptr) << "Invalid function type string: " << IRType
30 << "\n"
31 << Err.getMessage() << "\n";
32 FunctionCallee F = M->getOrInsertFunction(Name, FTy);
33 EXPECT_NE(F.getCallee(), nullptr)
34 << "The function must be present in the module\n";
35 // Reset the VFInfo
36 Info = VFInfo();
37 }
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +000038
Francesco Petrogallica1f9f52020-01-22 22:34:27 +000039 // Data needed to load the optional IR passed to invokeParser
40 LLVMContext Ctx;
41 SMDiagnostic Err;
42 std::unique_ptr<Module> M;
43 // CallInst *CI;
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +000044protected:
45 // Referencies to the parser output field.
Paul Walkerf5634cd2021-07-24 16:34:20 +010046 ElementCount &VF = Info.Shape.VF;
Francesco Petrogalli7b280132019-11-20 20:51:24 +000047 VFISAKind &ISA = Info.ISA;
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +000048 SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters;
Francesco Petrogalliab20a932019-12-13 19:43:26 +000049 std::string &ScalarName = Info.ScalarName;
50 std::string &VectorName = Info.VectorName;
Francesco Petrogallica1f9f52020-01-22 22:34:27 +000051 // Invoke the parser. We need to make sure that a function exist in
52 // the module because the parser fails if such function don't
53 // exists. Every time this method is invoked the state of the test
54 // is reset.
55 //
56 // \p MangledName -> the string the parser has to demangle.
57 //
58 // \p VectorName -> optional vector name that the method needs to
59 // use to create the function in the module if it differs from the
60 // standard mangled name.
61 //
62 // \p IRType -> FunctionType string to be used for the signature of
63 // the vector function. The correct signature is needed by the
64 // parser only for scalable functions. For the sake of testing, the
65 // generic fixed-length case can use as signature `void()`.
66 //
67 bool invokeParser(const StringRef MangledName,
68 const StringRef VectorName = "",
69 const StringRef IRType = "void()") {
70 StringRef Name = MangledName;
71 if (!VectorName.empty())
72 Name = VectorName;
73 // Reset the VFInfo and the Module to be able to invoke
74 // `invokeParser` multiple times in the same test.
75 reset(Name, IRType);
76
77 const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, *(M.get()));
Kazu Hiratabd701d32022-06-25 21:42:52 -070078 if (OptInfo) {
Fangrui Songb9b07ce2022-12-17 01:42:39 +000079 Info = *OptInfo;
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +000080 return true;
81 }
82
83 return false;
84 }
Anna Thomasd9ab34e2020-05-13 11:01:23 -040085
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +000086 // Checks that 1. the last Parameter in the Shape is of type
87 // VFParamKind::GlobalPredicate and 2. it is the only one of such
88 // type.
89 bool IsMasked() const {
90 const auto NGlobalPreds =
91 std::count_if(Info.Shape.Parameters.begin(),
92 Info.Shape.Parameters.end(), [](const VFParameter PK) {
93 return PK.ParamKind == VFParamKind::GlobalPredicate;
94 });
95 return NGlobalPreds == 1 && Info.Shape.Parameters.back().ParamKind ==
96 VFParamKind::GlobalPredicate;
97 }
98};
99} // unnamed namespace
100
Anna Thomasd9ab34e2020-05-13 11:01:23 -0400101// This test makes sure correct mangling occurs for given string.
102TEST_F(VFABIParserTest, ManglingVectorTLINames) {
David Sherwood998f0332021-02-08 17:16:03 +0000103 EXPECT_EQ(
104 VFABI::mangleTLIVectorName("vec", "scalar", 3, ElementCount::getFixed(4)),
105 "_ZGV_LLVM_N4vvv_scalar(vec)");
106 EXPECT_EQ(VFABI::mangleTLIVectorName("vec", "scalar", 3,
107 ElementCount::getScalable(4)),
108 "_ZGV_LLVM_Nxvvv_scalar(vec)");
109 EXPECT_EQ(VFABI::mangleTLIVectorName("custom.call.v5", "custom.call", 1,
110 ElementCount::getFixed(5)),
Anna Thomasd9ab34e2020-05-13 11:01:23 -0400111 "_ZGV_LLVM_N5v_custom.call(custom.call.v5)");
112}
113
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000114// This test makes sure that the demangling method succeeds only on
115// valid values of the string.
116TEST_F(VFABIParserTest, OnlyValidNames) {
117 // Incomplete string.
118 EXPECT_FALSE(invokeParser(""));
119 EXPECT_FALSE(invokeParser("_ZGV"));
120 EXPECT_FALSE(invokeParser("_ZGVn"));
121 EXPECT_FALSE(invokeParser("_ZGVnN"));
122 EXPECT_FALSE(invokeParser("_ZGVnN2"));
123 EXPECT_FALSE(invokeParser("_ZGVnN2v"));
124 EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
125 // Missing parameters.
126 EXPECT_FALSE(invokeParser("_ZGVnN2_foo"));
127 // Missing _ZGV prefix.
128 EXPECT_FALSE(invokeParser("_ZVnN2v_foo"));
129 // Missing <isa>.
130 EXPECT_FALSE(invokeParser("_ZGVN2v_foo"));
131 // Missing <mask>.
132 EXPECT_FALSE(invokeParser("_ZGVn2v_foo"));
133 // Missing <vlen>.
134 EXPECT_FALSE(invokeParser("_ZGVnNv_foo"));
135 // Missing <scalarname>.
136 EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
137 // Missing _ separator.
138 EXPECT_FALSE(invokeParser("_ZGVnN2vfoo"));
139 // Missing <vectorname>. Using `fakename` because the string being
140 // parsed is not a valid function name that `invokeParser` can add.
141 EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()", "fakename"));
142 // Unterminated name. Using `fakename` because the string being
143 // parsed is not a valid function name that `invokeParser` can add.
144 EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar", "fakename"));
145}
146
147TEST_F(VFABIParserTest, ParamListParsing) {
148 EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo"));
149 EXPECT_EQ(Parameters.size(), (unsigned)5);
150 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
151 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_Linear, 16}));
152 EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 32}));
153 EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, 3}));
154 EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, 1}));
155}
156
157TEST_F(VFABIParserTest, ScalarNameAndVectorName_01) {
158 EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
159 EXPECT_EQ(ScalarName, "sin");
160 EXPECT_EQ(VectorName, "_ZGVnM2v_sin");
161}
162
163TEST_F(VFABIParserTest, ScalarNameAndVectorName_02) {
164 EXPECT_TRUE(invokeParser("_ZGVnM2v_sin(UserFunc)", "UserFunc"));
165 EXPECT_EQ(ScalarName, "sin");
166 EXPECT_EQ(VectorName, "UserFunc");
167}
168
169TEST_F(VFABIParserTest, ScalarNameAndVectorName_03) {
170 EXPECT_TRUE(invokeParser("_ZGVnM2v___sin_sin_sin"));
171 EXPECT_EQ(ScalarName, "__sin_sin_sin");
172 EXPECT_EQ(VectorName, "_ZGVnM2v___sin_sin_sin");
173}
174
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000175TEST_F(VFABIParserTest, Parse) {
176 EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100177 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000178 EXPECT_FALSE(IsMasked());
179 EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000180 EXPECT_EQ(Parameters.size(), (unsigned)9);
181 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
182 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearPos, 2}));
183 EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearValPos, 27}));
184 EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}));
185 EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}));
186 EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_Linear, 1}));
187 EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearVal, 10}));
188 EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, 100}));
189 EXPECT_EQ(Parameters[8], VFParameter({8, VFParamKind::OMP_LinearRef, 1000}));
190 EXPECT_EQ(ScalarName, "sin");
191 EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin");
192}
193
194TEST_F(VFABIParserTest, ParseVectorName) {
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000195 EXPECT_TRUE(invokeParser("_ZGVnN2v_sin(my_v_sin)", "my_v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100196 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000197 EXPECT_FALSE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000198 EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
199 EXPECT_EQ(Parameters.size(), (unsigned)1);
200 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector, 0}));
201 EXPECT_EQ(ScalarName, "sin");
202 EXPECT_EQ(VectorName, "my_v_sin");
203}
204
205TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) {
206 EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100207 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000208 EXPECT_FALSE(IsMasked());
209 EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000210 EXPECT_EQ(Parameters.size(), (unsigned)4);
211 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, -1}));
212 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, -10}));
213 EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearUVal, -100}));
214 EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearRef, -1000}));
215 EXPECT_EQ(ScalarName, "sin");
216 EXPECT_EQ(VectorName, "_ZGVnN2ln1Ln10Un100Rn1000_sin");
217}
218
219TEST_F(VFABIParserTest, ParseScalableSVE) {
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000220 EXPECT_TRUE(invokeParser(
221 "_ZGVsMxv_sin(custom_vg)", "custom_vg",
222 "<vscale x 2 x i32>(<vscale x 2 x i32>, <vscale x 2 x i1>)"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100223 EXPECT_EQ(VF, ElementCount::getScalable(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000224 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000225 EXPECT_EQ(ISA, VFISAKind::SVE);
226 EXPECT_EQ(ScalarName, "sin");
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000227 EXPECT_EQ(VectorName, "custom_vg");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000228}
229
230TEST_F(VFABIParserTest, ParseFixedWidthSVE) {
231 EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100232 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000233 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000234 EXPECT_EQ(ISA, VFISAKind::SVE);
235 EXPECT_EQ(ScalarName, "sin");
236 EXPECT_EQ(VectorName, "_ZGVsM2v_sin");
237}
238
239TEST_F(VFABIParserTest, NotAVectorFunctionABIName) {
240 // Vector names should start with `_ZGV`.
241 EXPECT_FALSE(invokeParser("ZGVnN2v_sin"));
242}
243
244TEST_F(VFABIParserTest, LinearWithRuntimeStep) {
245 EXPECT_FALSE(invokeParser("_ZGVnN2ls_sin"))
246 << "A number should be present after \"ls\".";
247 EXPECT_TRUE(invokeParser("_ZGVnN2ls2_sin"));
248 EXPECT_FALSE(invokeParser("_ZGVnN2Rs_sin"))
249 << "A number should be present after \"Rs\".";
250 EXPECT_TRUE(invokeParser("_ZGVnN2Rs4_sin"));
251 EXPECT_FALSE(invokeParser("_ZGVnN2Ls_sin"))
252 << "A number should be present after \"Ls\".";
253 EXPECT_TRUE(invokeParser("_ZGVnN2Ls6_sin"));
254 EXPECT_FALSE(invokeParser("_ZGVnN2Us_sin"))
255 << "A number should be present after \"Us\".";
256 EXPECT_TRUE(invokeParser("_ZGVnN2Us8_sin"));
257}
258
259TEST_F(VFABIParserTest, LinearWithoutCompileTime) {
260 EXPECT_TRUE(invokeParser("_ZGVnN3lLRUlnLnRnUn_sin"));
261 EXPECT_EQ(Parameters.size(), (unsigned)8);
262 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Linear, 1}));
263 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_LinearVal, 1}));
264 EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_LinearRef, 1}));
265 EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::OMP_LinearUVal, 1}));
266 EXPECT_EQ(Parameters[4], VFParameter({4, VFParamKind::OMP_Linear, -1}));
267 EXPECT_EQ(Parameters[5], VFParameter({5, VFParamKind::OMP_LinearVal, -1}));
268 EXPECT_EQ(Parameters[6], VFParameter({6, VFParamKind::OMP_LinearRef, -1}));
269 EXPECT_EQ(Parameters[7], VFParameter({7, VFParamKind::OMP_LinearUVal, -1}));
270}
271
272TEST_F(VFABIParserTest, ISA) {
273 EXPECT_TRUE(invokeParser("_ZGVqN2v_sin"));
274 EXPECT_EQ(ISA, VFISAKind::Unknown);
275
276 EXPECT_TRUE(invokeParser("_ZGVnN2v_sin"));
277 EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
278
279 EXPECT_TRUE(invokeParser("_ZGVsN2v_sin"));
280 EXPECT_EQ(ISA, VFISAKind::SVE);
281
282 EXPECT_TRUE(invokeParser("_ZGVbN2v_sin"));
283 EXPECT_EQ(ISA, VFISAKind::SSE);
284
285 EXPECT_TRUE(invokeParser("_ZGVcN2v_sin"));
286 EXPECT_EQ(ISA, VFISAKind::AVX);
287
288 EXPECT_TRUE(invokeParser("_ZGVdN2v_sin"));
289 EXPECT_EQ(ISA, VFISAKind::AVX2);
290
291 EXPECT_TRUE(invokeParser("_ZGVeN2v_sin"));
292 EXPECT_EQ(ISA, VFISAKind::AVX512);
293}
294
Francesco Petrogalliab20a932019-12-13 19:43:26 +0000295TEST_F(VFABIParserTest, LLVM_ISA) {
296 EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000297 EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name"));
Francesco Petrogalliab20a932019-12-13 19:43:26 +0000298 EXPECT_EQ(ISA, VFISAKind::LLVM);
299}
300
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000301TEST_F(VFABIParserTest, InvalidMask) {
302 EXPECT_FALSE(invokeParser("_ZGVsK2v_sin"));
303}
304
305TEST_F(VFABIParserTest, InvalidParameter) {
306 EXPECT_FALSE(invokeParser("_ZGVsM2vX_sin"));
307}
308
309TEST_F(VFABIParserTest, Align) {
310 EXPECT_TRUE(invokeParser("_ZGVsN2l2a2_sin"));
311 EXPECT_EQ(Parameters.size(), (unsigned)1);
312 EXPECT_EQ(Parameters[0].Alignment, Align(2));
313
James Henderson7d272442020-01-06 10:15:44 +0000314 // Missing alignment value.
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000315 EXPECT_FALSE(invokeParser("_ZGVsM2l2a_sin"));
316 // Invalid alignment token "x".
317 EXPECT_FALSE(invokeParser("_ZGVsM2l2ax_sin"));
318 // Alignment MUST be associated to a paramater.
319 EXPECT_FALSE(invokeParser("_ZGVsM2a2_sin"));
320 // Alignment must be a power of 2.
321 EXPECT_FALSE(invokeParser("_ZGVsN2l2a0_sin"));
322 EXPECT_TRUE(invokeParser("_ZGVsN2l2a1_sin"));
323 EXPECT_FALSE(invokeParser("_ZGVsN2l2a3_sin"));
324 EXPECT_FALSE(invokeParser("_ZGVsN2l2a6_sin"));
325}
326
327TEST_F(VFABIParserTest, ParseUniform) {
Paul Walkerb1142172020-05-26 16:54:02 +0000328 EXPECT_TRUE(invokeParser("_ZGVnN2u_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100329 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000330 EXPECT_FALSE(IsMasked());
331 EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000332 EXPECT_EQ(Parameters.size(), (unsigned)1);
333 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Uniform, 0}));
334 EXPECT_EQ(ScalarName, "sin");
Paul Walkerb1142172020-05-26 16:54:02 +0000335 EXPECT_EQ(VectorName, "_ZGVnN2u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000336
Paul Walkerb1142172020-05-26 16:54:02 +0000337 // Uniform doesn't expect extra data.
338 EXPECT_FALSE(invokeParser("_ZGVnN2u0_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000339}
340
341TEST_F(VFABIParserTest, ISAIndependentMangling) {
342 // This test makes sure that the mangling of the parameters in
343 // independent on the <isa> token.
344 const SmallVector<VFParameter, 8> ExpectedParams = {
345 VFParameter({0, VFParamKind::Vector, 0}),
346 VFParameter({1, VFParamKind::OMP_LinearPos, 2}),
347 VFParameter({2, VFParamKind::OMP_LinearValPos, 27}),
348 VFParameter({3, VFParamKind::OMP_LinearUValPos, 4}),
349 VFParameter({4, VFParamKind::OMP_LinearRefPos, 5}),
350 VFParameter({5, VFParamKind::OMP_Linear, 1}),
351 VFParameter({6, VFParamKind::OMP_LinearVal, 10}),
352 VFParameter({7, VFParamKind::OMP_LinearUVal, 100}),
353 VFParameter({8, VFParamKind::OMP_LinearRef, 1000}),
Paul Walkerb1142172020-05-26 16:54:02 +0000354 VFParameter({9, VFParamKind::OMP_Uniform, 0}),
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000355 };
356
357#define __COMMON_CHECKS \
358 do { \
Paul Walkerf5634cd2021-07-24 16:34:20 +0100359 EXPECT_EQ(VF, ElementCount::getFixed(2)); \
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000360 EXPECT_FALSE(IsMasked()); \
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000361 EXPECT_EQ(Parameters.size(), (unsigned)10); \
362 EXPECT_EQ(Parameters, ExpectedParams); \
363 EXPECT_EQ(ScalarName, "sin"); \
364 } while (0)
365
366 // Advanced SIMD: <isa> = "n"
Paul Walkerb1142172020-05-26 16:54:02 +0000367 EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000368 EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
369 __COMMON_CHECKS;
Paul Walkerb1142172020-05-26 16:54:02 +0000370 EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000371
372 // SVE: <isa> = "s"
Paul Walkerb1142172020-05-26 16:54:02 +0000373 EXPECT_TRUE(invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000374 EXPECT_EQ(ISA, VFISAKind::SVE);
375 __COMMON_CHECKS;
Paul Walkerb1142172020-05-26 16:54:02 +0000376 EXPECT_EQ(VectorName, "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000377
378 // SSE: <isa> = "b"
Paul Walkerb1142172020-05-26 16:54:02 +0000379 EXPECT_TRUE(invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000380 EXPECT_EQ(ISA, VFISAKind::SSE);
381 __COMMON_CHECKS;
Paul Walkerb1142172020-05-26 16:54:02 +0000382 EXPECT_EQ(VectorName, "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000383
384 // AVX: <isa> = "c"
Paul Walkerb1142172020-05-26 16:54:02 +0000385 EXPECT_TRUE(invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000386 EXPECT_EQ(ISA, VFISAKind::AVX);
387 __COMMON_CHECKS;
Paul Walkerb1142172020-05-26 16:54:02 +0000388 EXPECT_EQ(VectorName, "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000389
390 // AVX2: <isa> = "d"
Paul Walkerb1142172020-05-26 16:54:02 +0000391 EXPECT_TRUE(invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000392 EXPECT_EQ(ISA, VFISAKind::AVX2);
393 __COMMON_CHECKS;
Paul Walkerb1142172020-05-26 16:54:02 +0000394 EXPECT_EQ(VectorName, "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000395
396 // AVX512: <isa> = "e"
Paul Walkerb1142172020-05-26 16:54:02 +0000397 EXPECT_TRUE(invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000398 EXPECT_EQ(ISA, VFISAKind::AVX512);
399 __COMMON_CHECKS;
Paul Walkerb1142172020-05-26 16:54:02 +0000400 EXPECT_EQ(VectorName, "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000401
Francesco Petrogalli9bc06d02019-11-11 16:48:51 +0000402 // LLVM: <isa> = "_LLVM_" internal vector function.
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000403 EXPECT_TRUE(invokeParser(
Paul Walkerb1142172020-05-26 16:54:02 +0000404 "_ZGV_LLVM_N2vls2Ls27Us4Rs5l1L10U100R1000u_sin(vectorf)", "vectorf"));
Francesco Petrogalli9bc06d02019-11-11 16:48:51 +0000405 EXPECT_EQ(ISA, VFISAKind::LLVM);
406 __COMMON_CHECKS;
407 EXPECT_EQ(VectorName, "vectorf");
408
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000409 // Unknown ISA (randomly using "q"). This test will need update if
410 // some targets decide to use "q" as their ISA token.
Paul Walkerb1142172020-05-26 16:54:02 +0000411 EXPECT_TRUE(invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000412 EXPECT_EQ(ISA, VFISAKind::Unknown);
413 __COMMON_CHECKS;
Paul Walkerb1142172020-05-26 16:54:02 +0000414 EXPECT_EQ(VectorName, "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin");
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000415
416#undef __COMMON_CHECKS
417}
418
419TEST_F(VFABIParserTest, MissingScalarName) {
420 EXPECT_FALSE(invokeParser("_ZGVnN2v_"));
421}
422
423TEST_F(VFABIParserTest, MissingVectorName) {
424 EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()"));
425}
426
427TEST_F(VFABIParserTest, MissingVectorNameTermination) {
428 EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar"));
429}
430
431TEST_F(VFABIParserTest, ParseMaskingNEON) {
432 EXPECT_TRUE(invokeParser("_ZGVnM2v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100433 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000434 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000435 EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD);
436 EXPECT_EQ(Parameters.size(), (unsigned)2);
437 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
438 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
439 EXPECT_EQ(ScalarName, "sin");
440}
441
442TEST_F(VFABIParserTest, ParseMaskingSVE) {
443 EXPECT_TRUE(invokeParser("_ZGVsM2v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100444 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000445 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000446 EXPECT_EQ(ISA, VFISAKind::SVE);
447 EXPECT_EQ(Parameters.size(), (unsigned)2);
448 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
449 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
450 EXPECT_EQ(ScalarName, "sin");
451}
452
453TEST_F(VFABIParserTest, ParseMaskingSSE) {
454 EXPECT_TRUE(invokeParser("_ZGVbM2v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100455 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000456 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000457 EXPECT_EQ(ISA, VFISAKind::SSE);
458 EXPECT_EQ(Parameters.size(), (unsigned)2);
459 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
460 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
461 EXPECT_EQ(ScalarName, "sin");
462}
463
464TEST_F(VFABIParserTest, ParseMaskingAVX) {
465 EXPECT_TRUE(invokeParser("_ZGVcM2v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100466 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000467 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000468 EXPECT_EQ(ISA, VFISAKind::AVX);
469 EXPECT_EQ(Parameters.size(), (unsigned)2);
470 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
471 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
472 EXPECT_EQ(ScalarName, "sin");
473}
474
475TEST_F(VFABIParserTest, ParseMaskingAVX2) {
476 EXPECT_TRUE(invokeParser("_ZGVdM2v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100477 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000478 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000479 EXPECT_EQ(ISA, VFISAKind::AVX2);
480 EXPECT_EQ(Parameters.size(), (unsigned)2);
481 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
482 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
483 EXPECT_EQ(ScalarName, "sin");
484}
485
486TEST_F(VFABIParserTest, ParseMaskingAVX512) {
487 EXPECT_TRUE(invokeParser("_ZGVeM2v_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100488 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000489 EXPECT_TRUE(IsMasked());
Francesco Petrogalli82ca42a2019-09-19 17:47:32 +0000490 EXPECT_EQ(ISA, VFISAKind::AVX512);
491 EXPECT_EQ(Parameters.size(), (unsigned)2);
492 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
493 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
494 EXPECT_EQ(ScalarName, "sin");
495}
Francesco Petrogallic63b6db2019-10-30 19:08:21 +0000496
Francesco Petrogallie0e1d4d2019-12-06 20:32:18 +0000497TEST_F(VFABIParserTest, ParseMaskingLLVM) {
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000498 EXPECT_TRUE(invokeParser("_ZGV_LLVM_M2v_sin(custom_vector_sin)",
499 "custom_vector_sin"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100500 EXPECT_EQ(VF, ElementCount::getFixed(2));
Francesco Petrogallie0e1d4d2019-12-06 20:32:18 +0000501 EXPECT_TRUE(IsMasked());
Francesco Petrogallie0e1d4d2019-12-06 20:32:18 +0000502 EXPECT_EQ(ISA, VFISAKind::LLVM);
503 EXPECT_EQ(Parameters.size(), (unsigned)2);
504 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
505 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
506 EXPECT_EQ(ScalarName, "sin");
507 EXPECT_EQ(VectorName, "custom_vector_sin");
508}
509
510TEST_F(VFABIParserTest, ParseScalableMaskingLLVM) {
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000511 EXPECT_TRUE(invokeParser(
512 "_ZGV_LLVM_Mxv_sin(custom_vector_sin)", "custom_vector_sin",
513 "<vscale x 2 x i32> (<vscale x 2 x i32>, <vscale x 2 x i1>)"));
Francesco Petrogallie0e1d4d2019-12-06 20:32:18 +0000514 EXPECT_TRUE(IsMasked());
Paul Walkerf5634cd2021-07-24 16:34:20 +0100515 EXPECT_EQ(VF, ElementCount::getScalable(2));
Francesco Petrogallie0e1d4d2019-12-06 20:32:18 +0000516 EXPECT_EQ(ISA, VFISAKind::LLVM);
517 EXPECT_EQ(Parameters.size(), (unsigned)2);
518 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
519 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::GlobalPredicate}));
520 EXPECT_EQ(ScalarName, "sin");
521 EXPECT_EQ(VectorName, "custom_vector_sin");
522}
523
524TEST_F(VFABIParserTest, ParseScalableMaskingLLVMSincos) {
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000525 EXPECT_TRUE(invokeParser("_ZGV_LLVM_Mxvl8l8_sincos(custom_vector_sincos)",
526 "custom_vector_sincos",
527 "void(<vscale x 2 x double>, double *, double *)"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100528 EXPECT_EQ(VF, ElementCount::getScalable(2));
Francesco Petrogallie0e1d4d2019-12-06 20:32:18 +0000529 EXPECT_TRUE(IsMasked());
Francesco Petrogallie0e1d4d2019-12-06 20:32:18 +0000530 EXPECT_EQ(ISA, VFISAKind::LLVM);
531 EXPECT_EQ(Parameters.size(), (unsigned)4);
532 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
533 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::OMP_Linear, 8}));
534 EXPECT_EQ(Parameters[2], VFParameter({2, VFParamKind::OMP_Linear, 8}));
535 EXPECT_EQ(Parameters[3], VFParameter({3, VFParamKind::GlobalPredicate}));
536 EXPECT_EQ(ScalarName, "sincos");
537 EXPECT_EQ(VectorName, "custom_vector_sincos");
538}
539
Francesco Petrogallic63b6db2019-10-30 19:08:21 +0000540class VFABIAttrTest : public testing::Test {
541protected:
542 void SetUp() override {
543 M = parseAssemblyString(IR, Err, Ctx);
544 // Get the only call instruction in the block, which is the first
545 // instruction.
546 CI = dyn_cast<CallInst>(&*(instructions(M->getFunction("f")).begin()));
547 }
548 const char *IR = "define i32 @f(i32 %a) {\n"
549 " %1 = call i32 @g(i32 %a) #0\n"
550 " ret i32 %1\n"
551 "}\n"
552 "declare i32 @g(i32)\n"
553 "declare <2 x i32> @custom_vg(<2 x i32>)"
554 "declare <4 x i32> @_ZGVnN4v_g(<4 x i32>)"
555 "declare <8 x i32> @_ZGVnN8v_g(<8 x i32>)"
556 "attributes #0 = { "
557 "\"vector-function-abi-variant\"=\""
558 "_ZGVnN2v_g(custom_vg),_ZGVnN4v_g\" }";
559 LLVMContext Ctx;
560 SMDiagnostic Err;
561 std::unique_ptr<Module> M;
562 CallInst *CI;
563 SmallVector<std::string, 8> Mappings;
564};
565
566TEST_F(VFABIAttrTest, Read) {
567 VFABI::getVectorVariantNames(*CI, Mappings);
568 SmallVector<std::string, 8> Exp;
569 Exp.push_back("_ZGVnN2v_g(custom_vg)");
570 Exp.push_back("_ZGVnN4v_g");
571 EXPECT_EQ(Mappings, Exp);
572}
Francesco Petrogalli9bc06d02019-11-11 16:48:51 +0000573
574TEST_F(VFABIParserTest, LLVM_InternalISA) {
575 EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000576 EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name"));
Francesco Petrogalli9bc06d02019-11-11 16:48:51 +0000577 EXPECT_EQ(ISA, VFISAKind::LLVM);
578}
Francesco Petrogalliab20a932019-12-13 19:43:26 +0000579
580TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) {
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000581 EXPECT_TRUE(invokeParser("_ZGV_LLVM_N4vv_llvm.pow.f32(__svml_powf4)",
582 "__svml_powf4"));
Paul Walkerf5634cd2021-07-24 16:34:20 +0100583 EXPECT_EQ(VF, ElementCount::getFixed(4));
Francesco Petrogalliab20a932019-12-13 19:43:26 +0000584 EXPECT_FALSE(IsMasked());
Francesco Petrogalliab20a932019-12-13 19:43:26 +0000585 EXPECT_EQ(ISA, VFISAKind::LLVM);
586 EXPECT_EQ(Parameters.size(), (unsigned)2);
587 EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
588 EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::Vector}));
589 EXPECT_EQ(ScalarName, "llvm.pow.f32");
590}
Francesco Petrogallica1f9f52020-01-22 22:34:27 +0000591
592TEST_F(VFABIParserTest, ParseScalableRequiresDeclaration) {
593 const char *MangledName = "_ZGVsMxv_sin(custom_vg)";
594 // The parser succeds only when the correct function definition of
595 // `custom_vg` is added to the module.
596 EXPECT_FALSE(invokeParser(MangledName));
597 EXPECT_TRUE(invokeParser(
598 MangledName, "custom_vg",
599 "<vscale x 4 x double>(<vscale x 4 x double>, <vscale x 4 x i1>)"));
600}
601
602TEST_F(VFABIParserTest, ZeroIsInvalidVLEN) {
603 EXPECT_FALSE(invokeParser("_ZGVeM0v_sin"));
604 EXPECT_FALSE(invokeParser("_ZGVeN0v_sin"));
605 EXPECT_FALSE(invokeParser("_ZGVsM0v_sin"));
606 EXPECT_FALSE(invokeParser("_ZGVsN0v_sin"));
607}
Sanne Wouda53514412020-06-25 16:08:13 +0100608
609static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
610 SMDiagnostic Err;
611 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
612 if (!Mod)
613 Err.print("VectorFunctionABITests", errs());
614 return Mod;
615}
616
617TEST(VFABIGetMappingsTest, IndirectCallInst) {
618 LLVMContext C;
619 std::unique_ptr<Module> M = parseIR(C, R"IR(
620define void @call(void () * %f) {
621entry:
622 call void %f()
623 ret void
624}
625)IR");
626 auto F = dyn_cast_or_null<Function>(M->getNamedValue("call"));
627 ASSERT_TRUE(F);
628 auto CI = dyn_cast<CallInst>(&F->front().front());
629 ASSERT_TRUE(CI);
630 ASSERT_TRUE(CI->isIndirectCall());
631 auto Mappings = VFDatabase::getMappings(*CI);
632 EXPECT_EQ(Mappings.size(), (unsigned)0);
633}