LLVM: lib/Transforms/Utils/VNCoercion.cpp Source File (original) (raw)
6
7#define DEBUG_TYPE "vncoerce"
8
9namespace llvm {
10namespace VNCoercion {
11
15
16
20 if (StoredTy == LoadTy)
21 return true;
22
24 TypeSize MinStoreSize = DL.getTypeSizeInBits(StoredTy);
25 TypeSize LoadSize = DL.getTypeSizeInBits(LoadTy);
27 MinStoreSize == LoadSize)
28 return true;
29
30
31
32
35 return false;
36
37
38
39 const auto &Attrs = F->getAttributes().getFnAttrs();
40 unsigned MinVScale = Attrs.getVScaleRangeMin();
41 MinStoreSize =
45 return false;
46 }
47
48
49 if (llvm::alignTo(MinStoreSize, 8) != MinStoreSize)
50 return false;
51
52
54 return false;
55
56 bool StoredNI = DL.isNonIntegralPointerType(StoredTy->getScalarType());
57 bool LoadNI = DL.isNonIntegralPointerType(LoadTy->getScalarType());
58
59 if (StoredNI != LoadNI) {
60
61
62
64 return CI->isNullValue();
65 return false;
66 } else if (StoredNI && LoadNI &&
69 return false;
70 }
71
72
73
74
75 if (StoredNI && (StoredTy->isScalableTy() || MinStoreSize != LoadSize))
76 return false;
77
79 return false;
80
81 return true;
82}
83
84
85
86
87
88
89
93 "precondition violation - materialization can't fail");
97
98
100
101
102
105 return Helper.CreateIntrinsic(LoadedTy, Intrinsic::vector_extract,
106 {StoredVal, Helper.getInt64(0)});
107 }
108
109 TypeSize StoredValSize = DL.getTypeSizeInBits(StoredValTy);
110 TypeSize LoadedValSize = DL.getTypeSizeInBits(LoadedTy);
111
112
113 if (StoredValSize == LoadedValSize) {
114
116 StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy);
117 } else {
118
120 StoredValTy = DL.getIntPtrType(StoredValTy);
121 StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy);
122 }
123
124 Type *TypeToCastTo = LoadedTy;
126 TypeToCastTo = DL.getIntPtrType(TypeToCastTo);
127
128 if (StoredValTy != TypeToCastTo)
129 StoredVal = Helper.CreateBitCast(StoredVal, TypeToCastTo);
130
131
133 StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy);
134 }
135
138
139 return StoredVal;
140 }
141
142
143
146 "canCoerceMustAliasedValueToLoad fail");
147
148
150 StoredValTy = DL.getIntPtrType(StoredValTy);
151 StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy);
152 }
153
154
157 StoredVal = Helper.CreateBitCast(StoredVal, StoredValTy);
158 }
159
160
161
162 if (DL.isBigEndian()) {
163 uint64_t ShiftAmt = DL.getTypeStoreSizeInBits(StoredValTy).getFixedValue() -
164 DL.getTypeStoreSizeInBits(LoadedTy).getFixedValue();
166 StoredVal, ConstantInt::get(StoredVal->getType(), ShiftAmt));
167 }
168
169
172
173 if (LoadedTy != NewIntTy) {
174
176 StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy);
177 else
178
179 StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy);
180 }
181
184
185 return StoredVal;
186}
187
188
189
190
191
192
193
194
195
200
201
203 return -1;
204
205 int64_t StoreOffset = 0, LoadOffset = 0;
206 Value *StoreBase =
209 if (StoreBase != LoadBase)
210 return -1;
211
212 uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy).getFixedValue();
213
214 if ((WriteSizeInBits & 7) | (LoadSize & 7))
215 return -1;
216 uint64_t StoreSize = WriteSizeInBits / 8;
217 LoadSize /= 8;
218
219
220
221
222
223 if (StoreOffset > LoadOffset ||
224 StoreOffset + int64_t(StoreSize) < LoadOffset + int64_t(LoadSize))
225 return -1;
226
227
228
229 return LoadOffset - StoreOffset;
230}
231
232
233
237
238
240 return -1;
241
243 return -1;
244
250}
251
252
253
254
257
259 return -1;
260
262 return -1;
263
265 uint64_t DepSize = DL.getTypeSizeInBits(DepLI->getType()).getFixedValue();
267}
268
271
273 if (!SizeCst)
274 return -1;
276
277
278
280 if (DL.isNonIntegralPointerType(LoadTy->getScalarType())) {
282 if (!CI || !CI->isZero())
283 return -1;
284 }
286 MemSizeInBits, DL);
287 }
288
289
290
291
293
295 if (!Src)
296 return -1;
297
300 return -1;
301
302
304 MemSizeInBits, DL);
307
308
309
310 unsigned IndexSize = DL.getIndexTypeSizeInBits(Src->getType());
313 return -1;
314}
315
320
321
322
323
327 return SrcVal;
328 }
329
330
331
333 assert(Offset == 0 && "Expected a zero offset for scalable types");
334 return SrcVal;
335 }
336
337
338
339
344 return SrcVal;
345 }
346
348 (DL.getTypeSizeInBits(SrcVal->getType()).getFixedValue() + 7) / 8;
349 uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy).getFixedValue() + 7) / 8;
350
351
353 SrcVal =
354 Builder.CreatePtrToInt(SrcVal, DL.getIntPtrType(SrcVal->getType()));
356 SrcVal =
357 Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize * 8));
358
359
360 unsigned ShiftAmt;
361 if (DL.isLittleEndian())
362 ShiftAmt = Offset * 8;
363 else
364 ShiftAmt = (StoreSize - LoadSize - Offset) * 8;
365 if (ShiftAmt)
366 SrcVal = Builder.CreateLShr(SrcVal,
367 ConstantInt::get(SrcVal->getType(), ShiftAmt));
368
369 if (LoadSize != StoreSize)
370 SrcVal = Builder.CreateTruncOrBitCast(SrcVal,
372 return SrcVal;
373}
374
378#ifndef NDEBUG
380 TypeSize LoadSize = DL.getTypeStoreSize(LoadTy);
382 MinSrcValSize =
384 F->getAttributes().getFnAttrs().getVScaleRangeMin());
386 "Expected Offset + LoadSize <= SrcValSize");
389 "Expected offset of zero and LoadSize <= SrcValSize");
390#endif
394}
395
398#ifndef NDEBUG
399 unsigned SrcValSize = DL.getTypeStoreSize(SrcVal->getType()).getFixedValue();
400 unsigned LoadSize = DL.getTypeStoreSize(LoadTy).getFixedValue();
402#endif
404}
405
406
407
412 uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
414
415
416
418
419
420 Value *Val = MSI->getValue();
421 if (LoadSize != 1)
422 Val =
423 Builder.CreateZExtOrBitCast(Val, IntegerType::get(Ctx, LoadSize * 8));
424 Value *OneElt = Val;
425
426
427 for (unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
428
429 if (NumBytesSet * 2 <= LoadSize) {
430 Value *ShVal = Builder.CreateShl(
431 Val, ConstantInt::get(Val->getType(), NumBytesSet * 8));
432 Val = Builder.CreateOr(Val, ShVal);
433 NumBytesSet <<= 1;
434 continue;
435 }
436
437
439 Builder.CreateShl(Val, ConstantInt::get(Val->getType(), 1 * 8));
440 Val = Builder.CreateOr(OneElt, ShVal);
441 ++NumBytesSet;
442 }
443
446 }
447
448
451 unsigned IndexSize = DL.getIndexTypeSizeInBits(Src->getType());
454}
455
459 uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
460
461
462
465 if (!Val)
466 return nullptr;
467
468 Val = ConstantInt::get(Ctx, APInt::getSplat(LoadSize * 8, Val->getValue()));
470 }
471
472
475 unsigned IndexSize = DL.getIndexTypeSizeInBits(Src->getType());
478}
479}
480}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Class for arbitrary precision integers.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
Common base class shared among various IRBuilders.
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateTruncOrBitCast(Value *V, Type *DestTy, const Twine &Name="")
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
Value * getPointerOperand()
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it,...
This class wraps the llvm.memcpy/memmove intrinsics.
An instruction for storing to memory.
Value * getValueOperand()
Value * getPointerOperand()
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
bool isTargetExtTy() const
Return true if this is a target extension type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
@ C
The default llvm calling convention, compatible with C.
static int analyzeLoadFromClobberingWrite(Type *LoadTy, Value *LoadPtr, Value *WritePtr, uint64_t WriteSizeInBits, const DataLayout &DL)
This function is called when we have a memdep query of a load that ends up being a clobbering memory ...
Definition VNCoercion.cpp:196
static Value * getStoreValueForLoadHelper(Value *SrcVal, unsigned Offset, Type *LoadTy, IRBuilderBase &Builder, const DataLayout &DL)
Definition VNCoercion.cpp:316
int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...
Definition VNCoercion.cpp:234
Value * getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingMemInst returned an offset, this function can be used to actually perform...
Definition VNCoercion.cpp:408
Constant * getConstantValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
Definition VNCoercion.cpp:396
Value * coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, IRBuilderBase &IRB, Function *F)
If we saw a store of a value to memory, and then a load from a must-aliased pointer of a different ty...
Definition VNCoercion.cpp:90
int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...
Definition VNCoercion.cpp:255
Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
Definition VNCoercion.cpp:456
Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, Function *F)
If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...
Definition VNCoercion.cpp:375
int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
Definition VNCoercion.cpp:269
static bool isFirstClassAggregateOrScalableType(Type *Ty)
Definition VNCoercion.cpp:12
bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, Function *F)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
Definition VNCoercion.cpp:17
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....