LLVM 24.0.0git
ReplaceWithVeclib.cpp
Go to the documentation of this file.
1//=== ReplaceWithVeclib.cpp - Replace vector intrinsics with veclib calls -===//
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// Replaces calls to LLVM Intrinsics with matching calls to functions from a
10// vector library (e.g libmvec, SVML) using TargetLibraryInfo interface.
11//
12//===----------------------------------------------------------------------===//
13
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/Statistic.h"
17#include "llvm/ADT/StringRef.h"
23#include "llvm/CodeGen/Passes.h"
25#include "llvm/IR/IRBuilder.h"
32
33using namespace llvm;
34
35#define DEBUG_TYPE "replace-with-veclib"
36
37STATISTIC(NumCallsReplaced,
38 "Number of calls to intrinsics that have been replaced.");
39
40STATISTIC(NumTLIFuncDeclAdded,
41 "Number of vector library function declarations added.");
42
43STATISTIC(NumFuncUsedAdded,
44 "Number of functions added to `llvm.compiler.used`");
45
46/// Returns a vector Function that it adds to the Module \p M. When an \p
47/// ScalarFunc is not null, it copies its attributes to the newly created
48/// Function.
50 const StringRef TLIName,
51 std::optional<CallingConv::ID> CC,
52 Function *ScalarFunc = nullptr) {
53 Function *TLIFunc = M->getFunction(TLIName);
54 if (!TLIFunc) {
55 TLIFunc =
56 Function::Create(VectorFTy, Function::ExternalLinkage, TLIName, *M);
57 if (ScalarFunc)
58 TLIFunc->copyAttributesFrom(ScalarFunc);
59 if (CC)
60 TLIFunc->setCallingConv(*CC);
61
62 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added vector library function `"
63 << TLIName << "` of type `" << *(TLIFunc->getType())
64 << "` to module.\n");
65
66 ++NumTLIFuncDeclAdded;
67 // Add the freshly created function to llvm.compiler.used, similar to as it
68 // is done in InjectTLIMappings.
69 appendToCompilerUsed(*M, {TLIFunc});
70 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << TLIName
71 << "` to `@llvm.compiler.used`.\n");
72 ++NumFuncUsedAdded;
73 }
74 return TLIFunc;
75}
76
77/// Replace the intrinsic call \p II to \p TLIVecFunc, which is the
78/// corresponding function from the vector library.
80 Function *TLIVecFunc) {
82 SmallVector<Value *> Args(II->args());
83 if (Info.isMasked()) {
84 auto *MaskTy =
85 VectorType::get(Type::getInt1Ty(II->getContext()), Info.Shape.VF);
86 Args.push_back(Constant::getAllOnesValue(MaskTy));
87 }
88
89 // Preserve the operand bundles.
91 II->getOperandBundlesAsDefs(OpBundles);
92
93 // Preserve fast math flags for FP math (getFastMathFlagsOrNone keeps this
94 // safe for non-FP intrinsics, whose flags are simply empty).
95 auto *Replacement = IRBuilder.CreateCall(
96 TLIVecFunc, Args, OpBundles, /*FMFSource=*/II->getFastMathFlagsOrNone());
97 // Preserve fpmath for FP math
98 if (isa<FPMathOperator>(Replacement))
99 Replacement->copyMetadata(*II, {LLVMContext::MD_fpmath});
100 II->replaceAllUsesWith(Replacement);
101 Replacement->setCallingConv(TLIVecFunc->getCallingConv());
102}
103
104/// Returns true when successfully replaced \p II, which is a call to a
105/// vectorized intrinsic, with a suitable function taking vector arguments,
106/// based on available mappings in the \p TLI.
108 IntrinsicInst *II) {
109 assert(II != nullptr && "Intrinsic cannot be null");
110 Intrinsic::ID IID = II->getIntrinsicID();
111 Type *RetTy = II->getType();
112 Type *ScalarRetTy = RetTy->getScalarType();
113 // At the moment VFABI assumes the return type is always widened unless it is
114 // a void type.
115 auto *VTy = dyn_cast<VectorType>(RetTy);
116 ElementCount EC(VTy ? VTy->getElementCount() : ElementCount::getFixed(0));
117
118 // OloadTys collects types used in scalar intrinsic overload name.
119 SmallVector<Type *, 3> OloadTys;
120 if (!RetTy->isVoidTy() &&
121 isVectorIntrinsicWithOverloadTypeAtArg(IID, -1, /*TTI=*/nullptr))
122 OloadTys.push_back(ScalarRetTy);
123
124 // Compute the argument types of the corresponding scalar call and check that
125 // all vector operands match the previously found EC.
126 SmallVector<Type *, 8> ScalarArgTypes;
127 for (auto Arg : enumerate(II->args())) {
128 auto *ArgTy = Arg.value()->getType();
129 bool IsOloadTy = isVectorIntrinsicWithOverloadTypeAtArg(IID, Arg.index(),
130 /*TTI=*/nullptr);
131 if (isVectorIntrinsicWithScalarOpAtArg(IID, Arg.index(), /*TTI=*/nullptr)) {
132 ScalarArgTypes.push_back(ArgTy);
133 if (IsOloadTy)
134 OloadTys.push_back(ArgTy);
135 } else if (auto *VectorArgTy = dyn_cast<VectorType>(ArgTy)) {
136 auto *ScalarArgTy = VectorArgTy->getElementType();
137 ScalarArgTypes.push_back(ScalarArgTy);
138 if (IsOloadTy)
139 OloadTys.push_back(ScalarArgTy);
140 // When return type is void, set EC to the first vector argument, and
141 // disallow vector arguments with different ECs.
142 if (EC.isZero())
143 EC = VectorArgTy->getElementCount();
144 else if (EC != VectorArgTy->getElementCount())
145 return false;
146 } else
147 // Exit when it is supposed to be a vector argument but it isn't.
148 return false;
149 }
150
151 // Try to reconstruct the name for the scalar version of the instruction,
152 // using scalar argument types.
153 std::string ScalarName =
155 ? Intrinsic::getName(IID, OloadTys, II->getModule())
156 : Intrinsic::getName(IID).str();
157
158 // Try to find the mapping for the scalar version of this intrinsic and the
159 // exact vector width of the call operands in the TargetLibraryInfo. First,
160 // check with a non-masked variant, and if that fails try with a masked one.
161 const VecDesc *VD =
162 TLI.getVectorMappingInfo(ScalarName, EC, /*Masked*/ false);
163 if (!VD && !(VD = TLI.getVectorMappingInfo(ScalarName, EC, /*Masked*/ true)))
164 return false;
165
166 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Found TLI mapping from: `" << ScalarName
167 << "` and vector width " << EC << " to: `"
168 << VD->getVectorFnName() << "`.\n");
169
170 // Replace the call to the intrinsic with a call to the vector library
171 // function.
172 FunctionType *ScalarFTy =
173 FunctionType::get(ScalarRetTy, ScalarArgTypes, /*isVarArg*/ false);
174 const std::string MangledName = VD->getVectorFunctionABIVariantString();
175 auto OptInfo = VFABI::tryDemangleForVFABI(MangledName, ScalarFTy);
176 if (!OptInfo)
177 return false;
178
179 // There is no guarantee that the vectorized instructions followed the VFABI
180 // specification when being created, this is why we need to add extra check to
181 // make sure that the operands of the vector function obtained via VFABI match
182 // the operands of the original vector instruction.
183 for (auto &VFParam : OptInfo->Shape.Parameters) {
184 if (VFParam.ParamKind == VFParamKind::GlobalPredicate)
185 continue;
186
187 // tryDemangleForVFABI must return valid ParamPos, otherwise it could be
188 // a bug in the VFABI parser.
189 assert(VFParam.ParamPos < II->arg_size() && "ParamPos has invalid range");
190 Type *OrigTy = II->getArgOperand(VFParam.ParamPos)->getType();
191 if (OrigTy->isVectorTy() != (VFParam.ParamKind == VFParamKind::Vector)) {
192 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Will not replace: " << ScalarName
193 << ". Wrong type at index " << VFParam.ParamPos << ": "
194 << *OrigTy << "\n");
195 return false;
196 }
197 }
198
199 FunctionType *VectorFTy = VFABI::createFunctionType(*OptInfo, ScalarFTy);
200 if (!VectorFTy)
201 return false;
202
203 Function *TLIFunc =
204 getTLIFunction(II->getModule(), VectorFTy, VD->getVectorFnName(),
205 VD->getCallingConv(), II->getCalledFunction());
206 replaceWithTLIFunction(II, *OptInfo, TLIFunc);
207 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Replaced call to `" << ScalarName
208 << "` with call to `" << TLIFunc->getName() << "`.\n");
209 ++NumCallsReplaced;
210 return true;
211}
212
213/// Returns true when \p TLI has a vector mapping for the scalar function name
214/// \p Name at \p EC (matching either masked or unmasked variants).
215static bool hasVectorMapping(const TargetLibraryInfo &TLI, StringRef Name,
216 ElementCount EC) {
217 return TLI.getVectorMappingInfo(Name, EC, /*Masked=*/false) ||
218 TLI.getVectorMappingInfo(Name, EC, /*Masked=*/true);
219}
220
221/// Returns true when \p TLI has a vector mapping for \p IID at the given
222/// element type and \p EC.
224 Intrinsic::ID IID, Type *ScalarTy,
225 ElementCount EC, Module *M) {
226 std::string Name = Intrinsic::getName(IID, {ScalarTy}, M);
227 return hasVectorMapping(TLI, Name, EC);
228}
229
230/// If \p II is a vector llvm.sincos with no direct vector library mapping but
231/// the target does have vector mappings for both llvm.sin and llvm.cos at the
232/// same element count, replace it with separate llvm.sin and llvm.cos calls
233/// and run the standard veclib replacement on each.
237 if (II->getIntrinsicID() != Intrinsic::sincos)
238 return false;
239 Value *Arg = II->getArgOperand(0);
240 auto *VTy = dyn_cast<VectorType>(Arg->getType());
241 if (!VTy)
242 return false;
243
244 ElementCount EC = VTy->getElementCount();
245 Type *ScalarTy = VTy->getElementType();
246 Module *M = II->getModule();
247
248 // If a vector sincos mapping exists for the intrinsic name (e.g.
249 // "llvm.sincos.f32") or for the scalar libcall name ("sincos"/"sincosf"),
250 // leave the call alone -- SelectionDAG legalization will handle it via
251 // expandMultipleResultFPLibCall when the runtime libcall impl is enabled.
252 if (hasIntrinsicVectorMapping(TLI, Intrinsic::sincos, ScalarTy, EC, M))
253 return false;
254 LibFunc LF = NotLibFunc;
255 if (ScalarTy->isFloatTy())
256 LF = LibFunc_sincosf;
257 else if (ScalarTy->isDoubleTy())
258 LF = LibFunc_sincos;
259 if (LF != NotLibFunc && hasVectorMapping(TLI, TLI.getName(LF), EC))
260 return false;
261
262 // Splitting is only worthwhile when both sin and cos have vector mappings.
263 if (!hasIntrinsicVectorMapping(TLI, Intrinsic::sin, ScalarTy, EC, M) ||
264 !hasIntrinsicVectorMapping(TLI, Intrinsic::cos, ScalarTy, EC, M))
265 return false;
266
267 // All users must be extractvalue.
268 for (User *U : II->users()) {
269 if (!isa<ExtractValueInst>(U))
270 return false;
271 }
272
274 Function *SinFn =
275 Intrinsic::getOrInsertDeclaration(M, Intrinsic::sin, Arg->getType());
276 Function *CosFn =
277 Intrinsic::getOrInsertDeclaration(M, Intrinsic::cos, Arg->getType());
278 CallInst *SinCall = B.CreateCall(SinFn, {Arg}, /*FMFSource=*/II, "sin");
279 CallInst *CosCall = B.CreateCall(CosFn, {Arg}, /*FMFSource=*/II, "cos");
280 SinCall->copyMetadata(*II, {LLVMContext::MD_fpmath});
281 CosCall->copyMetadata(*II, {LLVMContext::MD_fpmath});
282
283 // Forward extractvalue uses to the new calls.
284 for (User *U : make_early_inc_range(II->users())) {
285 auto *EV = cast<ExtractValueInst>(U);
286 EV->replaceAllUsesWith(EV->getIndices()[0] == 0 ? SinCall : CosCall);
287 EV->eraseFromParent();
288 }
289
290 // Replace each new call with the vector library function.
292 Replaced.push_back(SinCall);
294 Replaced.push_back(CosCall);
295
296 return true;
297}
298
299static bool runImpl(const TargetLibraryInfo &TLI, Function &F) {
300 SmallVector<Instruction *> ReplacedCalls;
301 for (auto &I : instructions(F)) {
302 auto *II = dyn_cast<IntrinsicInst>(&I);
303 if (!II)
304 continue;
305
306 // Vector llvm.sincos returns a struct so it does not fit the generic
307 // path below; try to split it into separate sin and cos calls when the
308 // target has vector mappings for them.
309 if (trySplitVectorSinCos(TLI, II, ReplacedCalls)) {
310 ReplacedCalls.push_back(&I);
311 continue;
312 }
313
314 // Process only intrinsic calls that return void or a vector.
315 if (!II->getType()->isVectorTy() && !II->getType()->isVoidTy())
316 continue;
317
318 if (replaceWithCallToVeclib(TLI, II))
319 ReplacedCalls.push_back(&I);
320 }
321 // Erase any intrinsic calls that were replaced with vector library calls.
322 for (auto *I : ReplacedCalls)
323 I->eraseFromParent();
324 return !ReplacedCalls.empty();
325}
326
327////////////////////////////////////////////////////////////////////////////////
328// New pass manager implementation.
329////////////////////////////////////////////////////////////////////////////////
333 auto Changed = runImpl(TLI, F);
334 if (Changed) {
335 LLVM_DEBUG(dbgs() << "Intrinsic calls replaced with vector libraries: "
336 << NumCallsReplaced << "\n");
337
345 return PA;
346 }
347
348 // The pass did not replace any calls, hence it preserves all analyses.
349 return PreservedAnalyses::all();
350}
351
352////////////////////////////////////////////////////////////////////////////////
353// Legacy PM Implementation.
354////////////////////////////////////////////////////////////////////////////////
360
370
371////////////////////////////////////////////////////////////////////////////////
372// Legacy Pass manager initialization
373////////////////////////////////////////////////////////////////////////////////
375
377 "Replace intrinsics with calls to vector library", false,
378 false)
381 "Replace intrinsics with calls to vector library", false,
382 false)
383
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runImpl(MachineFunction &MF)
Definition CFIFixup.cpp:304
#define DEBUG_TYPE
This is the interface for a simple mod/ref and alias analysis over globals.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI, IntrinsicInst *II)
Returns true when successfully replaced II, which is a call to a vectorized intrinsic,...
static void replaceWithTLIFunction(IntrinsicInst *II, VFInfo &Info, Function *TLIVecFunc)
Replace the intrinsic call II to TLIVecFunc, which is the corresponding function from the vector libr...
static bool trySplitVectorSinCos(const TargetLibraryInfo &TLI, IntrinsicInst *II, SmallVectorImpl< Instruction * > &Replaced)
If II is a vector llvm.sincos with no direct vector library mapping but the target does have vector m...
static bool hasIntrinsicVectorMapping(const TargetLibraryInfo &TLI, Intrinsic::ID IID, Type *ScalarTy, ElementCount EC, Module *M)
Returns true when TLI has a vector mapping for IID at the given element type and EC.
Function * getTLIFunction(Module *M, FunctionType *VectorFTy, const StringRef TLIName, std::optional< CallingConv::ID > CC, Function *ScalarFunc=nullptr)
Returns a vector Function that it adds to the Module M.
static bool hasVectorMapping(const TargetLibraryInfo &TLI, StringRef Name, ElementCount EC)
Returns true when TLI has a vector mapping for the scalar function name Name at EC (matching either m...
static bool runImpl(const TargetLibraryInfo &TLI, Function &F)
This file contains some templates that are useful if you are working with the STL at all.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
An analysis that produces DemandedBits for a function.
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:168
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
const Function & getFunction() const
Definition Function.h:166
void setCallingConv(CallingConv::ID CC)
Definition Function.h:276
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:838
PointerType * getType() const
Global values are always pointers.
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
Legacy wrapper pass to provide the GlobalsAAResult object.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2554
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2893
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
A wrapper class for inspecting calls to intrinsic functions.
This analysis provides dependence information for the memory accesses of a loop.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
OptimizationRemarkEmitter legacy analysis pass.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
Analysis pass that exposes the ScalarEvolution for a function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
StringRef getName(LibFunc F) const
const VecDesc * getVectorMappingInfo(StringRef F, const ElementCount &VF, bool Masked) const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:288
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:155
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:158
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:306
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
Provides info so a possible vectorization of a function can be computed.
std::optional< CallingConv::ID > getCallingConv() const
LLVM_ABI std::string getVectorFunctionABIVariantString() const
Returns a vector function ABI variant string on the form: ZGV<isa><mask><vlen><vparams><scalarname>(<...
StringRef getVectorFnName() const
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
Changed
LLVM_ABI StringRef getName(ID id)
Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
LLVM_ABI bool isOverloaded(ID id)
Returns true if the intrinsic can be overloaded.
LLVM_ABI std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy)
Function to construct a VFInfo out of a mangled names in the following format:
LLVM_ABI FunctionType * createFunctionType(const VFInfo &Info, const FunctionType *ScalarFTy)
Constructs a FunctionType by applying vector function information to the type of a matching scalar fu...
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
LLVM_ABI bool isVectorIntrinsicWithScalarOpAtArg(Intrinsic::ID ID, unsigned ScalarOpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic has a scalar operand.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI FunctionPass * createReplaceWithVeclibLegacyPass()
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isVectorIntrinsicWithOverloadTypeAtArg(Intrinsic::ID ID, int OpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic is overloaded on the type of the operand at index OpdI...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Holds the VFShape for a specific scalar to vector function mapping.