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 @@ -166,6 +166,12 @@ /// respective IR declarations. std::optional tryDemangleForVFABI(StringRef MangledName, const Module &M); +/// \param M -> The pointer to module used to retrieve informations about the +/// vector function. If nullptr is passed, we don't check the existence of +/// the demangled vector function. +std::optional tryDemangleForVFABI(StringRef MangledName, + const Module *M = nullptr); +VFInfo demangleForVFABI(StringRef MangledName); /// This routine mangles the given VectorName according to the LangRef /// specification for vector-function-abi-variant attribute and is specific to diff --git a/llvm/lib/Analysis/VFABIDemangling.cpp b/llvm/lib/Analysis/VFABIDemangling.cpp --- a/llvm/lib/Analysis/VFABIDemangling.cpp +++ b/llvm/lib/Analysis/VFABIDemangling.cpp @@ -312,10 +312,21 @@ } } // namespace +VFInfo VFABI::demangleForVFABI(StringRef MangledName) { + auto VI = VFABI::tryDemangleForVFABI(MangledName, /*M = */ nullptr); + assert(VI && "Invalid name for a VFABI variant."); + return VI.value(); +} + +std::optional VFABI::tryDemangleForVFABI(StringRef MangledName, + const Module &M) { + return VFABI::tryDemangleForVFABI(MangledName, &M); +} + // Format of the ABI name: // _ZGV_[()] std::optional VFABI::tryDemangleForVFABI(StringRef MangledName, - const Module &M) { + const Module *M) { const StringRef OriginalName = MangledName; // Assume there is no custom name , and therefore the // vector name consists of @@ -369,11 +380,6 @@ } } while (ParamFound == ParseRet::OK); - // A valid MangledName must have at least one valid entry in the - // . - if (Parameters.empty()) - return std::nullopt; - // Check for the and the optional , which // are separated from the prefix with "_" if (!MangledName.consume_front("_")) @@ -434,7 +440,8 @@ // need to make sure that the VF field of the VFShape class is never // set to 0. if (IsScalable) { - const Function *F = M.getFunction(VectorName); + assert(M && "Can't demangle scalable variant name without a valid module!"); + const Function *F = M->getFunction(VectorName); // The declaration of the function must be present in the module // to be able to retrieve its signature. if (!F) @@ -444,11 +451,11 @@ } // 1. We don't accept a zero lanes vectorization factor. - // 2. We don't accept the demangling if the vector function is not - // present in the module. + // 2. If M is not nullptr, we don't accept the demangling if the vector + // function is not present in the module. if (VF == 0) return std::nullopt; - if (!M.getFunction(VectorName)) + if (M && !M->getFunction(VectorName)) return std::nullopt; const VFShape Shape({ElementCount::get(VF, IsScalable), Parameters}); 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 @@ -66,7 +66,8 @@ // bool invokeParser(const StringRef MangledName, const StringRef VectorName = "", - const StringRef IRType = "void()") { + const StringRef IRType = "void()", + bool CheckVectorNameExistence = true) { StringRef Name = MangledName; if (!VectorName.empty()) Name = VectorName; @@ -74,7 +75,8 @@ // `invokeParser` multiple times in the same test. reset(Name, IRType); - const auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, *(M.get())); + const auto OptInfo = VFABI::tryDemangleForVFABI( + MangledName, CheckVectorNameExistence ? M.get() : nullptr); if (OptInfo) { Info = *OptInfo; return true; @@ -122,8 +124,6 @@ EXPECT_FALSE(invokeParser("_ZGVnN2")); EXPECT_FALSE(invokeParser("_ZGVnN2v")); EXPECT_FALSE(invokeParser("_ZGVnN2v_")); - // Missing parameters. - EXPECT_FALSE(invokeParser("_ZGVnN2_foo")); // Missing _ZGV prefix. EXPECT_FALSE(invokeParser("_ZVnN2v_foo")); // Missing . @@ -144,6 +144,20 @@ EXPECT_FALSE(invokeParser("_ZGVnN2v_foo(bar", "fakename")); } +TEST_F(VFABIParserTest, EmptyParamList) { + EXPECT_TRUE(invokeParser("_ZGVnN2_foo", /*VectorName = */ "", + /*IRType = */ "void()")); +} + +TEST_F(VFABIParserTest, DontCheckVectorNameExistence) { + // Demangling succeeds even if `UserFunc` doesn't exist in the module. + EXPECT_TRUE(invokeParser("_ZGVnM2v_sin(UserFunc)", /*VectorName = */ "", + /*IRType = */ "void()", + /*CheckVectorNameExistence = */ false)); + EXPECT_EQ(ScalarName, "sin"); + EXPECT_EQ(VectorName, "UserFunc"); +} + TEST_F(VFABIParserTest, ParamListParsing) { EXPECT_TRUE(invokeParser("_ZGVnN2vl16Ls32R3l_foo")); EXPECT_EQ(Parameters.size(), (unsigned)5);