1 //===- IRBuilder.cpp - Builder for LLVM Instrs ----------------------------===//
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 // This file implements the IRBuilder class, which is used as a convenient way
10 // to create LLVM instructions with a consistent and simplified interface.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/IR/IRBuilder.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/None.h"
17 #include "llvm/IR/Constant.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/GlobalValue.h"
22 #include "llvm/IR/GlobalVariable.h"
23 #include "llvm/IR/IntrinsicInst.h"
24 #include "llvm/IR/Intrinsics.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/IR/NoFolder.h"
27 #include "llvm/IR/Operator.h"
28 #include "llvm/IR/Statepoint.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/IR/Value.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/MathExtras.h"
33 #include <cassert>
34 #include <cstdint>
35 #include <vector>
36
37 using namespace llvm;
38
39 /// CreateGlobalString - Make a new global variable with an initializer that
40 /// has array of i8 type filled in with the nul terminated string value
41 /// specified. If Name is specified, it is the name of the global variable
42 /// created.
CreateGlobalString(StringRef Str,const Twine & Name,unsigned AddressSpace,Module * M)43 GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
44 const Twine &Name,
45 unsigned AddressSpace,
46 Module *M) {
47 Constant *StrConstant = ConstantDataArray::getString(Context, Str);
48 if (!M)
49 M = BB->getParent()->getParent();
50 auto *GV = new GlobalVariable(
51 *M, StrConstant->getType(), true, GlobalValue::PrivateLinkage,
52 StrConstant, Name, nullptr, GlobalVariable::NotThreadLocal, AddressSpace);
53 GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
54 GV->setAlignment(Align(1));
55 return GV;
56 }
57
getCurrentFunctionReturnType() const58 Type *IRBuilderBase::getCurrentFunctionReturnType() const {
59 assert(BB && BB->getParent() && "No current function!");
60 return BB->getParent()->getReturnType();
61 }
62
getCastedInt8PtrValue(Value * Ptr)63 Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
64 auto *PT = cast<PointerType>(Ptr->getType());
65 if (PT->getElementType()->isIntegerTy(8))
66 return Ptr;
67
68 // Otherwise, we need to insert a bitcast.
69 return CreateBitCast(Ptr, getInt8PtrTy(PT->getAddressSpace()));
70 }
71
createCallHelper(Function * Callee,ArrayRef<Value * > Ops,IRBuilderBase * Builder,const Twine & Name="",Instruction * FMFSource=nullptr,ArrayRef<OperandBundleDef> OpBundles={})72 static CallInst *createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
73 IRBuilderBase *Builder,
74 const Twine &Name = "",
75 Instruction *FMFSource = nullptr,
76 ArrayRef<OperandBundleDef> OpBundles = {}) {
77 CallInst *CI = Builder->CreateCall(Callee, Ops, OpBundles, Name);
78 if (FMFSource)
79 CI->copyFastMathFlags(FMFSource);
80 return CI;
81 }
82
CreateVScale(Constant * Scaling,const Twine & Name)83 Value *IRBuilderBase::CreateVScale(Constant *Scaling, const Twine &Name) {
84 Module *M = GetInsertBlock()->getParent()->getParent();
85 assert(isa<ConstantInt>(Scaling) && "Expected constant integer");
86 Function *TheFn =
87 Intrinsic::getDeclaration(M, Intrinsic::vscale, {Scaling->getType()});
88 CallInst *CI = createCallHelper(TheFn, {}, this, Name);
89 return cast<ConstantInt>(Scaling)->getSExtValue() == 1
90 ? CI
91 : CreateMul(CI, Scaling);
92 }
93
CreateMemSet(Value * Ptr,Value * Val,Value * Size,MaybeAlign Align,bool isVolatile,MDNode * TBAATag,MDNode * ScopeTag,MDNode * NoAliasTag)94 CallInst *IRBuilderBase::CreateMemSet(Value *Ptr, Value *Val, Value *Size,
95 MaybeAlign Align, bool isVolatile,
96 MDNode *TBAATag, MDNode *ScopeTag,
97 MDNode *NoAliasTag) {
98 Ptr = getCastedInt8PtrValue(Ptr);
99 Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
100 Type *Tys[] = { Ptr->getType(), Size->getType() };
101 Module *M = BB->getParent()->getParent();
102 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
103
104 CallInst *CI = createCallHelper(TheFn, Ops, this);
105
106 if (Align)
107 cast<MemSetInst>(CI)->setDestAlignment(Align->value());
108
109 // Set the TBAA info if present.
110 if (TBAATag)
111 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
112
113 if (ScopeTag)
114 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
115
116 if (NoAliasTag)
117 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
118
119 return CI;
120 }
121
CreateElementUnorderedAtomicMemSet(Value * Ptr,Value * Val,Value * Size,Align Alignment,uint32_t ElementSize,MDNode * TBAATag,MDNode * ScopeTag,MDNode * NoAliasTag)122 CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet(
123 Value *Ptr, Value *Val, Value *Size, Align Alignment, uint32_t ElementSize,
124 MDNode *TBAATag, MDNode *ScopeTag, MDNode *NoAliasTag) {
125
126 Ptr = getCastedInt8PtrValue(Ptr);
127 Value *Ops[] = {Ptr, Val, Size, getInt32(ElementSize)};
128 Type *Tys[] = {Ptr->getType(), Size->getType()};
129 Module *M = BB->getParent()->getParent();
130 Function *TheFn = Intrinsic::getDeclaration(
131 M, Intrinsic::memset_element_unordered_atomic, Tys);
132
133 CallInst *CI = createCallHelper(TheFn, Ops, this);
134
135 cast<AtomicMemSetInst>(CI)->setDestAlignment(Alignment);
136
137 // Set the TBAA info if present.
138 if (TBAATag)
139 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
140
141 if (ScopeTag)
142 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
143
144 if (NoAliasTag)
145 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
146
147 return CI;
148 }
149
CreateMemTransferInst(Intrinsic::ID IntrID,Value * Dst,MaybeAlign DstAlign,Value * Src,MaybeAlign SrcAlign,Value * Size,bool isVolatile,MDNode * TBAATag,MDNode * TBAAStructTag,MDNode * ScopeTag,MDNode * NoAliasTag)150 CallInst *IRBuilderBase::CreateMemTransferInst(
151 Intrinsic::ID IntrID, Value *Dst, MaybeAlign DstAlign, Value *Src,
152 MaybeAlign SrcAlign, Value *Size, bool isVolatile, MDNode *TBAATag,
153 MDNode *TBAAStructTag, MDNode *ScopeTag, MDNode *NoAliasTag) {
154 Dst = getCastedInt8PtrValue(Dst);
155 Src = getCastedInt8PtrValue(Src);
156
157 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
158 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
159 Module *M = BB->getParent()->getParent();
160 Function *TheFn = Intrinsic::getDeclaration(M, IntrID, Tys);
161
162 CallInst *CI = createCallHelper(TheFn, Ops, this);
163
164 auto* MCI = cast<MemTransferInst>(CI);
165 if (DstAlign)
166 MCI->setDestAlignment(*DstAlign);
167 if (SrcAlign)
168 MCI->setSourceAlignment(*SrcAlign);
169
170 // Set the TBAA info if present.
171 if (TBAATag)
172 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
173
174 // Set the TBAA Struct info if present.
175 if (TBAAStructTag)
176 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
177
178 if (ScopeTag)
179 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
180
181 if (NoAliasTag)
182 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
183
184 return CI;
185 }
186
CreateMemCpyInline(Value * Dst,MaybeAlign DstAlign,Value * Src,MaybeAlign SrcAlign,Value * Size)187 CallInst *IRBuilderBase::CreateMemCpyInline(Value *Dst, MaybeAlign DstAlign,
188 Value *Src, MaybeAlign SrcAlign,
189 Value *Size) {
190 Dst = getCastedInt8PtrValue(Dst);
191 Src = getCastedInt8PtrValue(Src);
192 Value *IsVolatile = getInt1(false);
193
194 Value *Ops[] = {Dst, Src, Size, IsVolatile};
195 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
196 Function *F = BB->getParent();
197 Module *M = F->getParent();
198 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy_inline, Tys);
199
200 CallInst *CI = createCallHelper(TheFn, Ops, this);
201
202 auto *MCI = cast<MemCpyInlineInst>(CI);
203 if (DstAlign)
204 MCI->setDestAlignment(*DstAlign);
205 if (SrcAlign)
206 MCI->setSourceAlignment(*SrcAlign);
207
208 return CI;
209 }
210
CreateElementUnorderedAtomicMemCpy(Value * Dst,Align DstAlign,Value * Src,Align SrcAlign,Value * Size,uint32_t ElementSize,MDNode * TBAATag,MDNode * TBAAStructTag,MDNode * ScopeTag,MDNode * NoAliasTag)211 CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
212 Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size,
213 uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
214 MDNode *ScopeTag, MDNode *NoAliasTag) {
215 assert(DstAlign >= ElementSize &&
216 "Pointer alignment must be at least element size");
217 assert(SrcAlign >= ElementSize &&
218 "Pointer alignment must be at least element size");
219 Dst = getCastedInt8PtrValue(Dst);
220 Src = getCastedInt8PtrValue(Src);
221
222 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
223 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
224 Module *M = BB->getParent()->getParent();
225 Function *TheFn = Intrinsic::getDeclaration(
226 M, Intrinsic::memcpy_element_unordered_atomic, Tys);
227
228 CallInst *CI = createCallHelper(TheFn, Ops, this);
229
230 // Set the alignment of the pointer args.
231 auto *AMCI = cast<AtomicMemCpyInst>(CI);
232 AMCI->setDestAlignment(DstAlign);
233 AMCI->setSourceAlignment(SrcAlign);
234
235 // Set the TBAA info if present.
236 if (TBAATag)
237 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
238
239 // Set the TBAA Struct info if present.
240 if (TBAAStructTag)
241 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
242
243 if (ScopeTag)
244 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
245
246 if (NoAliasTag)
247 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
248
249 return CI;
250 }
251
CreateMemMove(Value * Dst,MaybeAlign DstAlign,Value * Src,MaybeAlign SrcAlign,Value * Size,bool isVolatile,MDNode * TBAATag,MDNode * ScopeTag,MDNode * NoAliasTag)252 CallInst *IRBuilderBase::CreateMemMove(Value *Dst, MaybeAlign DstAlign,
253 Value *Src, MaybeAlign SrcAlign,
254 Value *Size, bool isVolatile,
255 MDNode *TBAATag, MDNode *ScopeTag,
256 MDNode *NoAliasTag) {
257 Dst = getCastedInt8PtrValue(Dst);
258 Src = getCastedInt8PtrValue(Src);
259
260 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
261 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
262 Module *M = BB->getParent()->getParent();
263 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
264
265 CallInst *CI = createCallHelper(TheFn, Ops, this);
266
267 auto *MMI = cast<MemMoveInst>(CI);
268 if (DstAlign)
269 MMI->setDestAlignment(*DstAlign);
270 if (SrcAlign)
271 MMI->setSourceAlignment(*SrcAlign);
272
273 // Set the TBAA info if present.
274 if (TBAATag)
275 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
276
277 if (ScopeTag)
278 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
279
280 if (NoAliasTag)
281 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
282
283 return CI;
284 }
285
CreateElementUnorderedAtomicMemMove(Value * Dst,Align DstAlign,Value * Src,Align SrcAlign,Value * Size,uint32_t ElementSize,MDNode * TBAATag,MDNode * TBAAStructTag,MDNode * ScopeTag,MDNode * NoAliasTag)286 CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove(
287 Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size,
288 uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
289 MDNode *ScopeTag, MDNode *NoAliasTag) {
290 assert(DstAlign >= ElementSize &&
291 "Pointer alignment must be at least element size");
292 assert(SrcAlign >= ElementSize &&
293 "Pointer alignment must be at least element size");
294 Dst = getCastedInt8PtrValue(Dst);
295 Src = getCastedInt8PtrValue(Src);
296
297 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
298 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
299 Module *M = BB->getParent()->getParent();
300 Function *TheFn = Intrinsic::getDeclaration(
301 M, Intrinsic::memmove_element_unordered_atomic, Tys);
302
303 CallInst *CI = createCallHelper(TheFn, Ops, this);
304
305 // Set the alignment of the pointer args.
306 CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), DstAlign));
307 CI->addParamAttr(1, Attribute::getWithAlignment(CI->getContext(), SrcAlign));
308
309 // Set the TBAA info if present.
310 if (TBAATag)
311 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
312
313 // Set the TBAA Struct info if present.
314 if (TBAAStructTag)
315 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
316
317 if (ScopeTag)
318 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
319
320 if (NoAliasTag)
321 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
322
323 return CI;
324 }
325
getReductionIntrinsic(IRBuilderBase * Builder,Intrinsic::ID ID,Value * Src)326 static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
327 Value *Src) {
328 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
329 Value *Ops[] = {Src};
330 Type *Tys[] = { Src->getType() };
331 auto Decl = Intrinsic::getDeclaration(M, ID, Tys);
332 return createCallHelper(Decl, Ops, Builder);
333 }
334
CreateFAddReduce(Value * Acc,Value * Src)335 CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
336 Module *M = GetInsertBlock()->getParent()->getParent();
337 Value *Ops[] = {Acc, Src};
338 auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fadd,
339 {Src->getType()});
340 return createCallHelper(Decl, Ops, this);
341 }
342
CreateFMulReduce(Value * Acc,Value * Src)343 CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
344 Module *M = GetInsertBlock()->getParent()->getParent();
345 Value *Ops[] = {Acc, Src};
346 auto Decl = Intrinsic::getDeclaration(M, Intrinsic::vector_reduce_fmul,
347 {Src->getType()});
348 return createCallHelper(Decl, Ops, this);
349 }
350
CreateAddReduce(Value * Src)351 CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
352 return getReductionIntrinsic(this, Intrinsic::vector_reduce_add, Src);
353 }
354
CreateMulReduce(Value * Src)355 CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
356 return getReductionIntrinsic(this, Intrinsic::vector_reduce_mul, Src);
357 }
358
CreateAndReduce(Value * Src)359 CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
360 return getReductionIntrinsic(this, Intrinsic::vector_reduce_and, Src);
361 }
362
CreateOrReduce(Value * Src)363 CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
364 return getReductionIntrinsic(this, Intrinsic::vector_reduce_or, Src);
365 }
366
CreateXorReduce(Value * Src)367 CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
368 return getReductionIntrinsic(this, Intrinsic::vector_reduce_xor, Src);
369 }
370
CreateIntMaxReduce(Value * Src,bool IsSigned)371 CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
372 auto ID =
373 IsSigned ? Intrinsic::vector_reduce_smax : Intrinsic::vector_reduce_umax;
374 return getReductionIntrinsic(this, ID, Src);
375 }
376
CreateIntMinReduce(Value * Src,bool IsSigned)377 CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
378 auto ID =
379 IsSigned ? Intrinsic::vector_reduce_smin : Intrinsic::vector_reduce_umin;
380 return getReductionIntrinsic(this, ID, Src);
381 }
382
CreateFPMaxReduce(Value * Src,bool NoNaN)383 CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src, bool NoNaN) {
384 auto Rdx = getReductionIntrinsic(this, Intrinsic::vector_reduce_fmax, Src);
385 if (NoNaN) {
386 FastMathFlags FMF;
387 FMF.setNoNaNs();
388 Rdx->setFastMathFlags(FMF);
389 }
390 return Rdx;
391 }
392
CreateFPMinReduce(Value * Src,bool NoNaN)393 CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src, bool NoNaN) {
394 auto Rdx = getReductionIntrinsic(this, Intrinsic::vector_reduce_fmin, Src);
395 if (NoNaN) {
396 FastMathFlags FMF;
397 FMF.setNoNaNs();
398 Rdx->setFastMathFlags(FMF);
399 }
400 return Rdx;
401 }
402
CreateLifetimeStart(Value * Ptr,ConstantInt * Size)403 CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
404 assert(isa<PointerType>(Ptr->getType()) &&
405 "lifetime.start only applies to pointers.");
406 Ptr = getCastedInt8PtrValue(Ptr);
407 if (!Size)
408 Size = getInt64(-1);
409 else
410 assert(Size->getType() == getInt64Ty() &&
411 "lifetime.start requires the size to be an i64");
412 Value *Ops[] = { Size, Ptr };
413 Module *M = BB->getParent()->getParent();
414 Function *TheFn =
415 Intrinsic::getDeclaration(M, Intrinsic::lifetime_start, {Ptr->getType()});
416 return createCallHelper(TheFn, Ops, this);
417 }
418
CreateLifetimeEnd(Value * Ptr,ConstantInt * Size)419 CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
420 assert(isa<PointerType>(Ptr->getType()) &&
421 "lifetime.end only applies to pointers.");
422 Ptr = getCastedInt8PtrValue(Ptr);
423 if (!Size)
424 Size = getInt64(-1);
425 else
426 assert(Size->getType() == getInt64Ty() &&
427 "lifetime.end requires the size to be an i64");
428 Value *Ops[] = { Size, Ptr };
429 Module *M = BB->getParent()->getParent();
430 Function *TheFn =
431 Intrinsic::getDeclaration(M, Intrinsic::lifetime_end, {Ptr->getType()});
432 return createCallHelper(TheFn, Ops, this);
433 }
434
CreateInvariantStart(Value * Ptr,ConstantInt * Size)435 CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
436
437 assert(isa<PointerType>(Ptr->getType()) &&
438 "invariant.start only applies to pointers.");
439 Ptr = getCastedInt8PtrValue(Ptr);
440 if (!Size)
441 Size = getInt64(-1);
442 else
443 assert(Size->getType() == getInt64Ty() &&
444 "invariant.start requires the size to be an i64");
445
446 Value *Ops[] = {Size, Ptr};
447 // Fill in the single overloaded type: memory object type.
448 Type *ObjectPtr[1] = {Ptr->getType()};
449 Module *M = BB->getParent()->getParent();
450 Function *TheFn =
451 Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr);
452 return createCallHelper(TheFn, Ops, this);
453 }
454
455 CallInst *
CreateAssumption(Value * Cond,ArrayRef<OperandBundleDef> OpBundles)456 IRBuilderBase::CreateAssumption(Value *Cond,
457 ArrayRef<OperandBundleDef> OpBundles) {
458 assert(Cond->getType() == getInt1Ty() &&
459 "an assumption condition must be of type i1");
460
461 Value *Ops[] = { Cond };
462 Module *M = BB->getParent()->getParent();
463 Function *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
464 return createCallHelper(FnAssume, Ops, this, "", nullptr, OpBundles);
465 }
466
467 /// Create a call to a Masked Load intrinsic.
468 /// \p Ptr - base pointer for the load
469 /// \p Alignment - alignment of the source location
470 /// \p Mask - vector of booleans which indicates what vector lanes should
471 /// be accessed in memory
472 /// \p PassThru - pass-through value that is used to fill the masked-off lanes
473 /// of the result
474 /// \p Name - name of the result variable
CreateMaskedLoad(Value * Ptr,Align Alignment,Value * Mask,Value * PassThru,const Twine & Name)475 CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, Align Alignment,
476 Value *Mask, Value *PassThru,
477 const Twine &Name) {
478 auto *PtrTy = cast<PointerType>(Ptr->getType());
479 Type *DataTy = PtrTy->getElementType();
480 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
481 assert(Mask && "Mask should not be all-ones (null)");
482 if (!PassThru)
483 PassThru = UndefValue::get(DataTy);
484 Type *OverloadedTypes[] = { DataTy, PtrTy };
485 Value *Ops[] = {Ptr, getInt32(Alignment.value()), Mask, PassThru};
486 return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
487 OverloadedTypes, Name);
488 }
489
490 /// Create a call to a Masked Store intrinsic.
491 /// \p Val - data to be stored,
492 /// \p Ptr - base pointer for the store
493 /// \p Alignment - alignment of the destination location
494 /// \p Mask - vector of booleans which indicates what vector lanes should
495 /// be accessed in memory
CreateMaskedStore(Value * Val,Value * Ptr,Align Alignment,Value * Mask)496 CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
497 Align Alignment, Value *Mask) {
498 auto *PtrTy = cast<PointerType>(Ptr->getType());
499 Type *DataTy = PtrTy->getElementType();
500 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
501 assert(Mask && "Mask should not be all-ones (null)");
502 Type *OverloadedTypes[] = { DataTy, PtrTy };
503 Value *Ops[] = {Val, Ptr, getInt32(Alignment.value()), Mask};
504 return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
505 }
506
507 /// Create a call to a Masked intrinsic, with given intrinsic Id,
508 /// an array of operands - Ops, and an array of overloaded types -
509 /// OverloadedTypes.
CreateMaskedIntrinsic(Intrinsic::ID Id,ArrayRef<Value * > Ops,ArrayRef<Type * > OverloadedTypes,const Twine & Name)510 CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
511 ArrayRef<Value *> Ops,
512 ArrayRef<Type *> OverloadedTypes,
513 const Twine &Name) {
514 Module *M = BB->getParent()->getParent();
515 Function *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
516 return createCallHelper(TheFn, Ops, this, Name);
517 }
518
519 /// Create a call to a Masked Gather intrinsic.
520 /// \p Ptrs - vector of pointers for loading
521 /// \p Align - alignment for one element
522 /// \p Mask - vector of booleans which indicates what vector lanes should
523 /// be accessed in memory
524 /// \p PassThru - pass-through value that is used to fill the masked-off lanes
525 /// of the result
526 /// \p Name - name of the result variable
CreateMaskedGather(Value * Ptrs,Align Alignment,Value * Mask,Value * PassThru,const Twine & Name)527 CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, Align Alignment,
528 Value *Mask, Value *PassThru,
529 const Twine &Name) {
530 auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
531 auto *PtrTy = cast<PointerType>(PtrsTy->getElementType());
532 unsigned NumElts = PtrsTy->getNumElements();
533 auto *DataTy = FixedVectorType::get(PtrTy->getElementType(), NumElts);
534
535 if (!Mask)
536 Mask = Constant::getAllOnesValue(
537 FixedVectorType::get(Type::getInt1Ty(Context), NumElts));
538
539 if (!PassThru)
540 PassThru = UndefValue::get(DataTy);
541
542 Type *OverloadedTypes[] = {DataTy, PtrsTy};
543 Value *Ops[] = {Ptrs, getInt32(Alignment.value()), Mask, PassThru};
544
545 // We specify only one type when we create this intrinsic. Types of other
546 // arguments are derived from this type.
547 return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, OverloadedTypes,
548 Name);
549 }
550
551 /// Create a call to a Masked Scatter intrinsic.
552 /// \p Data - data to be stored,
553 /// \p Ptrs - the vector of pointers, where the \p Data elements should be
554 /// stored
555 /// \p Align - alignment for one element
556 /// \p Mask - vector of booleans which indicates what vector lanes should
557 /// be accessed in memory
CreateMaskedScatter(Value * Data,Value * Ptrs,Align Alignment,Value * Mask)558 CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
559 Align Alignment, Value *Mask) {
560 auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
561 auto *DataTy = cast<FixedVectorType>(Data->getType());
562 unsigned NumElts = PtrsTy->getNumElements();
563
564 #ifndef NDEBUG
565 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
566 assert(NumElts == DataTy->getNumElements() &&
567 PtrTy->getElementType() == DataTy->getElementType() &&
568 "Incompatible pointer and data types");
569 #endif
570
571 if (!Mask)
572 Mask = Constant::getAllOnesValue(
573 FixedVectorType::get(Type::getInt1Ty(Context), NumElts));
574
575 Type *OverloadedTypes[] = {DataTy, PtrsTy};
576 Value *Ops[] = {Data, Ptrs, getInt32(Alignment.value()), Mask};
577
578 // We specify only one type when we create this intrinsic. Types of other
579 // arguments are derived from this type.
580 return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
581 }
582
583 template <typename T0>
584 static std::vector<Value *>
getStatepointArgs(IRBuilderBase & B,uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,uint32_t Flags,ArrayRef<T0> CallArgs)585 getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
586 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs) {
587 std::vector<Value *> Args;
588 Args.push_back(B.getInt64(ID));
589 Args.push_back(B.getInt32(NumPatchBytes));
590 Args.push_back(ActualCallee);
591 Args.push_back(B.getInt32(CallArgs.size()));
592 Args.push_back(B.getInt32(Flags));
593 Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
594 // GC Transition and Deopt args are now always handled via operand bundle.
595 // They will be removed from the signature of gc.statepoint shortly.
596 Args.push_back(B.getInt32(0));
597 Args.push_back(B.getInt32(0));
598 // GC args are now encoded in the gc-live operand bundle
599 return Args;
600 }
601
602 template<typename T1, typename T2, typename T3>
603 static std::vector<OperandBundleDef>
getStatepointBundles(Optional<ArrayRef<T1>> TransitionArgs,Optional<ArrayRef<T2>> DeoptArgs,ArrayRef<T3> GCArgs)604 getStatepointBundles(Optional<ArrayRef<T1>> TransitionArgs,
605 Optional<ArrayRef<T2>> DeoptArgs,
606 ArrayRef<T3> GCArgs) {
607 std::vector<OperandBundleDef> Rval;
608 if (DeoptArgs) {
609 SmallVector<Value*, 16> DeoptValues;
610 DeoptValues.insert(DeoptValues.end(), DeoptArgs->begin(), DeoptArgs->end());
611 Rval.emplace_back("deopt", DeoptValues);
612 }
613 if (TransitionArgs) {
614 SmallVector<Value*, 16> TransitionValues;
615 TransitionValues.insert(TransitionValues.end(),
616 TransitionArgs->begin(), TransitionArgs->end());
617 Rval.emplace_back("gc-transition", TransitionValues);
618 }
619 if (GCArgs.size()) {
620 SmallVector<Value*, 16> LiveValues;
621 LiveValues.insert(LiveValues.end(), GCArgs.begin(), GCArgs.end());
622 Rval.emplace_back("gc-live", LiveValues);
623 }
624 return Rval;
625 }
626
627 template <typename T0, typename T1, typename T2, typename T3>
CreateGCStatepointCallCommon(IRBuilderBase * Builder,uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,uint32_t Flags,ArrayRef<T0> CallArgs,Optional<ArrayRef<T1>> TransitionArgs,Optional<ArrayRef<T2>> DeoptArgs,ArrayRef<T3> GCArgs,const Twine & Name)628 static CallInst *CreateGCStatepointCallCommon(
629 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
630 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
631 Optional<ArrayRef<T1>> TransitionArgs,
632 Optional<ArrayRef<T2>> DeoptArgs, ArrayRef<T3> GCArgs,
633 const Twine &Name) {
634 // Extract out the type of the callee.
635 auto *FuncPtrType = cast<PointerType>(ActualCallee->getType());
636 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
637 "actual callee must be a callable value");
638
639 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
640 // Fill in the one generic type'd argument (the function is also vararg)
641 Type *ArgTypes[] = { FuncPtrType };
642 Function *FnStatepoint =
643 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
644 ArgTypes);
645
646 std::vector<Value *> Args =
647 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
648 CallArgs);
649
650 return Builder->CreateCall(FnStatepoint, Args,
651 getStatepointBundles(TransitionArgs, DeoptArgs,
652 GCArgs),
653 Name);
654 }
655
CreateGCStatepointCall(uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,ArrayRef<Value * > CallArgs,Optional<ArrayRef<Value * >> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)656 CallInst *IRBuilderBase::CreateGCStatepointCall(
657 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
658 ArrayRef<Value *> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs,
659 ArrayRef<Value *> GCArgs, const Twine &Name) {
660 return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
661 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
662 CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
663 }
664
CreateGCStatepointCall(uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,uint32_t Flags,ArrayRef<Value * > CallArgs,Optional<ArrayRef<Use>> TransitionArgs,Optional<ArrayRef<Use>> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)665 CallInst *IRBuilderBase::CreateGCStatepointCall(
666 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
667 ArrayRef<Value *> CallArgs, Optional<ArrayRef<Use>> TransitionArgs,
668 Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs,
669 const Twine &Name) {
670 return CreateGCStatepointCallCommon<Value *, Use, Use, Value *>(
671 this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
672 DeoptArgs, GCArgs, Name);
673 }
674
CreateGCStatepointCall(uint64_t ID,uint32_t NumPatchBytes,Value * ActualCallee,ArrayRef<Use> CallArgs,Optional<ArrayRef<Value * >> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)675 CallInst *IRBuilderBase::CreateGCStatepointCall(
676 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
677 ArrayRef<Use> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs,
678 ArrayRef<Value *> GCArgs, const Twine &Name) {
679 return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
680 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
681 CallArgs, None, DeoptArgs, GCArgs, Name);
682 }
683
684 template <typename T0, typename T1, typename T2, typename T3>
CreateGCStatepointInvokeCommon(IRBuilderBase * Builder,uint64_t ID,uint32_t NumPatchBytes,Value * 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)685 static InvokeInst *CreateGCStatepointInvokeCommon(
686 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
687 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
688 uint32_t Flags, ArrayRef<T0> InvokeArgs,
689 Optional<ArrayRef<T1>> TransitionArgs, Optional<ArrayRef<T2>> DeoptArgs,
690 ArrayRef<T3> GCArgs, const Twine &Name) {
691 // Extract out the type of the callee.
692 auto *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
693 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
694 "actual callee must be a callable value");
695
696 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
697 // Fill in the one generic type'd argument (the function is also vararg)
698 Function *FnStatepoint = Intrinsic::getDeclaration(
699 M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
700
701 std::vector<Value *> Args =
702 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
703 InvokeArgs);
704
705 return Builder->CreateInvoke(FnStatepoint, NormalDest, UnwindDest, Args,
706 getStatepointBundles(TransitionArgs, DeoptArgs,
707 GCArgs),
708 Name);
709 }
710
CreateGCStatepointInvoke(uint64_t ID,uint32_t NumPatchBytes,Value * ActualInvokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,ArrayRef<Value * > InvokeArgs,Optional<ArrayRef<Value * >> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)711 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
712 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
713 BasicBlock *NormalDest, BasicBlock *UnwindDest,
714 ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Value *>> DeoptArgs,
715 ArrayRef<Value *> GCArgs, const Twine &Name) {
716 return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
717 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
718 uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
719 DeoptArgs, GCArgs, Name);
720 }
721
CreateGCStatepointInvoke(uint64_t ID,uint32_t NumPatchBytes,Value * ActualInvokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,uint32_t Flags,ArrayRef<Value * > InvokeArgs,Optional<ArrayRef<Use>> TransitionArgs,Optional<ArrayRef<Use>> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)722 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
723 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
724 BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
725 ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
726 Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
727 return CreateGCStatepointInvokeCommon<Value *, Use, Use, Value *>(
728 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
729 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
730 }
731
CreateGCStatepointInvoke(uint64_t ID,uint32_t NumPatchBytes,Value * ActualInvokee,BasicBlock * NormalDest,BasicBlock * UnwindDest,ArrayRef<Use> InvokeArgs,Optional<ArrayRef<Value * >> DeoptArgs,ArrayRef<Value * > GCArgs,const Twine & Name)732 InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
733 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
734 BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
735 Optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
736 return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
737 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
738 uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
739 Name);
740 }
741
CreateGCResult(Instruction * Statepoint,Type * ResultType,const Twine & Name)742 CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
743 Type *ResultType,
744 const Twine &Name) {
745 Intrinsic::ID ID = Intrinsic::experimental_gc_result;
746 Module *M = BB->getParent()->getParent();
747 Type *Types[] = {ResultType};
748 Function *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
749
750 Value *Args[] = {Statepoint};
751 return createCallHelper(FnGCResult, Args, this, Name);
752 }
753
CreateGCRelocate(Instruction * Statepoint,int BaseOffset,int DerivedOffset,Type * ResultType,const Twine & Name)754 CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
755 int BaseOffset,
756 int DerivedOffset,
757 Type *ResultType,
758 const Twine &Name) {
759 Module *M = BB->getParent()->getParent();
760 Type *Types[] = {ResultType};
761 Function *FnGCRelocate =
762 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
763
764 Value *Args[] = {Statepoint,
765 getInt32(BaseOffset),
766 getInt32(DerivedOffset)};
767 return createCallHelper(FnGCRelocate, Args, this, Name);
768 }
769
CreateUnaryIntrinsic(Intrinsic::ID ID,Value * V,Instruction * FMFSource,const Twine & Name)770 CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
771 Instruction *FMFSource,
772 const Twine &Name) {
773 Module *M = BB->getModule();
774 Function *Fn = Intrinsic::getDeclaration(M, ID, {V->getType()});
775 return createCallHelper(Fn, {V}, this, Name, FMFSource);
776 }
777
CreateBinaryIntrinsic(Intrinsic::ID ID,Value * LHS,Value * RHS,Instruction * FMFSource,const Twine & Name)778 CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
779 Value *RHS,
780 Instruction *FMFSource,
781 const Twine &Name) {
782 Module *M = BB->getModule();
783 Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
784 return createCallHelper(Fn, {LHS, RHS}, this, Name, FMFSource);
785 }
786
CreateIntrinsic(Intrinsic::ID ID,ArrayRef<Type * > Types,ArrayRef<Value * > Args,Instruction * FMFSource,const Twine & Name)787 CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
788 ArrayRef<Type *> Types,
789 ArrayRef<Value *> Args,
790 Instruction *FMFSource,
791 const Twine &Name) {
792 Module *M = BB->getModule();
793 Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
794 return createCallHelper(Fn, Args, this, Name, FMFSource);
795 }
796
CreateConstrainedFPBinOp(Intrinsic::ID ID,Value * L,Value * R,Instruction * FMFSource,const Twine & Name,MDNode * FPMathTag,Optional<RoundingMode> Rounding,Optional<fp::ExceptionBehavior> Except)797 CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
798 Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
799 const Twine &Name, MDNode *FPMathTag,
800 Optional<RoundingMode> Rounding,
801 Optional<fp::ExceptionBehavior> Except) {
802 Value *RoundingV = getConstrainedFPRounding(Rounding);
803 Value *ExceptV = getConstrainedFPExcept(Except);
804
805 FastMathFlags UseFMF = FMF;
806 if (FMFSource)
807 UseFMF = FMFSource->getFastMathFlags();
808
809 CallInst *C = CreateIntrinsic(ID, {L->getType()},
810 {L, R, RoundingV, ExceptV}, nullptr, Name);
811 setConstrainedFPCallAttr(C);
812 setFPAttrs(C, FPMathTag, UseFMF);
813 return C;
814 }
815
CreateNAryOp(unsigned Opc,ArrayRef<Value * > Ops,const Twine & Name,MDNode * FPMathTag)816 Value *IRBuilderBase::CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops,
817 const Twine &Name, MDNode *FPMathTag) {
818 if (Instruction::isBinaryOp(Opc)) {
819 assert(Ops.size() == 2 && "Invalid number of operands!");
820 return CreateBinOp(static_cast<Instruction::BinaryOps>(Opc),
821 Ops[0], Ops[1], Name, FPMathTag);
822 }
823 if (Instruction::isUnaryOp(Opc)) {
824 assert(Ops.size() == 1 && "Invalid number of operands!");
825 return CreateUnOp(static_cast<Instruction::UnaryOps>(Opc),
826 Ops[0], Name, FPMathTag);
827 }
828 llvm_unreachable("Unexpected opcode!");
829 }
830
CreateConstrainedFPCast(Intrinsic::ID ID,Value * V,Type * DestTy,Instruction * FMFSource,const Twine & Name,MDNode * FPMathTag,Optional<RoundingMode> Rounding,Optional<fp::ExceptionBehavior> Except)831 CallInst *IRBuilderBase::CreateConstrainedFPCast(
832 Intrinsic::ID ID, Value *V, Type *DestTy,
833 Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag,
834 Optional<RoundingMode> Rounding,
835 Optional<fp::ExceptionBehavior> Except) {
836 Value *ExceptV = getConstrainedFPExcept(Except);
837
838 FastMathFlags UseFMF = FMF;
839 if (FMFSource)
840 UseFMF = FMFSource->getFastMathFlags();
841
842 CallInst *C;
843 bool HasRoundingMD = false;
844 switch (ID) {
845 default:
846 break;
847 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
848 case Intrinsic::INTRINSIC: \
849 HasRoundingMD = ROUND_MODE; \
850 break;
851 #include "llvm/IR/ConstrainedOps.def"
852 }
853 if (HasRoundingMD) {
854 Value *RoundingV = getConstrainedFPRounding(Rounding);
855 C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV},
856 nullptr, Name);
857 } else
858 C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr,
859 Name);
860
861 setConstrainedFPCallAttr(C);
862
863 if (isa<FPMathOperator>(C))
864 setFPAttrs(C, FPMathTag, UseFMF);
865 return C;
866 }
867
CreateFCmpHelper(CmpInst::Predicate P,Value * LHS,Value * RHS,const Twine & Name,MDNode * FPMathTag,bool IsSignaling)868 Value *IRBuilderBase::CreateFCmpHelper(
869 CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name,
870 MDNode *FPMathTag, bool IsSignaling) {
871 if (IsFPConstrained) {
872 auto ID = IsSignaling ? Intrinsic::experimental_constrained_fcmps
873 : Intrinsic::experimental_constrained_fcmp;
874 return CreateConstrainedFPCmp(ID, P, LHS, RHS, Name);
875 }
876
877 if (auto *LC = dyn_cast<Constant>(LHS))
878 if (auto *RC = dyn_cast<Constant>(RHS))
879 return Insert(Folder.CreateFCmp(P, LC, RC), Name);
880 return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name);
881 }
882
CreateConstrainedFPCmp(Intrinsic::ID ID,CmpInst::Predicate P,Value * L,Value * R,const Twine & Name,Optional<fp::ExceptionBehavior> Except)883 CallInst *IRBuilderBase::CreateConstrainedFPCmp(
884 Intrinsic::ID ID, CmpInst::Predicate P, Value *L, Value *R,
885 const Twine &Name, Optional<fp::ExceptionBehavior> Except) {
886 Value *PredicateV = getConstrainedFPPredicate(P);
887 Value *ExceptV = getConstrainedFPExcept(Except);
888
889 CallInst *C = CreateIntrinsic(ID, {L->getType()},
890 {L, R, PredicateV, ExceptV}, nullptr, Name);
891 setConstrainedFPCallAttr(C);
892 return C;
893 }
894
CreateConstrainedFPCall(Function * Callee,ArrayRef<Value * > Args,const Twine & Name,Optional<RoundingMode> Rounding,Optional<fp::ExceptionBehavior> Except)895 CallInst *IRBuilderBase::CreateConstrainedFPCall(
896 Function *Callee, ArrayRef<Value *> Args, const Twine &Name,
897 Optional<RoundingMode> Rounding,
898 Optional<fp::ExceptionBehavior> Except) {
899 llvm::SmallVector<Value *, 6> UseArgs;
900
901 for (auto *OneArg : Args)
902 UseArgs.push_back(OneArg);
903 bool HasRoundingMD = false;
904 switch (Callee->getIntrinsicID()) {
905 default:
906 break;
907 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
908 case Intrinsic::INTRINSIC: \
909 HasRoundingMD = ROUND_MODE; \
910 break;
911 #include "llvm/IR/ConstrainedOps.def"
912 }
913 if (HasRoundingMD)
914 UseArgs.push_back(getConstrainedFPRounding(Rounding));
915 UseArgs.push_back(getConstrainedFPExcept(Except));
916
917 CallInst *C = CreateCall(Callee, UseArgs, Name);
918 setConstrainedFPCallAttr(C);
919 return C;
920 }
921
CreateSelect(Value * C,Value * True,Value * False,const Twine & Name,Instruction * MDFrom)922 Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False,
923 const Twine &Name, Instruction *MDFrom) {
924 if (auto *CC = dyn_cast<Constant>(C))
925 if (auto *TC = dyn_cast<Constant>(True))
926 if (auto *FC = dyn_cast<Constant>(False))
927 return Insert(Folder.CreateSelect(CC, TC, FC), Name);
928
929 SelectInst *Sel = SelectInst::Create(C, True, False);
930 if (MDFrom) {
931 MDNode *Prof = MDFrom->getMetadata(LLVMContext::MD_prof);
932 MDNode *Unpred = MDFrom->getMetadata(LLVMContext::MD_unpredictable);
933 Sel = addBranchMetadata(Sel, Prof, Unpred);
934 }
935 if (isa<FPMathOperator>(Sel))
936 setFPAttrs(Sel, nullptr /* MDNode* */, FMF);
937 return Insert(Sel, Name);
938 }
939
CreatePtrDiff(Value * LHS,Value * RHS,const Twine & Name)940 Value *IRBuilderBase::CreatePtrDiff(Value *LHS, Value *RHS,
941 const Twine &Name) {
942 assert(LHS->getType() == RHS->getType() &&
943 "Pointer subtraction operand types must match!");
944 auto *ArgType = cast<PointerType>(LHS->getType());
945 Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
946 Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
947 Value *Difference = CreateSub(LHS_int, RHS_int);
948 return CreateExactSDiv(Difference,
949 ConstantExpr::getSizeOf(ArgType->getElementType()),
950 Name);
951 }
952
CreateLaunderInvariantGroup(Value * Ptr)953 Value *IRBuilderBase::CreateLaunderInvariantGroup(Value *Ptr) {
954 assert(isa<PointerType>(Ptr->getType()) &&
955 "launder.invariant.group only applies to pointers.");
956 // FIXME: we could potentially avoid casts to/from i8*.
957 auto *PtrType = Ptr->getType();
958 auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
959 if (PtrType != Int8PtrTy)
960 Ptr = CreateBitCast(Ptr, Int8PtrTy);
961 Module *M = BB->getParent()->getParent();
962 Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration(
963 M, Intrinsic::launder_invariant_group, {Int8PtrTy});
964
965 assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy &&
966 FnLaunderInvariantGroup->getFunctionType()->getParamType(0) ==
967 Int8PtrTy &&
968 "LaunderInvariantGroup should take and return the same type");
969
970 CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr});
971
972 if (PtrType != Int8PtrTy)
973 return CreateBitCast(Fn, PtrType);
974 return Fn;
975 }
976
CreateStripInvariantGroup(Value * Ptr)977 Value *IRBuilderBase::CreateStripInvariantGroup(Value *Ptr) {
978 assert(isa<PointerType>(Ptr->getType()) &&
979 "strip.invariant.group only applies to pointers.");
980
981 // FIXME: we could potentially avoid casts to/from i8*.
982 auto *PtrType = Ptr->getType();
983 auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
984 if (PtrType != Int8PtrTy)
985 Ptr = CreateBitCast(Ptr, Int8PtrTy);
986 Module *M = BB->getParent()->getParent();
987 Function *FnStripInvariantGroup = Intrinsic::getDeclaration(
988 M, Intrinsic::strip_invariant_group, {Int8PtrTy});
989
990 assert(FnStripInvariantGroup->getReturnType() == Int8PtrTy &&
991 FnStripInvariantGroup->getFunctionType()->getParamType(0) ==
992 Int8PtrTy &&
993 "StripInvariantGroup should take and return the same type");
994
995 CallInst *Fn = CreateCall(FnStripInvariantGroup, {Ptr});
996
997 if (PtrType != Int8PtrTy)
998 return CreateBitCast(Fn, PtrType);
999 return Fn;
1000 }
1001
CreateVectorSplat(unsigned NumElts,Value * V,const Twine & Name)1002 Value *IRBuilderBase::CreateVectorSplat(unsigned NumElts, Value *V,
1003 const Twine &Name) {
1004 auto EC = ElementCount::getFixed(NumElts);
1005 return CreateVectorSplat(EC, V, Name);
1006 }
1007
CreateVectorSplat(ElementCount EC,Value * V,const Twine & Name)1008 Value *IRBuilderBase::CreateVectorSplat(ElementCount EC, Value *V,
1009 const Twine &Name) {
1010 assert(EC.isNonZero() && "Cannot splat to an empty vector!");
1011
1012 // First insert it into an undef vector so we can shuffle it.
1013 Type *I32Ty = getInt32Ty();
1014 Value *Undef = UndefValue::get(VectorType::get(V->getType(), EC));
1015 V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0),
1016 Name + ".splatinsert");
1017
1018 // Shuffle the value across the desired number of elements.
1019 Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, EC));
1020 return CreateShuffleVector(V, Undef, Zeros, Name + ".splat");
1021 }
1022
CreateExtractInteger(const DataLayout & DL,Value * From,IntegerType * ExtractedTy,uint64_t Offset,const Twine & Name)1023 Value *IRBuilderBase::CreateExtractInteger(
1024 const DataLayout &DL, Value *From, IntegerType *ExtractedTy,
1025 uint64_t Offset, const Twine &Name) {
1026 auto *IntTy = cast<IntegerType>(From->getType());
1027 assert(DL.getTypeStoreSize(ExtractedTy) + Offset <=
1028 DL.getTypeStoreSize(IntTy) &&
1029 "Element extends past full value");
1030 uint64_t ShAmt = 8 * Offset;
1031 Value *V = From;
1032 if (DL.isBigEndian())
1033 ShAmt = 8 * (DL.getTypeStoreSize(IntTy) -
1034 DL.getTypeStoreSize(ExtractedTy) - Offset);
1035 if (ShAmt) {
1036 V = CreateLShr(V, ShAmt, Name + ".shift");
1037 }
1038 assert(ExtractedTy->getBitWidth() <= IntTy->getBitWidth() &&
1039 "Cannot extract to a larger integer!");
1040 if (ExtractedTy != IntTy) {
1041 V = CreateTrunc(V, ExtractedTy, Name + ".trunc");
1042 }
1043 return V;
1044 }
1045
CreatePreserveArrayAccessIndex(Type * ElTy,Value * Base,unsigned Dimension,unsigned LastIndex,MDNode * DbgInfo)1046 Value *IRBuilderBase::CreatePreserveArrayAccessIndex(
1047 Type *ElTy, Value *Base, unsigned Dimension, unsigned LastIndex,
1048 MDNode *DbgInfo) {
1049 assert(isa<PointerType>(Base->getType()) &&
1050 "Invalid Base ptr type for preserve.array.access.index.");
1051 auto *BaseType = Base->getType();
1052
1053 Value *LastIndexV = getInt32(LastIndex);
1054 Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
1055 SmallVector<Value *, 4> IdxList;
1056 for (unsigned I = 0; I < Dimension; ++I)
1057 IdxList.push_back(Zero);
1058 IdxList.push_back(LastIndexV);
1059
1060 Type *ResultType =
1061 GetElementPtrInst::getGEPReturnType(ElTy, Base, IdxList);
1062
1063 Module *M = BB->getParent()->getParent();
1064 Function *FnPreserveArrayAccessIndex = Intrinsic::getDeclaration(
1065 M, Intrinsic::preserve_array_access_index, {ResultType, BaseType});
1066
1067 Value *DimV = getInt32(Dimension);
1068 CallInst *Fn =
1069 CreateCall(FnPreserveArrayAccessIndex, {Base, DimV, LastIndexV});
1070 if (DbgInfo)
1071 Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
1072
1073 return Fn;
1074 }
1075
CreatePreserveUnionAccessIndex(Value * Base,unsigned FieldIndex,MDNode * DbgInfo)1076 Value *IRBuilderBase::CreatePreserveUnionAccessIndex(
1077 Value *Base, unsigned FieldIndex, MDNode *DbgInfo) {
1078 assert(isa<PointerType>(Base->getType()) &&
1079 "Invalid Base ptr type for preserve.union.access.index.");
1080 auto *BaseType = Base->getType();
1081
1082 Module *M = BB->getParent()->getParent();
1083 Function *FnPreserveUnionAccessIndex = Intrinsic::getDeclaration(
1084 M, Intrinsic::preserve_union_access_index, {BaseType, BaseType});
1085
1086 Value *DIIndex = getInt32(FieldIndex);
1087 CallInst *Fn =
1088 CreateCall(FnPreserveUnionAccessIndex, {Base, DIIndex});
1089 if (DbgInfo)
1090 Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
1091
1092 return Fn;
1093 }
1094
CreatePreserveStructAccessIndex(Type * ElTy,Value * Base,unsigned Index,unsigned FieldIndex,MDNode * DbgInfo)1095 Value *IRBuilderBase::CreatePreserveStructAccessIndex(
1096 Type *ElTy, Value *Base, unsigned Index, unsigned FieldIndex,
1097 MDNode *DbgInfo) {
1098 assert(isa<PointerType>(Base->getType()) &&
1099 "Invalid Base ptr type for preserve.struct.access.index.");
1100 auto *BaseType = Base->getType();
1101
1102 Value *GEPIndex = getInt32(Index);
1103 Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
1104 Type *ResultType =
1105 GetElementPtrInst::getGEPReturnType(ElTy, Base, {Zero, GEPIndex});
1106
1107 Module *M = BB->getParent()->getParent();
1108 Function *FnPreserveStructAccessIndex = Intrinsic::getDeclaration(
1109 M, Intrinsic::preserve_struct_access_index, {ResultType, BaseType});
1110
1111 Value *DIIndex = getInt32(FieldIndex);
1112 CallInst *Fn = CreateCall(FnPreserveStructAccessIndex,
1113 {Base, GEPIndex, DIIndex});
1114 if (DbgInfo)
1115 Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
1116
1117 return Fn;
1118 }
1119
CreateAlignmentAssumptionHelper(const DataLayout & DL,Value * PtrValue,Value * AlignValue,Value * OffsetValue)1120 CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(const DataLayout &DL,
1121 Value *PtrValue,
1122 Value *AlignValue,
1123 Value *OffsetValue) {
1124 SmallVector<Value *, 4> Vals({PtrValue, AlignValue});
1125 if (OffsetValue)
1126 Vals.push_back(OffsetValue);
1127 OperandBundleDefT<Value *> AlignOpB("align", Vals);
1128 return CreateAssumption(ConstantInt::getTrue(getContext()), {AlignOpB});
1129 }
1130
CreateAlignmentAssumption(const DataLayout & DL,Value * PtrValue,unsigned Alignment,Value * OffsetValue)1131 CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
1132 Value *PtrValue,
1133 unsigned Alignment,
1134 Value *OffsetValue) {
1135 assert(isa<PointerType>(PtrValue->getType()) &&
1136 "trying to create an alignment assumption on a non-pointer?");
1137 assert(Alignment != 0 && "Invalid Alignment");
1138 auto *PtrTy = cast<PointerType>(PtrValue->getType());
1139 Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
1140 Value *AlignValue = ConstantInt::get(IntPtrTy, Alignment);
1141 return CreateAlignmentAssumptionHelper(DL, PtrValue, AlignValue, OffsetValue);
1142 }
1143
CreateAlignmentAssumption(const DataLayout & DL,Value * PtrValue,Value * Alignment,Value * OffsetValue)1144 CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
1145 Value *PtrValue,
1146 Value *Alignment,
1147 Value *OffsetValue) {
1148 assert(isa<PointerType>(PtrValue->getType()) &&
1149 "trying to create an alignment assumption on a non-pointer?");
1150 return CreateAlignmentAssumptionHelper(DL, PtrValue, Alignment, OffsetValue);
1151 }
1152
~IRBuilderDefaultInserter()1153 IRBuilderDefaultInserter::~IRBuilderDefaultInserter() {}
~IRBuilderCallbackInserter()1154 IRBuilderCallbackInserter::~IRBuilderCallbackInserter() {}
~IRBuilderFolder()1155 IRBuilderFolder::~IRBuilderFolder() {}
anchor()1156 void ConstantFolder::anchor() {}
anchor()1157 void NoFolder::anchor() {}
1158