blob: febfe189df6ea7204eb56c2aa55d1a3ea3ef065d [file] [log] [blame]
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001//===- IRBuilder.cpp - Builder for LLVM Instrs ----------------------------===//
Chris Lattner17079fc2009-12-28 21:28:46 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner17079fc2009-12-28 21:28:46 +00006//
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
Chandler Carruth6bda14b2017-06-06 11:49:48 +000014#include "llvm/IR/IRBuilder.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000015#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"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000020#include "llvm/IR/Function.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000021#include "llvm/IR/GlobalValue.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000022#include "llvm/IR/GlobalVariable.h"
Daniel Neilson1e687242018-01-19 17:13:12 +000023#include "llvm/IR/IntrinsicInst.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000024#include "llvm/IR/Intrinsics.h"
25#include "llvm/IR/LLVMContext.h"
Nikita Popov3eaa53e2020-02-16 17:10:09 +010026#include "llvm/IR/NoFolder.h"
Simon Pilgrimc941b642020-06-25 12:48:14 +010027#include "llvm/IR/Operator.h"
Pat Gavlincc0431d2015-05-08 18:07:42 +000028#include "llvm/IR/Statepoint.h"
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000029#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
Chris Lattner17079fc2009-12-28 21:28:46 +000037using namespace llvm;
38
39/// CreateGlobalString - Make a new global variable with an initializer that
Dan Gohman97c59022010-02-10 20:04:19 +000040/// has array of i8 type filled in with the nul terminated string value
Chris Lattner17079fc2009-12-28 21:28:46 +000041/// specified. If Name is specified, it is the name of the global variable
42/// created.
David Blaikieaa41cd52015-04-03 21:33:42 +000043GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
Tobias Grossercdb89142015-06-19 02:12:07 +000044 const Twine &Name,
Johannes Doerfertfa5d22a2020-05-28 09:41:01 -050045 unsigned AddressSpace,
46 Module *M) {
Chris Lattnercf9e8f62012-02-05 02:29:43 +000047 Constant *StrConstant = ConstantDataArray::getString(Context, Str);
Johannes Doerfertfa5d22a2020-05-28 09:41:01 -050048 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);
Peter Collingbourne96efdd62016-06-14 21:01:22 +000053 GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
Guillaume Chatelet805c1572020-01-21 15:00:04 +010054 GV->setAlignment(Align(1));
Chris Lattner17079fc2009-12-28 21:28:46 +000055 return GV;
56}
Chris Lattner7ef1cac2009-12-28 21:45:40 +000057
Chris Lattnerb1907b22011-07-12 04:14:22 +000058Type *IRBuilderBase::getCurrentFunctionReturnType() const {
Chris Lattner49f9f762009-12-28 21:50:56 +000059 assert(BB && BB->getParent() && "No current function!");
60 return BB->getParent()->getReturnType();
61}
Chris Lattner143a07c2010-12-26 22:49:25 +000062
63Value *IRBuilderBase::getCastedInt8PtrValue(Value *Ptr) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +000064 auto *PT = cast<PointerType>(Ptr->getType());
Chris Lattner143a07c2010-12-26 22:49:25 +000065 if (PT->getElementType()->isIntegerTy(8))
66 return Ptr;
Bjorn Petterssonaa025802018-07-03 12:39:52 +000067
Chris Lattner143a07c2010-12-26 22:49:25 +000068 // Otherwise, we need to insert a bitcast.
Nikita Popovf6875c42020-02-18 20:35:16 +010069 return CreateBitCast(Ptr, getInt8PtrTy(PT->getAddressSpace()));
Chris Lattner143a07c2010-12-26 22:49:25 +000070}
71
James Y Knight7976eb52019-02-01 20:43:25 +000072static CallInst *createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
Philip Reames4750dd12014-12-30 05:55:58 +000073 IRBuilderBase *Builder,
Sanjay Pateld32104e2018-02-23 21:16:12 +000074 const Twine &Name = "",
Tyker78de7292020-09-12 13:36:45 +020075 Instruction *FMFSource = nullptr,
76 ArrayRef<OperandBundleDef> OpBundles = {}) {
77 CallInst *CI = Builder->CreateCall(Callee, Ops, OpBundles, Name);
Sanjay Pateld32104e2018-02-23 21:16:12 +000078 if (FMFSource)
79 CI->copyFastMathFlags(FMFSource);
Bjorn Petterssonaa025802018-07-03 12:39:52 +000080 return CI;
Chris Lattner143a07c2010-12-26 22:49:25 +000081}
82
Guillaume Chatelet1b2842b2019-12-09 17:36:50 +010083CallInst *IRBuilderBase::CreateMemSet(Value *Ptr, Value *Val, Value *Size,
84 MaybeAlign Align, bool isVolatile,
85 MDNode *TBAATag, MDNode *ScopeTag,
86 MDNode *NoAliasTag) {
Chris Lattner143a07c2010-12-26 22:49:25 +000087 Ptr = getCastedInt8PtrValue(Ptr);
Daniel Neilson1e687242018-01-19 17:13:12 +000088 Value *Ops[] = {Ptr, Val, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +000089 Type *Tys[] = { Ptr->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +000090 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +000091 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
Bjorn Petterssonaa025802018-07-03 12:39:52 +000092
Jay Foad5bd375a2011-07-15 08:37:34 +000093 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +000094
Guillaume Chatelet1b2842b2019-12-09 17:36:50 +010095 if (Align)
96 cast<MemSetInst>(CI)->setDestAlignment(Align->value());
Daniel Neilson1e687242018-01-19 17:13:12 +000097
Chris Lattner143a07c2010-12-26 22:49:25 +000098 // Set the TBAA info if present.
99 if (TBAATag)
100 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Hal Finkel94146652014-07-24 14:25:39 +0000101
102 if (ScopeTag)
103 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000104
Hal Finkel94146652014-07-24 14:25:39 +0000105 if (NoAliasTag)
106 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
Daniel Neilson1e687242018-01-19 17:13:12 +0000107
Chris Lattner143a07c2010-12-26 22:49:25 +0000108 return CI;
109}
110
Daniel Neilson936d50a2018-05-30 20:02:56 +0000111CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemSet(
Guillaume Chateletb4982d62019-12-19 15:41:05 +0100112 Value *Ptr, Value *Val, Value *Size, Align Alignment, uint32_t ElementSize,
Daniel Neilson936d50a2018-05-30 20:02:56 +0000113 MDNode *TBAATag, MDNode *ScopeTag, MDNode *NoAliasTag) {
Daniel Neilson936d50a2018-05-30 20:02:56 +0000114
115 Ptr = getCastedInt8PtrValue(Ptr);
116 Value *Ops[] = {Ptr, Val, Size, getInt32(ElementSize)};
117 Type *Tys[] = {Ptr->getType(), Size->getType()};
118 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000119 Function *TheFn = Intrinsic::getDeclaration(
Daniel Neilson936d50a2018-05-30 20:02:56 +0000120 M, Intrinsic::memset_element_unordered_atomic, Tys);
121
122 CallInst *CI = createCallHelper(TheFn, Ops, this);
123
Guillaume Chateletb4982d62019-12-19 15:41:05 +0100124 cast<AtomicMemSetInst>(CI)->setDestAlignment(Alignment);
Daniel Neilson936d50a2018-05-30 20:02:56 +0000125
126 // Set the TBAA info if present.
127 if (TBAATag)
128 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
129
130 if (ScopeTag)
131 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
132
133 if (NoAliasTag)
134 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
135
136 return CI;
137}
138
Guillaume Chateletdbc5acf2019-12-12 15:32:19 +0100139CallInst *IRBuilderBase::CreateMemCpy(Value *Dst, MaybeAlign DstAlign,
140 Value *Src, MaybeAlign SrcAlign,
141 Value *Size, bool isVolatile,
142 MDNode *TBAATag, MDNode *TBAAStructTag,
143 MDNode *ScopeTag, MDNode *NoAliasTag) {
Chris Lattner143a07c2010-12-26 22:49:25 +0000144 Dst = getCastedInt8PtrValue(Dst);
145 Src = getCastedInt8PtrValue(Src);
146
Daniel Neilson1e687242018-01-19 17:13:12 +0000147 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +0000148 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +0000149 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000150 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000151
Jay Foad5bd375a2011-07-15 08:37:34 +0000152 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +0000153
Daniel Neilson551a4d62018-01-27 17:59:10 +0000154 auto* MCI = cast<MemCpyInst>(CI);
Guillaume Chateletdbc5acf2019-12-12 15:32:19 +0100155 if (DstAlign)
156 MCI->setDestAlignment(*DstAlign);
157 if (SrcAlign)
158 MCI->setSourceAlignment(*SrcAlign);
Daniel Neilson1e687242018-01-19 17:13:12 +0000159
Chris Lattner143a07c2010-12-26 22:49:25 +0000160 // Set the TBAA info if present.
161 if (TBAATag)
162 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Dan Gohman099727f2012-09-26 22:17:14 +0000163
164 // Set the TBAA Struct info if present.
165 if (TBAAStructTag)
166 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000167
Hal Finkel94146652014-07-24 14:25:39 +0000168 if (ScopeTag)
169 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000170
Hal Finkel94146652014-07-24 14:25:39 +0000171 if (NoAliasTag)
172 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
Daniel Neilson1e687242018-01-19 17:13:12 +0000173
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000174 return CI;
Chris Lattner143a07c2010-12-26 22:49:25 +0000175}
176
Guillaume Chateletd65bbf82020-01-28 13:01:19 +0100177CallInst *IRBuilderBase::CreateMemCpyInline(Value *Dst, MaybeAlign DstAlign,
178 Value *Src, MaybeAlign SrcAlign,
179 Value *Size) {
180 Dst = getCastedInt8PtrValue(Dst);
181 Src = getCastedInt8PtrValue(Src);
182 Value *IsVolatile = getInt1(false);
183
184 Value *Ops[] = {Dst, Src, Size, IsVolatile};
185 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
186 Function *F = BB->getParent();
187 Module *M = F->getParent();
188 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memcpy_inline, Tys);
189
190 CallInst *CI = createCallHelper(TheFn, Ops, this);
191
192 auto *MCI = cast<MemCpyInlineInst>(CI);
193 if (DstAlign)
194 MCI->setDestAlignment(*DstAlign);
195 if (SrcAlign)
196 MCI->setSourceAlignment(*SrcAlign);
197
198 return CI;
199}
200
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000201CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
Guillaume Chatelet46b95632020-01-20 14:47:28 +0100202 Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size,
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000203 uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
204 MDNode *ScopeTag, MDNode *NoAliasTag) {
205 assert(DstAlign >= ElementSize &&
206 "Pointer alignment must be at least element size");
207 assert(SrcAlign >= ElementSize &&
208 "Pointer alignment must be at least element size");
Anna Thomasb2a212c2017-06-06 16:45:25 +0000209 Dst = getCastedInt8PtrValue(Dst);
210 Src = getCastedInt8PtrValue(Src);
211
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000212 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
213 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
Anna Thomasb2a212c2017-06-06 16:45:25 +0000214 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000215 Function *TheFn = Intrinsic::getDeclaration(
Daniel Neilson3faabbb2017-06-16 14:43:59 +0000216 M, Intrinsic::memcpy_element_unordered_atomic, Tys);
Anna Thomasb2a212c2017-06-06 16:45:25 +0000217
218 CallInst *CI = createCallHelper(TheFn, Ops, this);
219
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000220 // Set the alignment of the pointer args.
Daniel Neilson1e687242018-01-19 17:13:12 +0000221 auto *AMCI = cast<AtomicMemCpyInst>(CI);
222 AMCI->setDestAlignment(DstAlign);
223 AMCI->setSourceAlignment(SrcAlign);
Daniel Neilson6e4aa1e2017-11-10 19:38:12 +0000224
Anna Thomasb2a212c2017-06-06 16:45:25 +0000225 // Set the TBAA info if present.
226 if (TBAATag)
227 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
228
229 // Set the TBAA Struct info if present.
230 if (TBAAStructTag)
231 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
232
233 if (ScopeTag)
234 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
235
236 if (NoAliasTag)
237 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
238
239 return CI;
240}
241
Guillaume Chateletdbc5acf2019-12-12 15:32:19 +0100242CallInst *IRBuilderBase::CreateMemMove(Value *Dst, MaybeAlign DstAlign,
243 Value *Src, MaybeAlign SrcAlign,
244 Value *Size, bool isVolatile,
245 MDNode *TBAATag, MDNode *ScopeTag,
246 MDNode *NoAliasTag) {
Chris Lattner143a07c2010-12-26 22:49:25 +0000247 Dst = getCastedInt8PtrValue(Dst);
248 Src = getCastedInt8PtrValue(Src);
Daniel Neilson1e687242018-01-19 17:13:12 +0000249
250 Value *Ops[] = {Dst, Src, Size, getInt1(isVolatile)};
Jay Foadb804a2b2011-07-12 14:06:48 +0000251 Type *Tys[] = { Dst->getType(), Src->getType(), Size->getType() };
Chris Lattner143a07c2010-12-26 22:49:25 +0000252 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000253 Function *TheFn = Intrinsic::getDeclaration(M, Intrinsic::memmove, Tys);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000254
Jay Foad5bd375a2011-07-15 08:37:34 +0000255 CallInst *CI = createCallHelper(TheFn, Ops, this);
Daniel Neilson1e687242018-01-19 17:13:12 +0000256
257 auto *MMI = cast<MemMoveInst>(CI);
Guillaume Chateletdbc5acf2019-12-12 15:32:19 +0100258 if (DstAlign)
259 MMI->setDestAlignment(*DstAlign);
260 if (SrcAlign)
261 MMI->setSourceAlignment(*SrcAlign);
Daniel Neilson1e687242018-01-19 17:13:12 +0000262
Chris Lattner143a07c2010-12-26 22:49:25 +0000263 // Set the TBAA info if present.
264 if (TBAATag)
265 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000266
Hal Finkel94146652014-07-24 14:25:39 +0000267 if (ScopeTag)
268 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000269
Hal Finkel94146652014-07-24 14:25:39 +0000270 if (NoAliasTag)
271 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
Bjorn Petterssonaa025802018-07-03 12:39:52 +0000272
273 return CI;
Chris Lattner143a07c2010-12-26 22:49:25 +0000274}
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000275
Daniel Neilson936d50a2018-05-30 20:02:56 +0000276CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove(
Guillaume Chatelet139771f2020-01-20 17:11:00 +0100277 Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size,
Daniel Neilson936d50a2018-05-30 20:02:56 +0000278 uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,
279 MDNode *ScopeTag, MDNode *NoAliasTag) {
280 assert(DstAlign >= ElementSize &&
281 "Pointer alignment must be at least element size");
282 assert(SrcAlign >= ElementSize &&
283 "Pointer alignment must be at least element size");
284 Dst = getCastedInt8PtrValue(Dst);
285 Src = getCastedInt8PtrValue(Src);
286
287 Value *Ops[] = {Dst, Src, Size, getInt32(ElementSize)};
288 Type *Tys[] = {Dst->getType(), Src->getType(), Size->getType()};
289 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000290 Function *TheFn = Intrinsic::getDeclaration(
Daniel Neilson936d50a2018-05-30 20:02:56 +0000291 M, Intrinsic::memmove_element_unordered_atomic, Tys);
292
293 CallInst *CI = createCallHelper(TheFn, Ops, this);
294
295 // Set the alignment of the pointer args.
Guillaume Chatelet139771f2020-01-20 17:11:00 +0100296 CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), DstAlign));
297 CI->addParamAttr(1, Attribute::getWithAlignment(CI->getContext(), SrcAlign));
Daniel Neilson936d50a2018-05-30 20:02:56 +0000298
299 // Set the TBAA info if present.
300 if (TBAATag)
301 CI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
302
303 // Set the TBAA Struct info if present.
304 if (TBAAStructTag)
305 CI->setMetadata(LLVMContext::MD_tbaa_struct, TBAAStructTag);
306
307 if (ScopeTag)
308 CI->setMetadata(LLVMContext::MD_alias_scope, ScopeTag);
309
310 if (NoAliasTag)
311 CI->setMetadata(LLVMContext::MD_noalias, NoAliasTag);
312
313 return CI;
314}
315
Amara Emersoncf9daa32017-05-09 10:43:25 +0000316static CallInst *getReductionIntrinsic(IRBuilderBase *Builder, Intrinsic::ID ID,
317 Value *Src) {
318 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
319 Value *Ops[] = {Src};
Sander de Smalen51c2fa02019-06-13 09:37:38 +0000320 Type *Tys[] = { Src->getType() };
Amara Emersoncf9daa32017-05-09 10:43:25 +0000321 auto Decl = Intrinsic::getDeclaration(M, ID, Tys);
322 return createCallHelper(Decl, Ops, Builder);
323}
324
325CallInst *IRBuilderBase::CreateFAddReduce(Value *Acc, Value *Src) {
326 Module *M = GetInsertBlock()->getParent()->getParent();
327 Value *Ops[] = {Acc, Src};
Sander de Smalenf83cccf2019-05-20 09:54:06 +0000328 Type *Tys[] = {Acc->getType(), Src->getType()};
Amara Emersoncf9daa32017-05-09 10:43:25 +0000329 auto Decl = Intrinsic::getDeclaration(
Sander de Smalencbeb5632019-06-11 08:22:10 +0000330 M, Intrinsic::experimental_vector_reduce_v2_fadd, Tys);
Amara Emersoncf9daa32017-05-09 10:43:25 +0000331 return createCallHelper(Decl, Ops, this);
332}
333
334CallInst *IRBuilderBase::CreateFMulReduce(Value *Acc, Value *Src) {
335 Module *M = GetInsertBlock()->getParent()->getParent();
336 Value *Ops[] = {Acc, Src};
Sander de Smalenf83cccf2019-05-20 09:54:06 +0000337 Type *Tys[] = {Acc->getType(), Src->getType()};
Amara Emersoncf9daa32017-05-09 10:43:25 +0000338 auto Decl = Intrinsic::getDeclaration(
Sander de Smalencbeb5632019-06-11 08:22:10 +0000339 M, Intrinsic::experimental_vector_reduce_v2_fmul, Tys);
Amara Emersoncf9daa32017-05-09 10:43:25 +0000340 return createCallHelper(Decl, Ops, this);
341}
342
343CallInst *IRBuilderBase::CreateAddReduce(Value *Src) {
344 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_add,
345 Src);
346}
347
348CallInst *IRBuilderBase::CreateMulReduce(Value *Src) {
349 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_mul,
350 Src);
351}
352
353CallInst *IRBuilderBase::CreateAndReduce(Value *Src) {
354 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_and,
355 Src);
356}
357
358CallInst *IRBuilderBase::CreateOrReduce(Value *Src) {
359 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_or,
360 Src);
361}
362
363CallInst *IRBuilderBase::CreateXorReduce(Value *Src) {
364 return getReductionIntrinsic(this, Intrinsic::experimental_vector_reduce_xor,
365 Src);
366}
367
368CallInst *IRBuilderBase::CreateIntMaxReduce(Value *Src, bool IsSigned) {
369 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smax
370 : Intrinsic::experimental_vector_reduce_umax;
371 return getReductionIntrinsic(this, ID, Src);
372}
373
374CallInst *IRBuilderBase::CreateIntMinReduce(Value *Src, bool IsSigned) {
375 auto ID = IsSigned ? Intrinsic::experimental_vector_reduce_smin
376 : Intrinsic::experimental_vector_reduce_umin;
377 return getReductionIntrinsic(this, ID, Src);
378}
379
380CallInst *IRBuilderBase::CreateFPMaxReduce(Value *Src, bool NoNaN) {
381 auto Rdx = getReductionIntrinsic(
382 this, Intrinsic::experimental_vector_reduce_fmax, Src);
383 if (NoNaN) {
384 FastMathFlags FMF;
385 FMF.setNoNaNs();
386 Rdx->setFastMathFlags(FMF);
387 }
388 return Rdx;
389}
390
391CallInst *IRBuilderBase::CreateFPMinReduce(Value *Src, bool NoNaN) {
392 auto Rdx = getReductionIntrinsic(
393 this, Intrinsic::experimental_vector_reduce_fmin, Src);
394 if (NoNaN) {
395 FastMathFlags FMF;
396 FMF.setNoNaNs();
397 Rdx->setFastMathFlags(FMF);
398 }
399 return Rdx;
400}
401
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000402CallInst *IRBuilderBase::CreateLifetimeStart(Value *Ptr, ConstantInt *Size) {
403 assert(isa<PointerType>(Ptr->getType()) &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000404 "lifetime.start only applies to pointers.");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000405 Ptr = getCastedInt8PtrValue(Ptr);
406 if (!Size)
407 Size = getInt64(-1);
408 else
409 assert(Size->getType() == getInt64Ty() &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000410 "lifetime.start requires the size to be an i64");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000411 Value *Ops[] = { Size, Ptr };
412 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000413 Function *TheFn =
414 Intrinsic::getDeclaration(M, Intrinsic::lifetime_start, {Ptr->getType()});
Jay Foad5bd375a2011-07-15 08:37:34 +0000415 return createCallHelper(TheFn, Ops, this);
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000416}
417
418CallInst *IRBuilderBase::CreateLifetimeEnd(Value *Ptr, ConstantInt *Size) {
419 assert(isa<PointerType>(Ptr->getType()) &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000420 "lifetime.end only applies to pointers.");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000421 Ptr = getCastedInt8PtrValue(Ptr);
422 if (!Size)
423 Size = getInt64(-1);
424 else
425 assert(Size->getType() == getInt64Ty() &&
Bill Wendlingea6397f2012-07-19 00:11:40 +0000426 "lifetime.end requires the size to be an i64");
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000427 Value *Ops[] = { Size, Ptr };
428 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000429 Function *TheFn =
430 Intrinsic::getDeclaration(M, Intrinsic::lifetime_end, {Ptr->getType()});
Jay Foad5bd375a2011-07-15 08:37:34 +0000431 return createCallHelper(TheFn, Ops, this);
Nick Lewyckybabca9a2011-05-21 23:14:36 +0000432}
Hal Finkel6f814db2014-10-15 23:44:22 +0000433
Anna Thomas58d11922016-07-22 20:57:23 +0000434CallInst *IRBuilderBase::CreateInvariantStart(Value *Ptr, ConstantInt *Size) {
435
436 assert(isa<PointerType>(Ptr->getType()) &&
437 "invariant.start only applies to pointers.");
438 Ptr = getCastedInt8PtrValue(Ptr);
439 if (!Size)
440 Size = getInt64(-1);
441 else
442 assert(Size->getType() == getInt64Ty() &&
443 "invariant.start requires the size to be an i64");
444
445 Value *Ops[] = {Size, Ptr};
446 // Fill in the single overloaded type: memory object type.
447 Type *ObjectPtr[1] = {Ptr->getType()};
448 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000449 Function *TheFn =
Anna Thomas58d11922016-07-22 20:57:23 +0000450 Intrinsic::getDeclaration(M, Intrinsic::invariant_start, ObjectPtr);
451 return createCallHelper(TheFn, Ops, this);
452}
453
Tyker78de7292020-09-12 13:36:45 +0200454CallInst *
455IRBuilderBase::CreateAssumption(Value *Cond,
456 ArrayRef<OperandBundleDef> OpBundles) {
Hal Finkel6f814db2014-10-15 23:44:22 +0000457 assert(Cond->getType() == getInt1Ty() &&
458 "an assumption condition must be of type i1");
459
460 Value *Ops[] = { Cond };
461 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000462 Function *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
Tyker78de7292020-09-12 13:36:45 +0200463 return createCallHelper(FnAssume, Ops, this, "", nullptr, OpBundles);
Hal Finkel6f814db2014-10-15 23:44:22 +0000464}
465
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000466/// Create a call to a Masked Load intrinsic.
Guillaume Chateletbc8a1ab2020-01-21 11:21:31 +0100467/// \p Ptr - base pointer for the load
468/// \p Alignment - alignment of the source location
469/// \p Mask - vector of booleans which indicates what vector lanes should
470/// be accessed in memory
471/// \p PassThru - pass-through value that is used to fill the masked-off lanes
472/// of the result
473/// \p Name - name of the result variable
474CallInst *IRBuilderBase::CreateMaskedLoad(Value *Ptr, Align Alignment,
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000475 Value *Mask, Value *PassThru,
476 const Twine &Name) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000477 auto *PtrTy = cast<PointerType>(Ptr->getType());
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000478 Type *DataTy = PtrTy->getElementType();
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000479 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
Ayal Zakse841b212017-07-31 13:21:42 +0000480 assert(Mask && "Mask should not be all-ones (null)");
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000481 if (!PassThru)
482 PassThru = UndefValue::get(DataTy);
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000483 Type *OverloadedTypes[] = { DataTy, PtrTy };
Guillaume Chateletbc8a1ab2020-01-21 11:21:31 +0100484 Value *Ops[] = {Ptr, getInt32(Alignment.value()), Mask, PassThru};
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000485 return CreateMaskedIntrinsic(Intrinsic::masked_load, Ops,
486 OverloadedTypes, Name);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000487}
488
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000489/// Create a call to a Masked Store intrinsic.
Guillaume Chatelet09572332020-01-21 16:13:04 +0100490/// \p Val - data to be stored,
491/// \p Ptr - base pointer for the store
492/// \p Alignment - alignment of the destination location
493/// \p Mask - vector of booleans which indicates what vector lanes should
494/// be accessed in memory
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000495CallInst *IRBuilderBase::CreateMaskedStore(Value *Val, Value *Ptr,
Guillaume Chatelet09572332020-01-21 16:13:04 +0100496 Align Alignment, Value *Mask) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000497 auto *PtrTy = cast<PointerType>(Ptr->getType());
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000498 Type *DataTy = PtrTy->getElementType();
499 assert(DataTy->isVectorTy() && "Ptr should point to a vector");
Ayal Zakse841b212017-07-31 13:21:42 +0000500 assert(Mask && "Mask should not be all-ones (null)");
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000501 Type *OverloadedTypes[] = { DataTy, PtrTy };
Guillaume Chatelet09572332020-01-21 16:13:04 +0100502 Value *Ops[] = {Val, Ptr, getInt32(Alignment.value()), Mask};
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000503 return CreateMaskedIntrinsic(Intrinsic::masked_store, Ops, OverloadedTypes);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000504}
505
506/// Create a call to a Masked intrinsic, with given intrinsic Id,
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000507/// an array of operands - Ops, and an array of overloaded types -
508/// OverloadedTypes.
Pete Cooper9e1d3352015-05-20 17:16:39 +0000509CallInst *IRBuilderBase::CreateMaskedIntrinsic(Intrinsic::ID Id,
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000510 ArrayRef<Value *> Ops,
Artur Pilipenko7ad95ec2016-06-28 18:27:25 +0000511 ArrayRef<Type *> OverloadedTypes,
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000512 const Twine &Name) {
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000513 Module *M = BB->getParent()->getParent();
James Y Knight7976eb52019-02-01 20:43:25 +0000514 Function *TheFn = Intrinsic::getDeclaration(M, Id, OverloadedTypes);
Elena Demikhovsky84d19972014-12-30 14:28:14 +0000515 return createCallHelper(TheFn, Ops, this, Name);
Elena Demikhovskyf1de34b2014-12-04 09:40:44 +0000516}
Philip Reames4750dd12014-12-30 05:55:58 +0000517
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000518/// Create a call to a Masked Gather intrinsic.
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000519/// \p Ptrs - vector of pointers for loading
520/// \p Align - alignment for one element
521/// \p Mask - vector of booleans which indicates what vector lanes should
522/// be accessed in memory
523/// \p PassThru - pass-through value that is used to fill the masked-off lanes
524/// of the result
525/// \p Name - name of the result variable
Guillaume Chateletd0a7cc72020-01-24 17:40:17 +0100526CallInst *IRBuilderBase::CreateMaskedGather(Value *Ptrs, Align Alignment,
527 Value *Mask, Value *PassThru,
528 const Twine &Name) {
Christopher Tetreault5a55e272020-08-27 10:39:18 -0700529 auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
530 auto *PtrTy = cast<PointerType>(PtrsTy->getElementType());
Christopher Tetreault40ed21b2020-04-10 13:59:26 -0700531 unsigned NumElts = PtrsTy->getNumElements();
Christopher Tetreault900f78a2020-06-03 13:35:41 -0700532 auto *DataTy = FixedVectorType::get(PtrTy->getElementType(), NumElts);
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000533
534 if (!Mask)
Christopher Tetreault900f78a2020-06-03 13:35:41 -0700535 Mask = Constant::getAllOnesValue(
536 FixedVectorType::get(Type::getInt1Ty(Context), NumElts));
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000537
Amara Emerson4d33c862017-05-19 10:40:18 +0000538 if (!PassThru)
539 PassThru = UndefValue::get(DataTy);
540
Elad Cohenef5798a2017-05-03 12:28:54 +0000541 Type *OverloadedTypes[] = {DataTy, PtrsTy};
Guillaume Chateletd0a7cc72020-01-24 17:40:17 +0100542 Value *Ops[] = {Ptrs, getInt32(Alignment.value()), Mask, PassThru};
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000543
544 // We specify only one type when we create this intrinsic. Types of other
545 // arguments are derived from this type.
Elad Cohenef5798a2017-05-03 12:28:54 +0000546 return CreateMaskedIntrinsic(Intrinsic::masked_gather, Ops, OverloadedTypes,
547 Name);
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000548}
549
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000550/// Create a call to a Masked Scatter intrinsic.
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000551/// \p Data - data to be stored,
552/// \p Ptrs - the vector of pointers, where the \p Data elements should be
553/// stored
554/// \p Align - alignment for one element
555/// \p Mask - vector of booleans which indicates what vector lanes should
556/// be accessed in memory
557CallInst *IRBuilderBase::CreateMaskedScatter(Value *Data, Value *Ptrs,
Guillaume Chateletd0a7cc72020-01-24 17:40:17 +0100558 Align Alignment, Value *Mask) {
Christopher Tetreault5a55e272020-08-27 10:39:18 -0700559 auto *PtrsTy = cast<FixedVectorType>(Ptrs->getType());
560 auto *DataTy = cast<FixedVectorType>(Data->getType());
Christopher Tetreault40ed21b2020-04-10 13:59:26 -0700561 unsigned NumElts = PtrsTy->getNumElements();
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000562
Tim Northover5a1a56c2016-02-17 21:16:59 +0000563#ifndef NDEBUG
564 auto PtrTy = cast<PointerType>(PtrsTy->getElementType());
Christopher Tetreault40ed21b2020-04-10 13:59:26 -0700565 assert(NumElts == DataTy->getNumElements() &&
Tim Northover5a1a56c2016-02-17 21:16:59 +0000566 PtrTy->getElementType() == DataTy->getElementType() &&
567 "Incompatible pointer and data types");
568#endif
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000569
570 if (!Mask)
Christopher Tetreault900f78a2020-06-03 13:35:41 -0700571 Mask = Constant::getAllOnesValue(
572 FixedVectorType::get(Type::getInt1Ty(Context), NumElts));
Elad Cohenef5798a2017-05-03 12:28:54 +0000573
574 Type *OverloadedTypes[] = {DataTy, PtrsTy};
Guillaume Chateletd0a7cc72020-01-24 17:40:17 +0100575 Value *Ops[] = {Data, Ptrs, getInt32(Alignment.value()), Mask};
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000576
577 // We specify only one type when we create this intrinsic. Types of other
578 // arguments are derived from this type.
Elad Cohenef5798a2017-05-03 12:28:54 +0000579 return CreateMaskedIntrinsic(Intrinsic::masked_scatter, Ops, OverloadedTypes);
Elena Demikhovsky88e76ca2016-02-17 19:23:04 +0000580}
581
Philip Reames3d40c752020-06-04 15:22:07 -0700582template <typename T0>
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000583static std::vector<Value *>
584getStatepointArgs(IRBuilderBase &B, uint64_t ID, uint32_t NumPatchBytes,
Philip Reames3d40c752020-06-04 15:22:07 -0700585 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs) {
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000586 std::vector<Value *> Args;
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000587 Args.push_back(B.getInt64(ID));
588 Args.push_back(B.getInt32(NumPatchBytes));
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000589 Args.push_back(ActualCallee);
590 Args.push_back(B.getInt32(CallArgs.size()));
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000591 Args.push_back(B.getInt32(Flags));
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000592 Args.insert(Args.end(), CallArgs.begin(), CallArgs.end());
Philip Reames587fa992020-05-28 10:11:08 -0700593 // GC Transition and Deopt args are now always handled via operand bundle.
594 // They will be removed from the signature of gc.statepoint shortly.
595 Args.push_back(B.getInt32(0));
596 Args.push_back(B.getInt32(0));
Philip Reames3d40c752020-06-04 15:22:07 -0700597 // GC args are now encoded in the gc-live operand bundle
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000598 return Args;
599}
600
Philip Reames3d40c752020-06-04 15:22:07 -0700601template<typename T1, typename T2, typename T3>
Philip Reames587fa992020-05-28 10:11:08 -0700602static std::vector<OperandBundleDef>
603getStatepointBundles(Optional<ArrayRef<T1>> TransitionArgs,
Philip Reames3d40c752020-06-04 15:22:07 -0700604 Optional<ArrayRef<T2>> DeoptArgs,
605 ArrayRef<T3> GCArgs) {
Philip Reames587fa992020-05-28 10:11:08 -0700606 std::vector<OperandBundleDef> Rval;
607 if (DeoptArgs) {
608 SmallVector<Value*, 16> DeoptValues;
609 DeoptValues.insert(DeoptValues.end(), DeoptArgs->begin(), DeoptArgs->end());
610 Rval.emplace_back("deopt", DeoptValues);
611 }
612 if (TransitionArgs) {
613 SmallVector<Value*, 16> TransitionValues;
614 TransitionValues.insert(TransitionValues.end(),
615 TransitionArgs->begin(), TransitionArgs->end());
616 Rval.emplace_back("gc-transition", TransitionValues);
617 }
Philip Reames3d40c752020-06-04 15:22:07 -0700618 if (GCArgs.size()) {
619 SmallVector<Value*, 16> LiveValues;
620 LiveValues.insert(LiveValues.end(), GCArgs.begin(), GCArgs.end());
621 Rval.emplace_back("gc-live", LiveValues);
622 }
Philip Reames587fa992020-05-28 10:11:08 -0700623 return Rval;
624}
625
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000626template <typename T0, typename T1, typename T2, typename T3>
627static CallInst *CreateGCStatepointCallCommon(
628 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000629 Value *ActualCallee, uint32_t Flags, ArrayRef<T0> CallArgs,
Philip Reames587fa992020-05-28 10:11:08 -0700630 Optional<ArrayRef<T1>> TransitionArgs,
631 Optional<ArrayRef<T2>> DeoptArgs, ArrayRef<T3> GCArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000632 const Twine &Name) {
Sanjoy Das63245b52015-05-06 02:36:34 +0000633 // Extract out the type of the callee.
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000634 auto *FuncPtrType = cast<PointerType>(ActualCallee->getType());
Sanjoy Das63245b52015-05-06 02:36:34 +0000635 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
636 "actual callee must be a callable value");
Philip Reames4750dd12014-12-30 05:55:58 +0000637
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000638 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
Sanjoy Das63245b52015-05-06 02:36:34 +0000639 // Fill in the one generic type'd argument (the function is also vararg)
640 Type *ArgTypes[] = { FuncPtrType };
641 Function *FnStatepoint =
642 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_statepoint,
643 ArgTypes);
Philip Reames4750dd12014-12-30 05:55:58 +0000644
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000645 std::vector<Value *> Args =
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000646 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualCallee, Flags,
Philip Reames3d40c752020-06-04 15:22:07 -0700647 CallArgs);
Philip Reames587fa992020-05-28 10:11:08 -0700648
649 return Builder->CreateCall(FnStatepoint, Args,
Philip Reames3d40c752020-06-04 15:22:07 -0700650 getStatepointBundles(TransitionArgs, DeoptArgs,
651 GCArgs),
Philip Reames587fa992020-05-28 10:11:08 -0700652 Name);
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000653}
654
655CallInst *IRBuilderBase::CreateGCStatepointCall(
656 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
Philip Reames587fa992020-05-28 10:11:08 -0700657 ArrayRef<Value *> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000658 ArrayRef<Value *> GCArgs, const Twine &Name) {
659 return CreateGCStatepointCallCommon<Value *, Value *, Value *, Value *>(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000660 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
661 CallArgs, None /* No Transition Args */, DeoptArgs, GCArgs, Name);
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000662}
663
664CallInst *IRBuilderBase::CreateGCStatepointCall(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000665 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, uint32_t Flags,
Philip Reames587fa992020-05-28 10:11:08 -0700666 ArrayRef<Use> CallArgs, Optional<ArrayRef<Use>> TransitionArgs,
667 Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs,
668 const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000669 return CreateGCStatepointCallCommon<Use, Use, Use, Value *>(
670 this, ID, NumPatchBytes, ActualCallee, Flags, CallArgs, TransitionArgs,
671 DeoptArgs, GCArgs, Name);
Philip Reames4750dd12014-12-30 05:55:58 +0000672}
673
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000674CallInst *IRBuilderBase::CreateGCStatepointCall(
675 uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee,
Philip Reames587fa992020-05-28 10:11:08 -0700676 ArrayRef<Use> CallArgs, Optional<ArrayRef<Value *>> DeoptArgs,
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000677 ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000678 return CreateGCStatepointCallCommon<Use, Value *, Value *, Value *>(
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000679 this, ID, NumPatchBytes, ActualCallee, uint32_t(StatepointFlags::None),
680 CallArgs, None, DeoptArgs, GCArgs, Name);
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000681}
682
683template <typename T0, typename T1, typename T2, typename T3>
684static InvokeInst *CreateGCStatepointInvokeCommon(
685 IRBuilderBase *Builder, uint64_t ID, uint32_t NumPatchBytes,
686 Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest,
Philip Reames587fa992020-05-28 10:11:08 -0700687 uint32_t Flags, ArrayRef<T0> InvokeArgs,
688 Optional<ArrayRef<T1>> TransitionArgs, Optional<ArrayRef<T2>> DeoptArgs,
689 ArrayRef<T3> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000690 // Extract out the type of the callee.
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000691 auto *FuncPtrType = cast<PointerType>(ActualInvokee->getType());
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000692 assert(isa<FunctionType>(FuncPtrType->getElementType()) &&
693 "actual callee must be a callable value");
694
695 Module *M = Builder->GetInsertBlock()->getParent()->getParent();
696 // Fill in the one generic type'd argument (the function is also vararg)
697 Function *FnStatepoint = Intrinsic::getDeclaration(
698 M, Intrinsic::experimental_gc_statepoint, {FuncPtrType});
699
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000700 std::vector<Value *> Args =
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000701 getStatepointArgs(*Builder, ID, NumPatchBytes, ActualInvokee, Flags,
Philip Reames3d40c752020-06-04 15:22:07 -0700702 InvokeArgs);
Philip Reames587fa992020-05-28 10:11:08 -0700703
Nikita Popovf6875c42020-02-18 20:35:16 +0100704 return Builder->CreateInvoke(FnStatepoint, NormalDest, UnwindDest, Args,
Philip Reames3d40c752020-06-04 15:22:07 -0700705 getStatepointBundles(TransitionArgs, DeoptArgs,
706 GCArgs),
Nikita Popovf6875c42020-02-18 20:35:16 +0100707 Name);
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000708}
709
710InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000711 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
712 BasicBlock *NormalDest, BasicBlock *UnwindDest,
Philip Reames587fa992020-05-28 10:11:08 -0700713 ArrayRef<Value *> InvokeArgs, Optional<ArrayRef<Value *>> DeoptArgs,
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000714 ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000715 return CreateGCStatepointInvokeCommon<Value *, Value *, Value *, Value *>(
716 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000717 uint32_t(StatepointFlags::None), InvokeArgs, None /* No Transition Args*/,
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000718 DeoptArgs, GCArgs, Name);
719}
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000720
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000721InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
722 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000723 BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
Philip Reames587fa992020-05-28 10:11:08 -0700724 ArrayRef<Use> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
725 Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000726 return CreateGCStatepointInvokeCommon<Use, Use, Use, Value *>(
727 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest, Flags,
728 InvokeArgs, TransitionArgs, DeoptArgs, GCArgs, Name);
Sanjoy Dasabe1c682015-05-06 23:53:09 +0000729}
730
731InvokeInst *IRBuilderBase::CreateGCStatepointInvoke(
Sanjoy Dasa1d39ba2015-05-12 23:52:24 +0000732 uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
733 BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
Philip Reames587fa992020-05-28 10:11:08 -0700734 Optional<ArrayRef<Value *>> DeoptArgs, ArrayRef<Value *> GCArgs, const Twine &Name) {
Sanjoy Dasaf6980c2015-10-07 19:52:12 +0000735 return CreateGCStatepointInvokeCommon<Use, Value *, Value *, Value *>(
736 this, ID, NumPatchBytes, ActualInvokee, NormalDest, UnwindDest,
Sanjoy Das4fd3d402015-10-08 23:18:33 +0000737 uint32_t(StatepointFlags::None), InvokeArgs, None, DeoptArgs, GCArgs,
738 Name);
Ramkumar Ramachandra3408f3e2015-02-26 00:35:56 +0000739}
740
Philip Reames4750dd12014-12-30 05:55:58 +0000741CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
742 Type *ResultType,
743 const Twine &Name) {
Ramkumar Ramachandra75a4f352015-01-22 20:14:38 +0000744 Intrinsic::ID ID = Intrinsic::experimental_gc_result;
Philip Reames4750dd12014-12-30 05:55:58 +0000745 Module *M = BB->getParent()->getParent();
746 Type *Types[] = {ResultType};
James Y Knight7976eb52019-02-01 20:43:25 +0000747 Function *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
Philip Reames4750dd12014-12-30 05:55:58 +0000748
749 Value *Args[] = {Statepoint};
750 return createCallHelper(FnGCResult, Args, this, Name);
751}
752
753CallInst *IRBuilderBase::CreateGCRelocate(Instruction *Statepoint,
754 int BaseOffset,
755 int DerivedOffset,
756 Type *ResultType,
757 const Twine &Name) {
758 Module *M = BB->getParent()->getParent();
759 Type *Types[] = {ResultType};
James Y Knight7976eb52019-02-01 20:43:25 +0000760 Function *FnGCRelocate =
761 Intrinsic::getDeclaration(M, Intrinsic::experimental_gc_relocate, Types);
Philip Reames4750dd12014-12-30 05:55:58 +0000762
763 Value *Args[] = {Statepoint,
764 getInt32(BaseOffset),
765 getInt32(DerivedOffset)};
766 return createCallHelper(FnGCRelocate, Args, this, Name);
767}
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000768
Neil Henning57f5d0a2018-10-08 10:32:33 +0000769CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
770 Instruction *FMFSource,
771 const Twine &Name) {
772 Module *M = BB->getModule();
773 Function *Fn = Intrinsic::getDeclaration(M, ID, {V->getType()});
774 return createCallHelper(Fn, {V}, this, Name, FMFSource);
775}
776
777CallInst *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
778 Value *RHS,
779 Instruction *FMFSource,
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000780 const Twine &Name) {
Sanjay Pateld32104e2018-02-23 21:16:12 +0000781 Module *M = BB->getModule();
782 Function *Fn = Intrinsic::getDeclaration(M, ID, { LHS->getType() });
Neil Henning57f5d0a2018-10-08 10:32:33 +0000783 return createCallHelper(Fn, {LHS, RHS}, this, Name, FMFSource);
Matt Arsenaultcdb468c2017-02-27 23:08:49 +0000784}
Sanjay Pateld32104e2018-02-23 21:16:12 +0000785
786CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
Neil Henning57f5d0a2018-10-08 10:32:33 +0000787 ArrayRef<Type *> Types,
Sanjay Pateld32104e2018-02-23 21:16:12 +0000788 ArrayRef<Value *> Args,
789 Instruction *FMFSource,
790 const Twine &Name) {
Sanjay Pateld32104e2018-02-23 21:16:12 +0000791 Module *M = BB->getModule();
Neil Henning57f5d0a2018-10-08 10:32:33 +0000792 Function *Fn = Intrinsic::getDeclaration(M, ID, Types);
Sanjay Pateld32104e2018-02-23 21:16:12 +0000793 return createCallHelper(Fn, Args, this, Name, FMFSource);
794}
Nikita Popov3eaa53e2020-02-16 17:10:09 +0100795
Nikita Popovb90ea4f2020-04-02 21:35:24 +0200796CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
797 Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
798 const Twine &Name, MDNode *FPMathTag,
Serge Pavlovc7ff5b32020-03-26 14:51:09 +0700799 Optional<RoundingMode> Rounding,
Nikita Popovb90ea4f2020-04-02 21:35:24 +0200800 Optional<fp::ExceptionBehavior> Except) {
801 Value *RoundingV = getConstrainedFPRounding(Rounding);
802 Value *ExceptV = getConstrainedFPExcept(Except);
803
804 FastMathFlags UseFMF = FMF;
805 if (FMFSource)
806 UseFMF = FMFSource->getFastMathFlags();
807
808 CallInst *C = CreateIntrinsic(ID, {L->getType()},
809 {L, R, RoundingV, ExceptV}, nullptr, Name);
810 setConstrainedFPCallAttr(C);
811 setFPAttrs(C, FPMathTag, UseFMF);
812 return C;
813}
814
815Value *IRBuilderBase::CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops,
816 const Twine &Name, MDNode *FPMathTag) {
817 if (Instruction::isBinaryOp(Opc)) {
818 assert(Ops.size() == 2 && "Invalid number of operands!");
819 return CreateBinOp(static_cast<Instruction::BinaryOps>(Opc),
820 Ops[0], Ops[1], Name, FPMathTag);
821 }
822 if (Instruction::isUnaryOp(Opc)) {
823 assert(Ops.size() == 1 && "Invalid number of operands!");
824 return CreateUnOp(static_cast<Instruction::UnaryOps>(Opc),
825 Ops[0], Name, FPMathTag);
826 }
827 llvm_unreachable("Unexpected opcode!");
828}
829
830CallInst *IRBuilderBase::CreateConstrainedFPCast(
831 Intrinsic::ID ID, Value *V, Type *DestTy,
832 Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag,
Serge Pavlovc7ff5b32020-03-26 14:51:09 +0700833 Optional<RoundingMode> Rounding,
Nikita Popovb90ea4f2020-04-02 21:35:24 +0200834 Optional<fp::ExceptionBehavior> Except) {
835 Value *ExceptV = getConstrainedFPExcept(Except);
836
837 FastMathFlags UseFMF = FMF;
838 if (FMFSource)
839 UseFMF = FMFSource->getFastMathFlags();
840
841 CallInst *C;
842 bool HasRoundingMD = false;
843 switch (ID) {
844 default:
845 break;
846#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
847 case Intrinsic::INTRINSIC: \
848 HasRoundingMD = ROUND_MODE; \
849 break;
850#include "llvm/IR/ConstrainedOps.def"
851 }
852 if (HasRoundingMD) {
853 Value *RoundingV = getConstrainedFPRounding(Rounding);
854 C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV},
855 nullptr, Name);
856 } else
857 C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr,
858 Name);
859
860 setConstrainedFPCallAttr(C);
861
862 if (isa<FPMathOperator>(C))
863 setFPAttrs(C, FPMathTag, UseFMF);
864 return C;
865}
866
867Value *IRBuilderBase::CreateFCmpHelper(
868 CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name,
869 MDNode *FPMathTag, bool IsSignaling) {
870 if (IsFPConstrained) {
871 auto ID = IsSignaling ? Intrinsic::experimental_constrained_fcmps
872 : Intrinsic::experimental_constrained_fcmp;
873 return CreateConstrainedFPCmp(ID, P, LHS, RHS, Name);
874 }
875
876 if (auto *LC = dyn_cast<Constant>(LHS))
877 if (auto *RC = dyn_cast<Constant>(RHS))
878 return Insert(Folder.CreateFCmp(P, LC, RC), Name);
879 return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name);
880}
881
882CallInst *IRBuilderBase::CreateConstrainedFPCmp(
883 Intrinsic::ID ID, CmpInst::Predicate P, Value *L, Value *R,
884 const Twine &Name, Optional<fp::ExceptionBehavior> Except) {
885 Value *PredicateV = getConstrainedFPPredicate(P);
886 Value *ExceptV = getConstrainedFPExcept(Except);
887
888 CallInst *C = CreateIntrinsic(ID, {L->getType()},
889 {L, R, PredicateV, ExceptV}, nullptr, Name);
890 setConstrainedFPCallAttr(C);
891 return C;
892}
893
894CallInst *IRBuilderBase::CreateConstrainedFPCall(
895 Function *Callee, ArrayRef<Value *> Args, const Twine &Name,
Serge Pavlovc7ff5b32020-03-26 14:51:09 +0700896 Optional<RoundingMode> Rounding,
Nikita Popovb90ea4f2020-04-02 21:35:24 +0200897 Optional<fp::ExceptionBehavior> Except) {
898 llvm::SmallVector<Value *, 6> UseArgs;
899
900 for (auto *OneArg : Args)
901 UseArgs.push_back(OneArg);
902 bool HasRoundingMD = false;
903 switch (Callee->getIntrinsicID()) {
904 default:
905 break;
906#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
907 case Intrinsic::INTRINSIC: \
908 HasRoundingMD = ROUND_MODE; \
909 break;
910#include "llvm/IR/ConstrainedOps.def"
911 }
912 if (HasRoundingMD)
913 UseArgs.push_back(getConstrainedFPRounding(Rounding));
914 UseArgs.push_back(getConstrainedFPExcept(Except));
915
916 CallInst *C = CreateCall(Callee, UseArgs, Name);
917 setConstrainedFPCallAttr(C);
918 return C;
919}
920
921Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False,
922 const Twine &Name, Instruction *MDFrom) {
923 if (auto *CC = dyn_cast<Constant>(C))
924 if (auto *TC = dyn_cast<Constant>(True))
925 if (auto *FC = dyn_cast<Constant>(False))
926 return Insert(Folder.CreateSelect(CC, TC, FC), Name);
927
928 SelectInst *Sel = SelectInst::Create(C, True, False);
929 if (MDFrom) {
930 MDNode *Prof = MDFrom->getMetadata(LLVMContext::MD_prof);
931 MDNode *Unpred = MDFrom->getMetadata(LLVMContext::MD_unpredictable);
932 Sel = addBranchMetadata(Sel, Prof, Unpred);
933 }
934 if (isa<FPMathOperator>(Sel))
935 setFPAttrs(Sel, nullptr /* MDNode* */, FMF);
936 return Insert(Sel, Name);
937}
938
939Value *IRBuilderBase::CreatePtrDiff(Value *LHS, Value *RHS,
940 const Twine &Name) {
941 assert(LHS->getType() == RHS->getType() &&
942 "Pointer subtraction operand types must match!");
943 auto *ArgType = cast<PointerType>(LHS->getType());
944 Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
945 Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
946 Value *Difference = CreateSub(LHS_int, RHS_int);
947 return CreateExactSDiv(Difference,
948 ConstantExpr::getSizeOf(ArgType->getElementType()),
949 Name);
950}
951
952Value *IRBuilderBase::CreateLaunderInvariantGroup(Value *Ptr) {
953 assert(isa<PointerType>(Ptr->getType()) &&
954 "launder.invariant.group only applies to pointers.");
955 // FIXME: we could potentially avoid casts to/from i8*.
956 auto *PtrType = Ptr->getType();
957 auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
958 if (PtrType != Int8PtrTy)
959 Ptr = CreateBitCast(Ptr, Int8PtrTy);
960 Module *M = BB->getParent()->getParent();
961 Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration(
962 M, Intrinsic::launder_invariant_group, {Int8PtrTy});
963
964 assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy &&
965 FnLaunderInvariantGroup->getFunctionType()->getParamType(0) ==
966 Int8PtrTy &&
967 "LaunderInvariantGroup should take and return the same type");
968
969 CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr});
970
971 if (PtrType != Int8PtrTy)
972 return CreateBitCast(Fn, PtrType);
973 return Fn;
974}
975
976Value *IRBuilderBase::CreateStripInvariantGroup(Value *Ptr) {
977 assert(isa<PointerType>(Ptr->getType()) &&
978 "strip.invariant.group only applies to pointers.");
979
980 // FIXME: we could potentially avoid casts to/from i8*.
981 auto *PtrType = Ptr->getType();
982 auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
983 if (PtrType != Int8PtrTy)
984 Ptr = CreateBitCast(Ptr, Int8PtrTy);
985 Module *M = BB->getParent()->getParent();
986 Function *FnStripInvariantGroup = Intrinsic::getDeclaration(
987 M, Intrinsic::strip_invariant_group, {Int8PtrTy});
988
989 assert(FnStripInvariantGroup->getReturnType() == Int8PtrTy &&
990 FnStripInvariantGroup->getFunctionType()->getParamType(0) ==
991 Int8PtrTy &&
992 "StripInvariantGroup should take and return the same type");
993
994 CallInst *Fn = CreateCall(FnStripInvariantGroup, {Ptr});
995
996 if (PtrType != Int8PtrTy)
997 return CreateBitCast(Fn, PtrType);
998 return Fn;
999}
1000
1001Value *IRBuilderBase::CreateVectorSplat(unsigned NumElts, Value *V,
1002 const Twine &Name) {
Mehdi Aminia407ec92020-08-19 17:26:36 +00001003 auto EC = ElementCount::getFixed(NumElts);
Simon Pilgrime2022362020-08-02 16:55:16 +01001004 return CreateVectorSplat(EC, V, Name);
1005}
1006
1007Value *IRBuilderBase::CreateVectorSplat(ElementCount EC, Value *V,
1008 const Twine &Name) {
David Sherwoodf4257c52020-08-14 12:15:59 +01001009 assert(EC.isNonZero() && "Cannot splat to an empty vector!");
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001010
1011 // First insert it into an undef vector so we can shuffle it.
1012 Type *I32Ty = getInt32Ty();
Simon Pilgrime2022362020-08-02 16:55:16 +01001013 Value *Undef = UndefValue::get(VectorType::get(V->getType(), EC));
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001014 V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0),
1015 Name + ".splatinsert");
1016
1017 // Shuffle the value across the desired number of elements.
Simon Pilgrime2022362020-08-02 16:55:16 +01001018 Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, EC));
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001019 return CreateShuffleVector(V, Undef, Zeros, Name + ".splat");
1020}
1021
1022Value *IRBuilderBase::CreateExtractInteger(
1023 const DataLayout &DL, Value *From, IntegerType *ExtractedTy,
1024 uint64_t Offset, const Twine &Name) {
1025 auto *IntTy = cast<IntegerType>(From->getType());
1026 assert(DL.getTypeStoreSize(ExtractedTy) + Offset <=
1027 DL.getTypeStoreSize(IntTy) &&
1028 "Element extends past full value");
1029 uint64_t ShAmt = 8 * Offset;
1030 Value *V = From;
1031 if (DL.isBigEndian())
1032 ShAmt = 8 * (DL.getTypeStoreSize(IntTy) -
1033 DL.getTypeStoreSize(ExtractedTy) - Offset);
1034 if (ShAmt) {
1035 V = CreateLShr(V, ShAmt, Name + ".shift");
1036 }
1037 assert(ExtractedTy->getBitWidth() <= IntTy->getBitWidth() &&
1038 "Cannot extract to a larger integer!");
1039 if (ExtractedTy != IntTy) {
1040 V = CreateTrunc(V, ExtractedTy, Name + ".trunc");
1041 }
1042 return V;
1043}
1044
1045Value *IRBuilderBase::CreatePreserveArrayAccessIndex(
1046 Type *ElTy, Value *Base, unsigned Dimension, unsigned LastIndex,
1047 MDNode *DbgInfo) {
1048 assert(isa<PointerType>(Base->getType()) &&
1049 "Invalid Base ptr type for preserve.array.access.index.");
1050 auto *BaseType = Base->getType();
1051
1052 Value *LastIndexV = getInt32(LastIndex);
1053 Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
1054 SmallVector<Value *, 4> IdxList;
1055 for (unsigned I = 0; I < Dimension; ++I)
1056 IdxList.push_back(Zero);
1057 IdxList.push_back(LastIndexV);
1058
1059 Type *ResultType =
1060 GetElementPtrInst::getGEPReturnType(ElTy, Base, IdxList);
1061
1062 Module *M = BB->getParent()->getParent();
1063 Function *FnPreserveArrayAccessIndex = Intrinsic::getDeclaration(
1064 M, Intrinsic::preserve_array_access_index, {ResultType, BaseType});
1065
1066 Value *DimV = getInt32(Dimension);
1067 CallInst *Fn =
1068 CreateCall(FnPreserveArrayAccessIndex, {Base, DimV, LastIndexV});
1069 if (DbgInfo)
1070 Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
1071
1072 return Fn;
1073}
1074
1075Value *IRBuilderBase::CreatePreserveUnionAccessIndex(
1076 Value *Base, unsigned FieldIndex, MDNode *DbgInfo) {
1077 assert(isa<PointerType>(Base->getType()) &&
1078 "Invalid Base ptr type for preserve.union.access.index.");
1079 auto *BaseType = Base->getType();
1080
1081 Module *M = BB->getParent()->getParent();
1082 Function *FnPreserveUnionAccessIndex = Intrinsic::getDeclaration(
1083 M, Intrinsic::preserve_union_access_index, {BaseType, BaseType});
1084
1085 Value *DIIndex = getInt32(FieldIndex);
1086 CallInst *Fn =
1087 CreateCall(FnPreserveUnionAccessIndex, {Base, DIIndex});
1088 if (DbgInfo)
1089 Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
1090
1091 return Fn;
1092}
1093
1094Value *IRBuilderBase::CreatePreserveStructAccessIndex(
1095 Type *ElTy, Value *Base, unsigned Index, unsigned FieldIndex,
1096 MDNode *DbgInfo) {
1097 assert(isa<PointerType>(Base->getType()) &&
1098 "Invalid Base ptr type for preserve.struct.access.index.");
1099 auto *BaseType = Base->getType();
1100
1101 Value *GEPIndex = getInt32(Index);
1102 Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
1103 Type *ResultType =
1104 GetElementPtrInst::getGEPReturnType(ElTy, Base, {Zero, GEPIndex});
1105
1106 Module *M = BB->getParent()->getParent();
1107 Function *FnPreserveStructAccessIndex = Intrinsic::getDeclaration(
1108 M, Intrinsic::preserve_struct_access_index, {ResultType, BaseType});
1109
1110 Value *DIIndex = getInt32(FieldIndex);
1111 CallInst *Fn = CreateCall(FnPreserveStructAccessIndex,
1112 {Base, GEPIndex, DIIndex});
1113 if (DbgInfo)
1114 Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
1115
1116 return Fn;
1117}
1118
Tyker78de7292020-09-12 13:36:45 +02001119CallInst *IRBuilderBase::CreateAlignmentAssumptionHelper(const DataLayout &DL,
1120 Value *PtrValue,
1121 Value *AlignValue,
1122 Value *OffsetValue) {
1123 SmallVector<Value *, 4> Vals({PtrValue, AlignValue});
1124 if (OffsetValue)
1125 Vals.push_back(OffsetValue);
1126 OperandBundleDefT<Value *> AlignOpB("align", Vals);
1127 return CreateAssumption(ConstantInt::getTrue(getContext()), {AlignOpB});
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001128}
1129
Tyker78de7292020-09-12 13:36:45 +02001130CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
1131 Value *PtrValue,
1132 unsigned Alignment,
1133 Value *OffsetValue) {
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001134 assert(isa<PointerType>(PtrValue->getType()) &&
1135 "trying to create an alignment assumption on a non-pointer?");
1136 assert(Alignment != 0 && "Invalid Alignment");
1137 auto *PtrTy = cast<PointerType>(PtrValue->getType());
1138 Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
Tyker78de7292020-09-12 13:36:45 +02001139 Value *AlignValue = ConstantInt::get(IntPtrTy, Alignment);
1140 return CreateAlignmentAssumptionHelper(DL, PtrValue, AlignValue, OffsetValue);
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001141}
1142
Tyker78de7292020-09-12 13:36:45 +02001143CallInst *IRBuilderBase::CreateAlignmentAssumption(const DataLayout &DL,
1144 Value *PtrValue,
1145 Value *Alignment,
1146 Value *OffsetValue) {
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001147 assert(isa<PointerType>(PtrValue->getType()) &&
1148 "trying to create an alignment assumption on a non-pointer?");
Tyker78de7292020-09-12 13:36:45 +02001149 return CreateAlignmentAssumptionHelper(DL, PtrValue, Alignment, OffsetValue);
Nikita Popovb90ea4f2020-04-02 21:35:24 +02001150}
1151
Nikita Popov3eaa53e2020-02-16 17:10:09 +01001152IRBuilderDefaultInserter::~IRBuilderDefaultInserter() {}
1153IRBuilderCallbackInserter::~IRBuilderCallbackInserter() {}
1154IRBuilderFolder::~IRBuilderFolder() {}
1155void ConstantFolder::anchor() {}
1156void NoFolder::anchor() {}