Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 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" |
Francesco Petrogalli | c63b6db | 2019-10-30 19:08:21 +0000 | [diff] [blame] | 10 | #include "llvm/AsmParser/Parser.h" |
| 11 | #include "llvm/IR/InstIterator.h" |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 12 | #include "gtest/gtest.h" |
| 13 | |
| 14 | using namespace llvm; |
| 15 | |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 16 | namespace { |
| 17 | // Test fixture needed that holds the veariables needed by the parser. |
| 18 | class VFABIParserTest : public ::testing::Test { |
| 19 | private: |
| 20 | // Parser output. |
| 21 | VFInfo Info; |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 22 | // 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 Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 38 | |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 39 | // 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 Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 44 | protected: |
| 45 | // Referencies to the parser output field. |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 46 | ElementCount &VF = Info.Shape.VF; |
Francesco Petrogalli | 7b28013 | 2019-11-20 20:51:24 +0000 | [diff] [blame] | 47 | VFISAKind &ISA = Info.ISA; |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 48 | SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters; |
Francesco Petrogalli | ab20a93 | 2019-12-13 19:43:26 +0000 | [diff] [blame] | 49 | std::string &ScalarName = Info.ScalarName; |
| 50 | std::string &VectorName = Info.VectorName; |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 51 | // 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 Hirata | bd701d3 | 2022-06-25 21:42:52 -0700 | [diff] [blame] | 78 | if (OptInfo) { |
Fangrui Song | b9b07ce | 2022-12-17 01:42:39 +0000 | [diff] [blame] | 79 | Info = *OptInfo; |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 80 | return true; |
| 81 | } |
| 82 | |
| 83 | return false; |
| 84 | } |
Anna Thomas | d9ab34e | 2020-05-13 11:01:23 -0400 | [diff] [blame] | 85 | |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 86 | // 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 Thomas | d9ab34e | 2020-05-13 11:01:23 -0400 | [diff] [blame] | 101 | // This test makes sure correct mangling occurs for given string. |
| 102 | TEST_F(VFABIParserTest, ManglingVectorTLINames) { |
David Sherwood | 998f033 | 2021-02-08 17:16:03 +0000 | [diff] [blame] | 103 | 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 Thomas | d9ab34e | 2020-05-13 11:01:23 -0400 | [diff] [blame] | 111 | "_ZGV_LLVM_N5v_custom.call(custom.call.v5)"); |
| 112 | } |
| 113 | |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 114 | // This test makes sure that the demangling method succeeds only on |
| 115 | // valid values of the string. |
| 116 | TEST_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 | |
| 147 | TEST_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 | |
| 157 | TEST_F(VFABIParserTest, ScalarNameAndVectorName_01) { |
| 158 | EXPECT_TRUE(invokeParser("_ZGVnM2v_sin")); |
| 159 | EXPECT_EQ(ScalarName, "sin"); |
| 160 | EXPECT_EQ(VectorName, "_ZGVnM2v_sin"); |
| 161 | } |
| 162 | |
| 163 | TEST_F(VFABIParserTest, ScalarNameAndVectorName_02) { |
| 164 | EXPECT_TRUE(invokeParser("_ZGVnM2v_sin(UserFunc)", "UserFunc")); |
| 165 | EXPECT_EQ(ScalarName, "sin"); |
| 166 | EXPECT_EQ(VectorName, "UserFunc"); |
| 167 | } |
| 168 | |
| 169 | TEST_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 Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 175 | TEST_F(VFABIParserTest, Parse) { |
| 176 | EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 177 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 178 | EXPECT_FALSE(IsMasked()); |
| 179 | EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 180 | 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 | |
| 194 | TEST_F(VFABIParserTest, ParseVectorName) { |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 195 | EXPECT_TRUE(invokeParser("_ZGVnN2v_sin(my_v_sin)", "my_v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 196 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 197 | EXPECT_FALSE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 198 | 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 | |
| 205 | TEST_F(VFABIParserTest, LinearWithCompileTimeNegativeStep) { |
| 206 | EXPECT_TRUE(invokeParser("_ZGVnN2ln1Ln10Un100Rn1000_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 207 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 208 | EXPECT_FALSE(IsMasked()); |
| 209 | EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 210 | 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 | |
| 219 | TEST_F(VFABIParserTest, ParseScalableSVE) { |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 220 | 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 Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 223 | EXPECT_EQ(VF, ElementCount::getScalable(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 224 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 225 | EXPECT_EQ(ISA, VFISAKind::SVE); |
| 226 | EXPECT_EQ(ScalarName, "sin"); |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 227 | EXPECT_EQ(VectorName, "custom_vg"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 228 | } |
| 229 | |
| 230 | TEST_F(VFABIParserTest, ParseFixedWidthSVE) { |
| 231 | EXPECT_TRUE(invokeParser("_ZGVsM2v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 232 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 233 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 234 | EXPECT_EQ(ISA, VFISAKind::SVE); |
| 235 | EXPECT_EQ(ScalarName, "sin"); |
| 236 | EXPECT_EQ(VectorName, "_ZGVsM2v_sin"); |
| 237 | } |
| 238 | |
| 239 | TEST_F(VFABIParserTest, NotAVectorFunctionABIName) { |
| 240 | // Vector names should start with `_ZGV`. |
| 241 | EXPECT_FALSE(invokeParser("ZGVnN2v_sin")); |
| 242 | } |
| 243 | |
| 244 | TEST_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 | |
| 259 | TEST_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 | |
| 272 | TEST_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 Petrogalli | ab20a93 | 2019-12-13 19:43:26 +0000 | [diff] [blame] | 295 | TEST_F(VFABIParserTest, LLVM_ISA) { |
| 296 | EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin")); |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 297 | EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name")); |
Francesco Petrogalli | ab20a93 | 2019-12-13 19:43:26 +0000 | [diff] [blame] | 298 | EXPECT_EQ(ISA, VFISAKind::LLVM); |
| 299 | } |
| 300 | |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 301 | TEST_F(VFABIParserTest, InvalidMask) { |
| 302 | EXPECT_FALSE(invokeParser("_ZGVsK2v_sin")); |
| 303 | } |
| 304 | |
| 305 | TEST_F(VFABIParserTest, InvalidParameter) { |
| 306 | EXPECT_FALSE(invokeParser("_ZGVsM2vX_sin")); |
| 307 | } |
| 308 | |
| 309 | TEST_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 Henderson | 7d27244 | 2020-01-06 10:15:44 +0000 | [diff] [blame] | 314 | // Missing alignment value. |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 315 | 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 | |
| 327 | TEST_F(VFABIParserTest, ParseUniform) { |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 328 | EXPECT_TRUE(invokeParser("_ZGVnN2u_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 329 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 330 | EXPECT_FALSE(IsMasked()); |
| 331 | EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 332 | EXPECT_EQ(Parameters.size(), (unsigned)1); |
| 333 | EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::OMP_Uniform, 0})); |
| 334 | EXPECT_EQ(ScalarName, "sin"); |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 335 | EXPECT_EQ(VectorName, "_ZGVnN2u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 336 | |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 337 | // Uniform doesn't expect extra data. |
| 338 | EXPECT_FALSE(invokeParser("_ZGVnN2u0_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 339 | } |
| 340 | |
| 341 | TEST_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 Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 354 | VFParameter({9, VFParamKind::OMP_Uniform, 0}), |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 355 | }; |
| 356 | |
| 357 | #define __COMMON_CHECKS \ |
| 358 | do { \ |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 359 | EXPECT_EQ(VF, ElementCount::getFixed(2)); \ |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 360 | EXPECT_FALSE(IsMasked()); \ |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 361 | 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 Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 367 | EXPECT_TRUE(invokeParser("_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 368 | EXPECT_EQ(ISA, VFISAKind::AdvancedSIMD); |
| 369 | __COMMON_CHECKS; |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 370 | EXPECT_EQ(VectorName, "_ZGVnN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 371 | |
| 372 | // SVE: <isa> = "s" |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 373 | EXPECT_TRUE(invokeParser("_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 374 | EXPECT_EQ(ISA, VFISAKind::SVE); |
| 375 | __COMMON_CHECKS; |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 376 | EXPECT_EQ(VectorName, "_ZGVsN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 377 | |
| 378 | // SSE: <isa> = "b" |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 379 | EXPECT_TRUE(invokeParser("_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 380 | EXPECT_EQ(ISA, VFISAKind::SSE); |
| 381 | __COMMON_CHECKS; |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 382 | EXPECT_EQ(VectorName, "_ZGVbN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 383 | |
| 384 | // AVX: <isa> = "c" |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 385 | EXPECT_TRUE(invokeParser("_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 386 | EXPECT_EQ(ISA, VFISAKind::AVX); |
| 387 | __COMMON_CHECKS; |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 388 | EXPECT_EQ(VectorName, "_ZGVcN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 389 | |
| 390 | // AVX2: <isa> = "d" |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 391 | EXPECT_TRUE(invokeParser("_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 392 | EXPECT_EQ(ISA, VFISAKind::AVX2); |
| 393 | __COMMON_CHECKS; |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 394 | EXPECT_EQ(VectorName, "_ZGVdN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 395 | |
| 396 | // AVX512: <isa> = "e" |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 397 | EXPECT_TRUE(invokeParser("_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 398 | EXPECT_EQ(ISA, VFISAKind::AVX512); |
| 399 | __COMMON_CHECKS; |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 400 | EXPECT_EQ(VectorName, "_ZGVeN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 401 | |
Francesco Petrogalli | 9bc06d0 | 2019-11-11 16:48:51 +0000 | [diff] [blame] | 402 | // LLVM: <isa> = "_LLVM_" internal vector function. |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 403 | EXPECT_TRUE(invokeParser( |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 404 | "_ZGV_LLVM_N2vls2Ls27Us4Rs5l1L10U100R1000u_sin(vectorf)", "vectorf")); |
Francesco Petrogalli | 9bc06d0 | 2019-11-11 16:48:51 +0000 | [diff] [blame] | 405 | EXPECT_EQ(ISA, VFISAKind::LLVM); |
| 406 | __COMMON_CHECKS; |
| 407 | EXPECT_EQ(VectorName, "vectorf"); |
| 408 | |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 409 | // Unknown ISA (randomly using "q"). This test will need update if |
| 410 | // some targets decide to use "q" as their ISA token. |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 411 | EXPECT_TRUE(invokeParser("_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin")); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 412 | EXPECT_EQ(ISA, VFISAKind::Unknown); |
| 413 | __COMMON_CHECKS; |
Paul Walker | b114217 | 2020-05-26 16:54:02 +0000 | [diff] [blame] | 414 | EXPECT_EQ(VectorName, "_ZGVqN2vls2Ls27Us4Rs5l1L10U100R1000u_sin"); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 415 | |
| 416 | #undef __COMMON_CHECKS |
| 417 | } |
| 418 | |
| 419 | TEST_F(VFABIParserTest, MissingScalarName) { |
| 420 | EXPECT_FALSE(invokeParser("_ZGVnN2v_")); |
| 421 | } |
| 422 | |
| 423 | TEST_F(VFABIParserTest, MissingVectorName) { |
| 424 | EXPECT_FALSE(invokeParser("_ZGVnN2v_foo()")); |
| 425 | } |
| 426 | |
| 427 | TEST_F(VFABIParserTest, MissingVectorNameTermination) { |
| 428 | EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar")); |
| 429 | } |
| 430 | |
| 431 | TEST_F(VFABIParserTest, ParseMaskingNEON) { |
| 432 | EXPECT_TRUE(invokeParser("_ZGVnM2v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 433 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 434 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 435 | 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 | |
| 442 | TEST_F(VFABIParserTest, ParseMaskingSVE) { |
| 443 | EXPECT_TRUE(invokeParser("_ZGVsM2v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 444 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 445 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 446 | 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 | |
| 453 | TEST_F(VFABIParserTest, ParseMaskingSSE) { |
| 454 | EXPECT_TRUE(invokeParser("_ZGVbM2v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 455 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 456 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 457 | 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 | |
| 464 | TEST_F(VFABIParserTest, ParseMaskingAVX) { |
| 465 | EXPECT_TRUE(invokeParser("_ZGVcM2v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 466 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 467 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 468 | 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 | |
| 475 | TEST_F(VFABIParserTest, ParseMaskingAVX2) { |
| 476 | EXPECT_TRUE(invokeParser("_ZGVdM2v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 477 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 478 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 479 | 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 | |
| 486 | TEST_F(VFABIParserTest, ParseMaskingAVX512) { |
| 487 | EXPECT_TRUE(invokeParser("_ZGVeM2v_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 488 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 489 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | 82ca42a | 2019-09-19 17:47:32 +0000 | [diff] [blame] | 490 | 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 Petrogalli | c63b6db | 2019-10-30 19:08:21 +0000 | [diff] [blame] | 496 | |
Francesco Petrogalli | e0e1d4d | 2019-12-06 20:32:18 +0000 | [diff] [blame] | 497 | TEST_F(VFABIParserTest, ParseMaskingLLVM) { |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 498 | EXPECT_TRUE(invokeParser("_ZGV_LLVM_M2v_sin(custom_vector_sin)", |
| 499 | "custom_vector_sin")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 500 | EXPECT_EQ(VF, ElementCount::getFixed(2)); |
Francesco Petrogalli | e0e1d4d | 2019-12-06 20:32:18 +0000 | [diff] [blame] | 501 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | e0e1d4d | 2019-12-06 20:32:18 +0000 | [diff] [blame] | 502 | 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 | |
| 510 | TEST_F(VFABIParserTest, ParseScalableMaskingLLVM) { |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 511 | 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 Petrogalli | e0e1d4d | 2019-12-06 20:32:18 +0000 | [diff] [blame] | 514 | EXPECT_TRUE(IsMasked()); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 515 | EXPECT_EQ(VF, ElementCount::getScalable(2)); |
Francesco Petrogalli | e0e1d4d | 2019-12-06 20:32:18 +0000 | [diff] [blame] | 516 | 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 | |
| 524 | TEST_F(VFABIParserTest, ParseScalableMaskingLLVMSincos) { |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 525 | EXPECT_TRUE(invokeParser("_ZGV_LLVM_Mxvl8l8_sincos(custom_vector_sincos)", |
| 526 | "custom_vector_sincos", |
| 527 | "void(<vscale x 2 x double>, double *, double *)")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 528 | EXPECT_EQ(VF, ElementCount::getScalable(2)); |
Francesco Petrogalli | e0e1d4d | 2019-12-06 20:32:18 +0000 | [diff] [blame] | 529 | EXPECT_TRUE(IsMasked()); |
Francesco Petrogalli | e0e1d4d | 2019-12-06 20:32:18 +0000 | [diff] [blame] | 530 | 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 Petrogalli | c63b6db | 2019-10-30 19:08:21 +0000 | [diff] [blame] | 540 | class VFABIAttrTest : public testing::Test { |
| 541 | protected: |
| 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 | |
| 566 | TEST_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 Petrogalli | 9bc06d0 | 2019-11-11 16:48:51 +0000 | [diff] [blame] | 573 | |
| 574 | TEST_F(VFABIParserTest, LLVM_InternalISA) { |
| 575 | EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin")); |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 576 | EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)", "vector_name")); |
Francesco Petrogalli | 9bc06d0 | 2019-11-11 16:48:51 +0000 | [diff] [blame] | 577 | EXPECT_EQ(ISA, VFISAKind::LLVM); |
| 578 | } |
Francesco Petrogalli | ab20a93 | 2019-12-13 19:43:26 +0000 | [diff] [blame] | 579 | |
| 580 | TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) { |
Francesco Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 581 | EXPECT_TRUE(invokeParser("_ZGV_LLVM_N4vv_llvm.pow.f32(__svml_powf4)", |
| 582 | "__svml_powf4")); |
Paul Walker | f5634cd | 2021-07-24 16:34:20 +0100 | [diff] [blame] | 583 | EXPECT_EQ(VF, ElementCount::getFixed(4)); |
Francesco Petrogalli | ab20a93 | 2019-12-13 19:43:26 +0000 | [diff] [blame] | 584 | EXPECT_FALSE(IsMasked()); |
Francesco Petrogalli | ab20a93 | 2019-12-13 19:43:26 +0000 | [diff] [blame] | 585 | 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 Petrogalli | ca1f9f5 | 2020-01-22 22:34:27 +0000 | [diff] [blame] | 591 | |
| 592 | TEST_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 | |
| 602 | TEST_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 Wouda | 5351441 | 2020-06-25 16:08:13 +0100 | [diff] [blame] | 608 | |
| 609 | static 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 | |
| 617 | TEST(VFABIGetMappingsTest, IndirectCallInst) { |
| 618 | LLVMContext C; |
| 619 | std::unique_ptr<Module> M = parseIR(C, R"IR( |
| 620 | define void @call(void () * %f) { |
| 621 | entry: |
| 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 | } |