diff options
Diffstat (limited to 'llvm/lib/IR/IRBuilder.cpp')
| -rw-r--r-- | llvm/lib/IR/IRBuilder.cpp | 256 |
1 files changed, 180 insertions, 76 deletions
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index d0c622fe2389..f871205843a7 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -13,7 +13,6 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/None.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -32,6 +31,7 @@ #include "llvm/Support/Casting.h" #include <cassert> #include <cstdint> +#include <optional> #include <vector> using namespace llvm; @@ -84,12 +84,11 @@ void IRBuilderBase::SetInstDebugLocation(Instruction *I) const { } } -static CallInst *createCallHelper(Function *Callee, ArrayRef<Value *> Ops, - IRBuilderBase *Builder, - const Twine &Name = "", - Instruction *FMFSource = nullptr, - ArrayRef<OperandBundleDef> OpBundles = {}) { - CallInst *CI = Builder->CreateCall(Callee, Ops, OpBundles, Name); +CallInst * +IRBuilderBase::createCallHelper(Function *Callee, ArrayRef<Value *> Ops, + const Twine &Name, Instruction *FMFSource, + ArrayRef<OperandBundleDef> OpBundles) { + CallInst *CI = CreateCall(Callee, Ops, OpBundles, Name); if (FMFSource) CI->copyFastMathFlags(FMFSource); return CI; @@ -102,7 +101,7 @@ Value *IRBuilderBase::CreateVScale(Constant *Scaling, const Twine &Name) { Module *M = GetInsertBlock()->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::vscale, {Scaling->getType()}); - CallInst *CI = createCallHelper(TheFn, {}, this, Name); + CallInst *CI = CreateCall(TheFn, {}, {}, Name); return cast<ConstantInt>(Scaling)->getSExtValue() == 1 ? CI : CreateMul(CI, Scaling); @@ -146,7 +145,7 @@ CallInst *IRBuilderBase::CreateMemSet(Value *Ptr, Value *Val, Value *Size, Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); if (Align) cast<MemSetInst>(CI)->setDestAlignment(*Align); @@ -175,7 +174,7 @@ CallInst *IRBuilderBase::CreateMemSetInline(Value *Dst, MaybeAlign DstAlign, Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset_inline, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); if (DstAlign) cast<MemSetInlineInst>(CI)->setDestAlignment(*DstAlign); @@ -204,7 +203,7 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet( Function *TheFn = Intrinsic::getDeclaration( M, Intrinsic::memset_element_unordered_atomic, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); cast<AtomicMemSetInst>(CI)->setDestAlignment(Alignment); @@ -233,7 +232,7 @@ CallInst *IRBuilderBase::CreateMemTransferInst( Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, IntrID, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); auto* MCI = cast<MemTransferInst>(CI); if (DstAlign) @@ -271,7 +270,7 @@ CallInst *IRBuilderBase::CreateMemCpyInline( Module *M = F->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy_inline, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); auto *MCI = cast<MemCpyInlineInst>(CI); if (DstAlign) @@ -313,7 +312,7 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy( Function *TheFn = Intrinsic::getDeclaration( M, Intrinsic::memcpy_element_unordered_atomic, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); // Set the alignment of the pointer args. auto *AMCI = cast<AtomicMemCpyInst>(CI); @@ -350,7 +349,7 @@ CallInst *IRBuilderBase::CreateMemMove(Value *Dst, MaybeAlign DstAlign, Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); auto *MMI = cast<MemMoveInst>(CI); if (DstAlign) @@ -388,7 +387,7 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove( Function *TheFn = Intrinsic::getDeclaration( M, Intrinsic::memmove_element_unordered_atomic, Tys); - CallInst *CI = createCallHelper(TheFn, Ops, this); + CallInst *CI = CreateCall(TheFn, Ops); // Set the alignment of the pointer args. CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), DstAlign)); @@ -411,13 +410,12 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove( return CI; } -static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID, - Value *Src) { - Module *M = Builder->GetInsertBlock()->getParent()->getParent(); +CallInst *IRBuilderBase::getReductionIntrinsic(Intrinsic::ID ID, Value *Src) { + Module *M = GetInsertBlock()->getParent()->getParent(); Value *Ops[] = {Src}; Type *Tys[] = { Src->getType() }; auto Decl = Intrinsic::getDeclaration(M, ID, Tys); - return createCallHelper(Decl, Ops, Builder); + return CreateCall(Decl, Ops); } CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) { @@ -425,7 +423,7 @@ CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) { Value *Ops[] = {Acc, Src}; auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fadd, {Src->getType()}); - return createCallHelper(Decl, Ops, this); + return CreateCall(Decl, Ops); } CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) { @@ -433,47 +431,47 @@ CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) { Value *Ops[] = {Acc, Src}; auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fmul, {Src->getType()}); - return createCallHelper(Decl, Ops, this); + return CreateCall(Decl, Ops); } CallInst *IRBuilderBase::CreateAddReduce(Value *Src) { - return getReductionIntrinsic(this, Intrinsic::vector_reduce_add, Src); + return getReductionIntrinsic(Intrinsic::vector_reduce_add, Src); } CallInst *IRBuilderBase::CreateMulReduce(Value *Src) { - return getReductionIntrinsic(this, Intrinsic::vector_reduce_mul, Src); + return getReductionIntrinsic(Intrinsic::vector_reduce_mul, Src); } CallInst *IRBuilderBase::CreateAndReduce(Value *Src) { - return getReductionIntrinsic(this, Intrinsic::vector_reduce_and, Src); + return getReductionIntrinsic(Intrinsic::vector_reduce_and, Src); } CallInst *IRBuilderBase::CreateOrReduce(Value *Src) { - return getReductionIntrinsic(this, Intrinsic::vector_reduce_or, Src); + return getReductionIntrinsic(Intrinsic::vector_reduce_or, Src); } CallInst *IRBuilderBase::CreateXorReduce(Value *Src) { - return getReductionIntrinsic(this, Intrinsic::vector_reduce_xor, Src); + return getReductionIntrinsic(Intrinsic::vector_reduce_xor, Src); } CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) { auto ID = IsSigned ? Intrinsic::vector_reduce_smax : Intrinsic::vector_reduce_umax; - return getReductionIntrinsic(this, ID, Src); + return getReductionIntrinsic(ID, Src); } CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) { auto ID = IsSigned ? Intrinsic::vector_reduce_smin : Intrinsic::vector_reduce_umin; - return getReductionIntrinsic(this, ID, Src); + return getReductionIntrinsic(ID, Src); } CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src) { - return getReductionIntrinsic(this, Intrinsic::vector_reduce_fmax, Src); + return getReductionIntrinsic(Intrinsic::vector_reduce_fmax, Src); } CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src) { - return getReductionIntrinsic(this, Intrinsic::vector_reduce_fmin, Src); + return getReductionIntrinsic(Intrinsic::vector_reduce_fmin, Src); } CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) { @@ -489,7 +487,7 @@ CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) { Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_start, {Ptr->getType()}); - return createCallHelper(TheFn, Ops, this); + return CreateCall(TheFn, Ops); } CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) { @@ -505,7 +503,7 @@ CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) { Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::lifetime_end, {Ptr->getType()}); - return createCallHelper(TheFn, Ops, this); + return CreateCall(TheFn, Ops); } CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) { @@ -525,7 +523,38 @@ CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) { Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr); - return createCallHelper(TheFn, Ops, this); + return CreateCall(TheFn, Ops); +} + +static MaybeAlign getAlign(Value *Ptr) { + if (auto *O = dyn_cast<GlobalObject>(Ptr)) + return O->getAlign(); + if (auto *A = dyn_cast<GlobalAlias>(Ptr)) + return A->getAliaseeObject()->getAlign(); + return {}; +} + +CallInst *IRBuilderBase::CreateThreadLocalAddress(Value *Ptr) { +#ifndef NDEBUG + // Handle specially for constexpr cast. This is possible when + // opaque pointers not enabled since constant could be sinked + // directly by the design of llvm. This could be eliminated + // after we eliminate the abuse of constexpr. + auto *V = Ptr; + if (auto *CE = dyn_cast<ConstantExpr>(V)) + if (CE->isCast()) + V = CE->getOperand(0); + + assert(isa<GlobalValue>(V) && cast<GlobalValue>(V)->isThreadLocal() && + "threadlocal_address only applies to thread local variables."); +#endif + CallInst *CI = CreateIntrinsic(llvm::Intrinsic::threadlocal_address, + {Ptr->getType()}, {Ptr}); + if (MaybeAlign A = getAlign(Ptr)) { + CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), *A)); + CI->addRetAttr(Attribute::getWithAlignment(CI->getContext(), *A)); + } + return CI; } CallInst * @@ -537,14 +566,14 @@ IRBuilderBase::CreateAssumption(Value *Cond, Value *Ops[] = { Cond }; Module *M = BB->getParent()->getParent(); Function *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume); - return createCallHelper(FnAssume, Ops, this, "", nullptr, OpBundles); + return CreateCall(FnAssume, Ops, OpBundles); } Instruction *IRBuilderBase::CreateNoAliasScopeDeclaration(Value *Scope) { Module *M = BB->getModule(); auto *FnIntrinsic = Intrinsic::getDeclaration( M, Intrinsic::experimental_noalias_scope_decl, {}); - return createCallHelper(FnIntrinsic, {Scope}, this); + return CreateCall(FnIntrinsic, {Scope}); } /// Create a call to a Masked Load intrinsic. @@ -564,7 +593,7 @@ CallInst *IRBuilderBase::CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, assert(PtrTy->isOpaqueOrPointeeTypeMatches(Ty) && "Wrong element type"); assert(Mask && "Mask should not be all-ones (null)"); if (!PassThru) - PassThru = UndefValue::get(Ty); + PassThru = PoisonValue::get(Ty); Type *OverloadedTypes[] = { Ty, PtrTy }; Value *Ops[] = {Ptr, getInt32(Alignment.value()), Mask, PassThru}; return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops, @@ -598,7 +627,7 @@ CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id, const Twine &Name) { Module *M = BB->getParent()->getParent(); Function *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes); - return createCallHelper(TheFn, Ops, this, Name); + return CreateCall(TheFn, Ops, {}, Name); } /// Create a call to a Masked Gather intrinsic. @@ -628,7 +657,7 @@ CallInst *IRBuilderBase::CreateMaskedGather(Type *Ty, Value *Ptrs, VectorType::get(Type::getInt1Ty(Context), NumElts)); if (!PassThru) - PassThru = UndefValue::get(Ty); + PassThru = PoisonValue::get(Ty); Type *OverloadedTypes[] = {Ty, PtrsTy}; Value *Ops[] = {Ptrs, getInt32(Alignment.value()), Mask, PassThru}; @@ -671,6 +700,53 @@ CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs, return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes); } +/// Create a call to Masked Expand Load intrinsic +/// \p Ty - vector type to load +/// \p Ptr - base pointer for the load +/// \p Mask - vector of booleans which indicates what vector lanes should +/// be accessed in memory +/// \p PassThru - pass-through value that is used to fill the masked-off lanes +/// of the result +/// \p Name - name of the result variable +CallInst *IRBuilderBase::CreateMaskedExpandLoad(Type *Ty, Value *Ptr, + Value *Mask, Value *PassThru, + const Twine &Name) { + auto *PtrTy = cast<PointerType>(Ptr->getType()); + assert(Ty->isVectorTy() && "Type should be vector"); + assert(PtrTy->isOpaqueOrPointeeTypeMatches( + cast<FixedVectorType>(Ty)->getElementType()) && + "Wrong element type"); + (void)PtrTy; + assert(Mask && "Mask should not be all-ones (null)"); + if (!PassThru) + PassThru = PoisonValue::get(Ty); + Type *OverloadedTypes[] = {Ty}; + Value *Ops[] = {Ptr, Mask, PassThru}; + return CreateMaskedIntrinsic(Intrinsic::masked_expandload, Ops, + OverloadedTypes, Name); +} + +/// Create a call to Masked Compress Store intrinsic +/// \p Val - data to be stored, +/// \p Ptr - base pointer for the store +/// \p Mask - vector of booleans which indicates what vector lanes should +/// be accessed in memory +CallInst *IRBuilderBase::CreateMaskedCompressStore(Value *Val, Value *Ptr, + Value *Mask) { + auto *PtrTy = cast<PointerType>(Ptr->getType()); + Type *DataTy = Val->getType(); + assert(DataTy->isVectorTy() && "Val should be a vector"); + assert(PtrTy->isOpaqueOrPointeeTypeMatches( + cast<FixedVectorType>(DataTy)->getElementType()) && + "Wrong element type"); + (void)PtrTy; + assert(Mask && "Mask should not be all-ones (null)"); + Type *OverloadedTypes[] = {DataTy}; + Value *Ops[] = {Val, Ptr, Mask}; + return CreateMaskedIntrinsic(Intrinsic::masked_compressstore, Ops, + OverloadedTypes); +} + template <typename T0> static std::vector<Value *> getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes, @@ -692,8 +768,8 @@ getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes, template<typename T1, typename T2, typename T3> static std::vector<OperandBundleDef> -getStatepointBundles(Optional<ArrayRef<T1>> TransitionArgs, - Optional<ArrayRef<T2>> DeoptArgs, +getStatepointBundles(std::optional<ArrayRef<T1>> TransitionArgs, + std::optional<ArrayRef<T2>> DeoptArgs, ArrayRef<T3> GCArgs) { std::vector<OperandBundleDef> Rval; if (DeoptArgs) { @@ -718,8 +794,9 @@ template <typename T0, typename T1, typename T2, typename T3> static CallInst *CreateGCStatepointCallCommon( IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs, - Optional<ArrayRef<T1>> TransitionArgs, Optional<ArrayRef<T2>> DeoptArgs, - ArrayRef<T3> GCArgs, const Twine &Name) { + std::optional<ArrayRef<T1>> TransitionArgs, + std::optional<ArrayRef<T2>> DeoptArgs, ArrayRef<T3> GCArgs, + const Twine &Name) { Module *M = Builder->GetInsertBlock()->getParent()->getParent(); // Fill in the one generic type'd argument (the function is also vararg) Function *FnStatepoint = @@ -740,18 +817,19 @@ static CallInst *CreateGCStatepointCallCommon( CallInst *IRBuilderBase::CreateGCStatepointCall( uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualCallee, - ArrayRef<Value *> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs, + ArrayRef<Value *> CallArgs, std::optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>( this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None), - CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name); + CallArgs, std::nullopt /* No Transition Args */, DeoptArgs, GCArgs, Name); } CallInst *IRBuilderBase::CreateGCStatepointCall( uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualCallee, uint32_t Flags, ArrayRef<Value *> CallArgs, - Optional<ArrayRef<Use>> TransitionArgs, Optional<ArrayRef<Use>> DeoptArgs, - ArrayRef<Value *> GCArgs, const Twine &Name) { + std::optional<ArrayRef<Use>> TransitionArgs, + std::optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs, + const Twine &Name) { return CreateGCStatepointCallCommon<Value *, Use, Use, Value *>( this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs, DeoptArgs, GCArgs, Name); @@ -759,11 +837,11 @@ CallInst *IRBuilderBase::CreateGCStatepointCall( CallInst *IRBuilderBase::CreateGCStatepointCall( uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualCallee, - ArrayRef<Use> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs, + ArrayRef<Use> CallArgs, std::optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>( this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None), - CallArgs, None, DeoptArgs, GCArgs, Name); + CallArgs, std::nullopt, DeoptArgs, GCArgs, Name); } template <typename T0, typename T1, typename T2, typename T3> @@ -771,8 +849,9 @@ static InvokeInst *CreateGCStatepointInvokeCommon( IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, ArrayRef<T0> InvokeArgs, - Optional<ArrayRef<T1>> TransitionArgs, Optional<ArrayRef<T2>> DeoptArgs, - ArrayRef<T3> GCArgs, const Twine &Name) { + std::optional<ArrayRef<T1>> TransitionArgs, + std::optional<ArrayRef<T2>> DeoptArgs, ArrayRef<T3> GCArgs, + const Twine &Name) { Module *M = Builder->GetInsertBlock()->getParent()->getParent(); // Fill in the one generic type'd argument (the function is also vararg) Function *FnStatepoint = @@ -795,19 +874,19 @@ static InvokeInst *CreateGCStatepointInvokeCommon( InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, - ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Value *>> DeoptArgs, + ArrayRef<Value *> InvokeArgs, std::optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>( this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, - uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/, - DeoptArgs, GCArgs, Name); + uint32_t(StatepointFlags::None), InvokeArgs, + std::nullopt /* No Transition Args*/, DeoptArgs, GCArgs, Name); } InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags, - ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs, - Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs, + ArrayRef<Value *> InvokeArgs, std::optional<ArrayRef<Use>> TransitionArgs, + std::optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { return CreateGCStatepointInvokeCommon<Value *, Use, Use, Value *>( this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags, @@ -817,12 +896,12 @@ InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( InvokeInst *IRBuilderBase::CreateGCStatepointInvoke( uint64_t ID, uint32_t NumPatchBytes, FunctionCallee ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs, - Optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, + std::optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) { return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>( this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, - uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs, - Name); + uint32_t(StatepointFlags::None), InvokeArgs, std::nullopt, DeoptArgs, + GCArgs, Name); } CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint, @@ -833,7 +912,7 @@ CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint, Function *FnGCResult = Intrinsic::getDeclaration(M, ID, Types); Value *Args[] = {Statepoint}; - return createCallHelper(FnGCResult, Args, this, Name); + return CreateCall(FnGCResult, Args, {}, Name); } CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint, @@ -845,7 +924,7 @@ CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint, Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types); Value *Args[] = {Statepoint, getInt32(BaseOffset), getInt32(DerivedOffset)}; - return createCallHelper(FnGCRelocate, Args, this, Name); + return CreateCall(FnGCRelocate, Args, {}, Name); } CallInst *IRBuilderBase::CreateGCGetPointerBase(Value *DerivedPtr, @@ -854,7 +933,7 @@ CallInst *IRBuilderBase::CreateGCGetPointerBase(Value *DerivedPtr, Type *PtrTy = DerivedPtr->getType(); Function *FnGCFindBase = Intrinsic::getDeclaration( M, Intrinsic::experimental_gc_get_pointer_base, {PtrTy, PtrTy}); - return createCallHelper(FnGCFindBase, {DerivedPtr}, this, Name); + return CreateCall(FnGCFindBase, {DerivedPtr}, {}, Name); } CallInst *IRBuilderBase::CreateGCGetPointerOffset(Value *DerivedPtr, @@ -863,7 +942,7 @@ CallInst *IRBuilderBase::CreateGCGetPointerOffset(Value *DerivedPtr, Type *PtrTy = DerivedPtr->getType(); Function *FnGCGetOffset = Intrinsic::getDeclaration( M, Intrinsic::experimental_gc_get_pointer_offset, {PtrTy}); - return createCallHelper(FnGCGetOffset, {DerivedPtr}, this, Name); + return CreateCall(FnGCGetOffset, {DerivedPtr}, {}, Name); } CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, @@ -871,7 +950,7 @@ CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V, const Twine &Name) { Module *M = BB->getModule(); Function *Fn = Intrinsic::getDeclaration(M, ID, {V->getType()}); - return createCallHelper(Fn, {V}, this, Name, FMFSource); + return createCallHelper(Fn, {V}, Name, FMFSource); } CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, @@ -880,7 +959,7 @@ CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, const Twine &Name) { Module *M = BB->getModule(); Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() }); - return createCallHelper(Fn, {LHS, RHS}, this, Name, FMFSource); + return createCallHelper(Fn, {LHS, RHS}, Name, FMFSource); } CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID, @@ -890,14 +969,41 @@ CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID, const Twine &Name) { Module *M = BB->getModule(); Function *Fn = Intrinsic::getDeclaration(M, ID, Types); - return createCallHelper(Fn, Args, this, Name, FMFSource); + return createCallHelper(Fn, Args, Name, FMFSource); +} + +CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID, + ArrayRef<Value *> Args, + Instruction *FMFSource, + const Twine &Name) { + Module *M = BB->getModule(); + + SmallVector<Intrinsic::IITDescriptor> Table; + Intrinsic::getIntrinsicInfoTableEntries(ID, Table); + ArrayRef<Intrinsic::IITDescriptor> TableRef(Table); + + SmallVector<Type *> ArgTys; + ArgTys.reserve(Args.size()); + for (auto &I : Args) + ArgTys.push_back(I->getType()); + FunctionType *FTy = FunctionType::get(RetTy, ArgTys, false); + SmallVector<Type *> OverloadTys; + Intrinsic::MatchIntrinsicTypesResult Res = + matchIntrinsicSignature(FTy, TableRef, OverloadTys); + (void)Res; + assert(Res == Intrinsic::MatchIntrinsicTypes_Match && TableRef.empty() && + "Wrong types for intrinsic!"); + // TODO: Handle varargs intrinsics. + + Function *Fn = Intrinsic::getDeclaration(M, ID, OverloadTys); + return createCallHelper(Fn, Args, Name, FMFSource); } CallInst *IRBuilderBase::CreateConstrainedFPBinOp( Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag, - Optional<RoundingMode> Rounding, - Optional<fp::ExceptionBehavior> Except) { + std::optional<RoundingMode> Rounding, + std::optional<fp::ExceptionBehavior> Except) { Value *RoundingV = getConstrainedFPRounding(Rounding); Value *ExceptV = getConstrainedFPExcept(Except); @@ -930,8 +1036,8 @@ Value *IRBuilderBase::CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops, CallInst *IRBuilderBase::CreateConstrainedFPCast( Intrinsic::ID ID, Value *V, Type *DestTy, Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag, - Optional<RoundingMode> Rounding, - Optional<fp::ExceptionBehavior> Except) { + std::optional<RoundingMode> Rounding, + std::optional<fp::ExceptionBehavior> Except) { Value *ExceptV = getConstrainedFPExcept(Except); FastMathFlags UseFMF = FMF; @@ -981,7 +1087,7 @@ Value *IRBuilderBase::CreateFCmpHelper( CallInst *IRBuilderBase::CreateConstrainedFPCmp( Intrinsic::ID ID, CmpInst::Predicate P, Value *L, Value *R, - const Twine &Name, Optional<fp::ExceptionBehavior> Except) { + const Twine &Name, std::optional<fp::ExceptionBehavior> Except) { Value *PredicateV = getConstrainedFPPredicate(P); Value *ExceptV = getConstrainedFPExcept(Except); @@ -993,8 +1099,8 @@ CallInst *IRBuilderBase::CreateConstrainedFPCmp( CallInst *IRBuilderBase::CreateConstrainedFPCall( Function *Callee, ArrayRef<Value *> Args, const Twine &Name, - Optional<RoundingMode> Rounding, - Optional<fp::ExceptionBehavior> Except) { + std::optional<RoundingMode> Rounding, + std::optional<fp::ExceptionBehavior> Except) { llvm::SmallVector<Value *, 6> UseArgs; append_range(UseArgs, Args); @@ -1151,10 +1257,8 @@ Value *IRBuilderBase::CreateVectorSplat(ElementCount EC, Value *V, assert(EC.isNonZero() && "Cannot splat to an empty vector!"); // First insert it into a poison vector so we can shuffle it. - Type *I32Ty = getInt32Ty(); Value *Poison = PoisonValue::get(VectorType::get(V->getType(), EC)); - V = CreateInsertElement(Poison, V, ConstantInt::get(I32Ty, 0), - Name + ".splatinsert"); + V = CreateInsertElement(Poison, V, getInt64(0), Name + ".splatinsert"); // Shuffle the value across the desired number of elements. SmallVector<int, 16> Zeros; |
