diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h --- a/llvm/include/llvm/Analysis/VectorUtils.h +++ b/llvm/include/llvm/Analysis/VectorUtils.h @@ -173,6 +173,23 @@ /// respective IR declarations. Optional tryDemangleForVFABI(StringRef MangledName, const Module &M); +/// This routine mangles the given VectorName according to the LangRef +/// specification for vector-function-abi-variant attribute. +/// This returned string holds scalar-to-vector mapping: +/// _ZGV_() +/// +/// where: +/// +/// = "_LLVM_" +/// = "N". Note: TLI does not support masked interfaces. +/// = Number of concurrent lanes, stored in the `VectorizationFactor` +/// field of the `VecDesc` struct. +/// = "v", as many as are the numArgs. +/// = the name of the scalar function. +/// = the name of the vector function. +std::string mangleTLIVectorName(StringRef VectorName, StringRef ScalarName, + unsigned numArgs, unsigned VF); + /// Retrieve the `VFParamKind` from a string token. VFParamKind getVFParamKindFromString(const StringRef Token); diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp --- a/llvm/lib/Analysis/VectorUtils.cpp +++ b/llvm/lib/Analysis/VectorUtils.cpp @@ -1273,6 +1273,18 @@ } } +std::string VFABI::mangleTLIVectorName(StringRef VectorName, + StringRef ScalarName, unsigned numArgs, + unsigned VF) { + SmallString<256> Buffer; + llvm::raw_svector_ostream Out(Buffer); + Out << "_ZGV" << VFABI::_LLVM_ << "N" << VF; + for (unsigned I = 0; I < numArgs; ++I) + Out << "v"; + Out << "_" << ScalarName << "(" << VectorName << ")"; + return std::string(Out.str()); +} + void VFABI::getVectorVariantNames( const CallInst &CI, SmallVectorImpl &VariantMappings) { const StringRef S = diff --git a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp --- a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp +++ b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp @@ -33,31 +33,6 @@ STATISTIC(NumCompUsedAdded, "Number of `@llvm.compiler.used` operands that have been added."); -/// Helper function to map the TLI name to a strings that holds -/// scalar-to-vector mapping. -/// -/// _ZGV_() -/// -/// where: -/// -/// = "_LLVM_" -/// = "N". Note: TLI does not support masked interfaces. -/// = Number of concurrent lanes, stored in the `VectorizationFactor` -/// field of the `VecDesc` struct. -/// = "v", as many as are the number of parameters of CI. -/// = the name of the scalar function called by CI. -/// = the name of the vector function mapped by the TLI. -static std::string mangleTLIName(StringRef VectorName, const CallInst &CI, - unsigned VF) { - SmallString<256> Buffer; - llvm::raw_svector_ostream Out(Buffer); - Out << "_ZGV" << VFABI::_LLVM_ << "N" << VF; - for (unsigned I = 0; I < CI.getNumArgOperands(); ++I) - Out << "v"; - Out << "_" << CI.getCalledFunction()->getName() << "(" << VectorName << ")"; - return std::string(Out.str()); -} - /// A helper function that adds the vector function declaration that /// vectorizes the CallInst CI with a vectorization factor of VF /// lanes. The TLI assumes that all parameters and the return type of @@ -117,7 +92,8 @@ const std::string TLIName = std::string(TLI.getVectorizedFunction(ScalarName, VF)); if (!TLIName.empty()) { - std::string MangledName = mangleTLIName(TLIName, CI, VF); + std::string MangledName = VFABI::mangleTLIVectorName( + TLIName, ScalarName, CI.getNumArgOperands(), VF); if (!OriginalSetOfMappings.count(MangledName)) { Mappings.push_back(MangledName); ++NumCallInjected; diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp --- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp +++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp @@ -83,6 +83,30 @@ return false; } + + bool invokeParserForManglingTLIVectorName(const StringRef ScalarNameArg, + const StringRef VectorNameArg, + const unsigned NumArgs, + const unsigned VFArg, + const StringRef IRType = "void()") { + std::string MangledName = VFABI::mangleTLIVectorName( + VectorNameArg, ScalarNameArg, NumArgs, VFArg); + // Testing if the mangledname that is generated can be demangled and the + // correct values are retrieved. + reset(VectorNameArg, IRType); + + const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, *(M.get())); + if (!OptInfo.hasValue()) + return false; + Info = OptInfo.getValue(); + EXPECT_EQ(Info.ISA, VFISAKind::LLVM); + EXPECT_EQ(Info.ScalarName, ScalarNameArg); + EXPECT_EQ(Info.VectorName, VectorNameArg); + EXPECT_EQ(Info.Shape.Parameters.size(), NumArgs); + EXPECT_EQ(Info.Shape.VF, VFArg); + return true; + } + // Checks that 1. the last Parameter in the Shape is of type // VFParamKind::GlobalPredicate and 2. it is the only one of such // type. @@ -98,6 +122,13 @@ }; } // unnamed namespace +// This test makes sure correct mangling occurs for given string. +TEST_F(VFABIParserTest, ManglingVectorTLINames) { + + EXPECT_TRUE(invokeParserForManglingTLIVectorName( + "custom.call", "custom.call.v", 1 /* numArgs*/, 4)); +} + // This test makes sure that the demangling method succeeds only on // valid values of the string. TEST_F(VFABIParserTest, OnlyValidNames) {