[llvm] 0be8196 - [VectorUtils] Introduce the Vector Function Database (VFDatabase).
Francesco Petrogalli via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 10 08:38:10 PST 2019
Author: Francesco Petrogalli
Date: 2019-12-10T16:36:44Z
New Revision: 0be81968a283fd4161cb9ac9748d5ed200926292
URL: https://github.com/llvm/llvm-project/commit/0be81968a283fd4161cb9ac9748d5ed200926292
DIFF: https://github.com/llvm/llvm-project/commit/0be81968a283fd4161cb9ac9748d5ed200926292.diff
LOG: [VectorUtils] Introduce the Vector Function Database (VFDatabase).
This patch introduced the VFDatabase, the framework proposed in
http://lists.llvm.org/pipermail/llvm-dev/2019-June/133484.html. [*]
In this patch the VFDatabase is used to bridge the TargetLibraryInfo
(TLI) calls that were previously used to query for the availability of
vector counterparts of scalar functions.
The VFISAKind field `ISA` of VFShape have been moved into into VFInfo,
under the assumption that different vector ISAs may provide the same
vector signature. At the moment, the vectorizer accepts any of the
available ISAs as long as the signature provided by the VFDatabase
matches the one expected in the vectorization process. For example,
when targeting AVX or AVX2, which both have 256-bit registers, the IR
signature of the two vector functions associated to the two ISAs is
the same. The `getVectorizedFunction` method at the moment returns the
first available match. We will need to add more heuristics to the
search system to decide which of the available version (TLI, AVX,
AVX2, ...) the system should prefer, when multiple versions with the
same VFShape are present.
Some of the code in this patch is based on the work done by Sumedh
Arani in https://reviews.llvm.org/D66025.
[*] Notice that in the proposal the VFDatabase was called SVFS. The
name VFDatabase is more in line with LLVM recommendations for
naming classes and variables.
Differential Revision: https://reviews.llvm.org/D67572
Added:
Modified:
llvm/include/llvm/Analysis/TargetLibraryInfo.h
llvm/include/llvm/Analysis/VectorUtils.h
llvm/lib/Analysis/LazyCallGraph.cpp
llvm/lib/Analysis/LoopAccessAnalysis.cpp
llvm/lib/Analysis/VectorUtils.cpp
llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
llvm/lib/Transforms/Utils/ModuleUtils.cpp
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
llvm/test/Other/opt-O2-pipeline.ll
llvm/test/Other/opt-O3-pipeline.ll
llvm/test/Other/opt-Os-pipeline.ll
llvm/unittests/Analysis/VectorFunctionABITest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index be6c8cd084ec..04c59bb370c6 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -341,12 +341,16 @@ class TargetLibraryInfo {
FunctionAnalysisManager::Invalidator &) {
return false;
}
-
/// Returns the largest vectorization factor used in the list of
/// vector functions.
unsigned getWidestVF(StringRef ScalarF) const {
return Impl->getWidestVF(ScalarF);
}
+
+ /// Check if the function "F" is listed in a library known to LLVM.
+ bool isKnownVectorFunctionInLibrary(StringRef F) const {
+ return this->isFunctionVectorizable(F);
+ }
};
/// Analysis pass providing the \c TargetLibraryInfo.
diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index f5f805493d32..f6ccb04ce99f 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/CheckedArithmetic.h"
@@ -116,10 +117,10 @@ struct VFShape {
/// Holds the VFShape for a specific scalar to vector function mapping.
struct VFInfo {
- VFShape Shape; // Classification of the vector function.
- StringRef ScalarName; // Scalar Function Name.
- StringRef VectorName; // Vector Function Name associated to this VFInfo.
- VFISAKind ISA; // Instruction Set Architecture.
+ VFShape Shape; /// Classification of the vector function.
+ std::string ScalarName; /// Scalar Function Name.
+ std::string VectorName; /// Vector Function Name associated to this VFInfo.
+ VFISAKind ISA; /// Instruction Set Architecture.
// Comparison operator.
bool operator==(const VFInfo &Other) const {
@@ -167,6 +168,81 @@ void getVectorVariantNames(const CallInst &CI,
SmallVectorImpl<std::string> &VariantMappings);
} // end namespace VFABI
+/// The Vector Function Database.
+///
+/// Helper class used to find the vector functions associated to a
+/// scalar CallInst.
+class VFDatabase {
+ /// The CallInst for which we are looking for vector functions.
+ const CallInst &CI;
+ /// The Module of the CallInst CI.
+ const Module *M;
+ /// List of vector functions descritors associated to the call
+ /// instruction.
+ const SmallVector<VFInfo, 8> ScalarToVectorMappings;
+
+ /// Retreive the scalar-to-vector mappings associated to the rule of
+ /// a vector Function ABI.
+ static void getVFABIMappings(const CallInst &CI,
+ SmallVectorImpl<VFInfo> &Mappings) {
+ const StringRef ScalarName = CI.getCalledFunction()->getName();
+ const StringRef S =
+ CI.getAttribute(AttributeList::FunctionIndex, VFABI::MappingsAttrName)
+ .getValueAsString();
+ if (S.empty())
+ return;
+
+ SmallVector<std::string, 8> ListOfStrings;
+ VFABI::getVectorVariantNames(CI, ListOfStrings);
+ for (const auto &MangledName : ListOfStrings) {
+ const Optional<VFInfo> Shape = VFABI::tryDemangleForVFABI(MangledName);
+ // A match is found via scalar and vector names, and also by
+ // ensuring that the variant described in the attribute has a
+ // corresponding definition or declaration of the vector
+ // function in the Module M.
+ if (Shape.hasValue() && (Shape.getValue().ScalarName == ScalarName)) {
+ assert(CI.getModule()->getFunction(Shape.getValue().VectorName) &&
+ "Vector function is missing.");
+ Mappings.push_back(Shape.getValue());
+ }
+ }
+ }
+
+public:
+ /// Retrieve all the VFInfo instances associated to the CallInst CI.
+ static SmallVector<VFInfo, 8> getMappings(const CallInst &CI) {
+ SmallVector<VFInfo, 8> Ret;
+
+ // Get mappings from the Vector Function ABI variants.
+ getVFABIMappings(CI, Ret);
+
+ // Other non-VFABI variants should be retrieved here.
+
+ return Ret;
+ }
+
+ /// Constructor, requires a CallInst instance.
+ VFDatabase(CallInst &CI)
+ : CI(CI), M(CI.getModule()),
+ ScalarToVectorMappings(VFDatabase::getMappings(CI)) {}
+ /// \defgroup VFDatabase query interface.
+ ///
+ /// @{
+ /// Retrieve the Function with VFShape \p Shape.
+ Function *getVectorizedFunction(const VFShape &Shape) const {
+ for (const auto &Info : ScalarToVectorMappings)
+ if (Info.Shape == Shape)
+ return M->getFunction(Info.VectorName);
+
+ return nullptr;
+ }
+ /// Checks if a function is vectorizable with VFShape \p Shape.
+ bool isFunctionVectorizable(const VFShape &Shape) const {
+ return getVectorizedFunction(Shape) != nullptr;
+ }
+ /// @}
+};
+
template <typename T> class ArrayRef;
class DemandedBits;
class GetElementPtrInst;
diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
index ef31c1e0ba8c..a9dd5e012804 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/VectorUtils.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
@@ -146,8 +147,11 @@ LLVM_DUMP_METHOD void LazyCallGraph::Node::dump() const {
static bool isKnownLibFunction(Function &F, TargetLibraryInfo &TLI) {
LibFunc LF;
- // Either this is a normal library function or a "vectorizable" function.
- return TLI.getLibFunc(F, LF) || TLI.isFunctionVectorizable(F.getName());
+ // Either this is a normal library function or a "vectorizable"
+ // function. Not using the VFDatabase here because this query
+ // is related only to libraries handled via the TLI.
+ return TLI.getLibFunc(F, LF) ||
+ TLI.isKnownVectorFunctionInLibrary(F.getName());
}
LazyCallGraph::LazyCallGraph(
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 26fa5112c29a..05f6010c1bd1 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -1845,7 +1845,7 @@ void LoopAccessInfo::analyzeLoop(AliasAnalysis *AA, LoopInfo *LI,
// If the function has an explicit vectorized counterpart, we can safely
// assume that it can be vectorized.
if (Call && !Call->isNoBuiltin() && Call->getCalledFunction() &&
- TLI->isFunctionVectorizable(Call->getCalledFunction()->getName()))
+ !VFDatabase::getMappings(*Call).empty())
continue;
auto *Ld = dyn_cast<LoadInst>(&I);
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index c45ab941a142..a83dda1fc193 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -1174,6 +1174,7 @@ void VFABI::getVectorVariantNames(
for (auto &S : SetVector<StringRef>(ListAttr.begin(), ListAttr.end())) {
#ifndef NDEBUG
+ LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << S << "'\n");
Optional<VFInfo> Info = VFABI::tryDemangleForVFABI(S);
assert(Info.hasValue() && "Invalid name for a VFABI variant.");
assert(CI.getModule()->getFunction(Info.getValue().VectorName) &&
diff --git a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
index 9192e74b9ace..9e9fea974d64 100644
--- a/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
+++ b/llvm/lib/Transforms/Utils/InjectTLIMappings.cpp
@@ -13,6 +13,8 @@
#include "llvm/Transforms/Utils/InjectTLIMappings.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/DemandedBits.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/Transforms/Utils.h"
@@ -168,6 +170,11 @@ void InjectTLIMappingsLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addPreserved<TargetLibraryInfoWrapperPass>();
+ AU.addPreserved<ScalarEvolutionWrapperPass>();
+ AU.addPreserved<AAResultsWrapperPass>();
+ AU.addPreserved<LoopAccessLegacyAnalysis>();
+ AU.addPreserved<DemandedBitsWrapperPass>();
+ AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index b94f57e4dc2c..51c6450fcc2b 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -11,15 +11,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ModuleUtils.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
-
using namespace llvm;
+#define DEBUG_TYPE "moduleutils"
+
static void appendToGlobalArray(const char *Array, Module &M, Function *F,
int Priority, Constant *Data) {
IRBuilder<> IRB(M.getContext());
@@ -298,8 +300,9 @@ void VFABI::setVectorVariantNames(
Module *M = CI->getModule();
#ifndef NDEBUG
for (const std::string &VariantMapping : VariantMappings) {
+ LLVM_DEBUG(dbgs() << "VFABI: adding mapping '" << VariantMapping << "'\n");
Optional<VFInfo> VI = VFABI::tryDemangleForVFABI(VariantMapping);
- assert(VI.hasValue() && "Canno add an invalid VFABI name.");
+ assert(VI.hasValue() && "Cannot add an invalid VFABI name.");
assert(M->getNamedValue(VI.getValue().VectorName) &&
"Cannot add variant to attribute: "
"vector function declaration is missing.");
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 3f943f4c0688..0072a7db94e3 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -670,7 +670,7 @@ bool LoopVectorizationLegality::canVectorizeInstrs() {
if (CI && !getVectorIntrinsicIDForCall(CI, TLI) &&
!isa<DbgInfoIntrinsic>(CI) &&
!(CI->getCalledFunction() && TLI &&
- TLI->isFunctionVectorizable(CI->getCalledFunction()->getName()))) {
+ !VFDatabase::getMappings(*CI).empty())) {
// If the call is a recognized math libary call, it is likely that
// we can vectorize it given loosened floating-point constraints.
LibFunc Func;
@@ -685,7 +685,8 @@ bool LoopVectorizationLegality::canVectorizeInstrs() {
// but it's hard to provide meaningful yet generic advice.
// Also, should this be guarded by allowExtraAnalysis() and/or be part
// of the returned info from isFunctionVectorizable()?
- reportVectorizationFailure("Found a non-intrinsic callsite",
+ reportVectorizationFailure(
+ "Found a non-intrinsic callsite",
"library call cannot be vectorized. "
"Try compiling with -fno-math-errno, -ffast-math, "
"or similar flags",
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index be4bb933dd02..e80a78bb0afb 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -134,6 +134,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/InjectTLIMappings.h"
#include "llvm/Transforms/Utils/LoopSimplify.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/LoopVersioning.h"
@@ -1634,6 +1635,7 @@ struct LoopVectorize : public FunctionPass {
AU.addRequired<LoopAccessLegacyAnalysis>();
AU.addRequired<DemandedBitsWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
+ AU.addRequired<InjectTLIMappingsLegacy>();
// We currently do not preserve loopinfo/dominator analyses with outer loop
// vectorization. Until this is addressed, mark these analyses as preserved
@@ -3226,7 +3228,6 @@ unsigned LoopVectorizationCostModel::getVectorCallCost(CallInst *CI,
unsigned VF,
bool &NeedToScalarize) {
Function *F = CI->getCalledFunction();
- StringRef FnName = CI->getCalledFunction()->getName();
Type *ScalarRetTy = CI->getType();
SmallVector<Type *, 4> Tys, ScalarTys;
for (auto &ArgOp : CI->arg_operands())
@@ -3254,7 +3255,9 @@ unsigned LoopVectorizationCostModel::getVectorCallCost(CallInst *CI,
// If we can't emit a vector call for this function, then the currently found
// cost is the cost we need to return.
NeedToScalarize = true;
- if (!TLI || !TLI->isFunctionVectorizable(FnName, VF) || CI->isNoBuiltin())
+ if (!TLI || CI->isNoBuiltin() ||
+ !VFDatabase(*CI).isFunctionVectorizable(
+ VFShape::get(*CI, {VF, false} /*EC*/, false /*HasGlobalPred*/)))
return Cost;
// If the corresponding vector cost is cheaper, return its cost.
@@ -4279,9 +4282,6 @@ void InnerLoopVectorizer::widenInstruction(Instruction &I) {
Module *M = I.getParent()->getParent()->getParent();
auto *CI = cast<CallInst>(&I);
- StringRef FnName = CI->getCalledFunction()->getName();
- Function *F = CI->getCalledFunction();
- Type *RetTy = ToVectorTy(CI->getType(), VF);
SmallVector<Type *, 4> Tys;
for (Value *ArgOperand : CI->arg_operands())
Tys.push_back(ToVectorTy(ArgOperand->getType(), VF));
@@ -4317,17 +4317,18 @@ void InnerLoopVectorizer::widenInstruction(Instruction &I) {
TysForDecl[0] = VectorType::get(CI->getType()->getScalarType(), VF);
VectorF = Intrinsic::getDeclaration(M, ID, TysForDecl);
} else {
- // Use vector version of the library call.
- StringRef VFnName = TLI->getVectorizedFunction(FnName, VF);
- assert(!VFnName.empty() && "Vector function name is empty.");
- VectorF = M->getFunction(VFnName);
- if (!VectorF) {
- // Generate a declaration
- FunctionType *FTy = FunctionType::get(RetTy, Tys, false);
- VectorF =
- Function::Create(FTy, Function::ExternalLinkage, VFnName, M);
- VectorF->copyAttributesFrom(F);
- }
+ // Use vector version of the function call.
+ const VFShape Shape =
+ VFShape::get(*CI, {VF, false} /*EC*/, false /*HasGlobalPred*/);
+#ifndef NDEBUG
+ const SmallVector<VFInfo, 8> Infos = VFDatabase::getMappings(*CI);
+ assert(std::find_if(Infos.begin(), Infos.end(),
+ [&Shape](const VFInfo &Info) {
+ return Info.Shape == Shape;
+ }) != Infos.end() &&
+ "Vector function shape is missing from the database.");
+#endif
+ VectorF = VFDatabase(*CI).getVectorizedFunction(Shape);
}
assert(VectorF && "Can't create vector function.");
@@ -6356,6 +6357,7 @@ INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis)
INITIALIZE_PASS_DEPENDENCY(DemandedBitsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(InjectTLIMappingsLegacy)
INITIALIZE_PASS_END(LoopVectorize, LV_NAME, lv_name, false, false)
namespace llvm {
diff --git a/llvm/test/Other/opt-O2-pipeline.ll b/llvm/test/Other/opt-O2-pipeline.ll
index d2630500fbdb..a98781e37ae6 100644
--- a/llvm/test/Other/opt-O2-pipeline.ll
+++ b/llvm/test/Other/opt-O2-pipeline.ll
@@ -223,9 +223,11 @@
; CHECK-NEXT: Lazy Branch Probability Analysis
; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: Optimization Remark Emitter
+; CHECK-NEXT: Inject TLI Mappings
; CHECK-NEXT: Loop Vectorization
; CHECK-NEXT: Canonicalize natural loops
; CHECK-NEXT: Scalar Evolution Analysis
+; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
; CHECK-NEXT: Function Alias Analysis Results
; CHECK-NEXT: Loop Access Analysis
; CHECK-NEXT: Lazy Branch Probability Analysis
diff --git a/llvm/test/Other/opt-O3-pipeline.ll b/llvm/test/Other/opt-O3-pipeline.ll
index 82f6e8f5b558..7600b47fb72c 100644
--- a/llvm/test/Other/opt-O3-pipeline.ll
+++ b/llvm/test/Other/opt-O3-pipeline.ll
@@ -228,9 +228,11 @@
; CHECK-NEXT: Lazy Branch Probability Analysis
; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: Optimization Remark Emitter
+; CHECK-NEXT: Inject TLI Mappings
; CHECK-NEXT: Loop Vectorization
; CHECK-NEXT: Canonicalize natural loops
; CHECK-NEXT: Scalar Evolution Analysis
+; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
; CHECK-NEXT: Function Alias Analysis Results
; CHECK-NEXT: Loop Access Analysis
; CHECK-NEXT: Lazy Branch Probability Analysis
diff --git a/llvm/test/Other/opt-Os-pipeline.ll b/llvm/test/Other/opt-Os-pipeline.ll
index c690cc5d9641..e12a36c7585e 100644
--- a/llvm/test/Other/opt-Os-pipeline.ll
+++ b/llvm/test/Other/opt-Os-pipeline.ll
@@ -210,9 +210,11 @@
; CHECK-NEXT: Lazy Branch Probability Analysis
; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: Optimization Remark Emitter
+; CHECK-NEXT: Inject TLI Mappings
; CHECK-NEXT: Loop Vectorization
; CHECK-NEXT: Canonicalize natural loops
; CHECK-NEXT: Scalar Evolution Analysis
+; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
; CHECK-NEXT: Function Alias Analysis Results
; CHECK-NEXT: Loop Access Analysis
; CHECK-NEXT: Lazy Branch Probability Analysis
diff --git a/llvm/unittests/Analysis/VectorFunctionABITest.cpp b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
index 6aaa38c7d83a..becfe51cc0cf 100644
--- a/llvm/unittests/Analysis/VectorFunctionABITest.cpp
+++ b/llvm/unittests/Analysis/VectorFunctionABITest.cpp
@@ -13,7 +13,7 @@
using namespace llvm;
-// This test makes sure that the getFromVFABI method succeeds only on
+// This test makes sure that the demangling method succeeds only on
// valid values of the string.
TEST(VectorFunctionABITests, OnlyValidNames) {
// Incomplete string.
@@ -91,8 +91,8 @@ class VFABIParserTest : public ::testing::Test {
unsigned &VF = Info.Shape.VF;
VFISAKind &ISA = Info.ISA;
SmallVector<VFParameter, 8> &Parameters = Info.Shape.Parameters;
- StringRef &ScalarName = Info.ScalarName;
- StringRef &VectorName = Info.VectorName;
+ std::string &ScalarName = Info.ScalarName;
+ std::string &VectorName = Info.VectorName;
bool &IsScalable = Info.Shape.IsScalable;
// Invoke the parser.
bool invokeParser(const StringRef MangledName) {
@@ -243,6 +243,12 @@ TEST_F(VFABIParserTest, ISA) {
EXPECT_EQ(ISA, VFISAKind::AVX512);
}
+TEST_F(VFABIParserTest, LLVM_ISA) {
+ EXPECT_FALSE(invokeParser("_ZGV_LLVM_N2v_sin"));
+ EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)"));
+ EXPECT_EQ(ISA, VFISAKind::LLVM);
+}
+
TEST_F(VFABIParserTest, InvalidMask) {
EXPECT_FALSE(invokeParser("_ZGVsK2v_sin"));
}
@@ -525,3 +531,15 @@ TEST_F(VFABIParserTest, LLVM_InternalISA) {
EXPECT_TRUE(invokeParser("_ZGV_LLVM_N2v_sin_(vector_name)"));
EXPECT_EQ(ISA, VFISAKind::LLVM);
}
+
+TEST_F(VFABIParserTest, IntrinsicsInLLVMIsa) {
+ EXPECT_TRUE(invokeParser("_ZGV_LLVM_N4vv_llvm.pow.f32(__svml_powf4)"));
+ EXPECT_EQ(VF, (unsigned)4);
+ EXPECT_FALSE(IsMasked());
+ EXPECT_FALSE(IsScalable);
+ EXPECT_EQ(ISA, VFISAKind::LLVM);
+ EXPECT_EQ(Parameters.size(), (unsigned)2);
+ EXPECT_EQ(Parameters[0], VFParameter({0, VFParamKind::Vector}));
+ EXPECT_EQ(Parameters[1], VFParameter({1, VFParamKind::Vector}));
+ EXPECT_EQ(ScalarName, "llvm.pow.f32");
+}
More information about the llvm-commits
mailing list