10 #define DEBUG_TYPE "vncoerce" 12 namespace VNCoercion {
41 template <
class T,
class HelperClass>
46 "precondition violation - materialization can't fail");
47 if (
auto *
C = dyn_cast<Constant>(StoredVal))
49 StoredVal = FoldedStoredVal;
52 Type *StoredValTy = StoredVal->getType();
58 if (StoredValSize == LoadedValSize) {
61 StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy);
66 StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy);
69 Type *TypeToCastTo = LoadedTy;
73 if (StoredValTy != TypeToCastTo)
74 StoredVal = Helper.CreateBitCast(StoredVal, TypeToCastTo);
78 StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy);
81 if (
auto *
C = dyn_cast<ConstantExpr>(StoredVal))
83 StoredVal = FoldedStoredVal;
90 assert(StoredValSize >= LoadedValSize &&
91 "canCoerceMustAliasedValueToLoad fail");
96 StoredVal = Helper.CreatePtrToInt(StoredVal, StoredValTy);
102 StoredVal = Helper.CreateBitCast(StoredVal, StoredValTy);
110 StoredVal = Helper.CreateLShr(
116 StoredVal = Helper.CreateTruncOrBitCast(StoredVal, NewIntTy);
118 if (LoadedTy != NewIntTy) {
121 StoredVal = Helper.CreateIntToPtr(StoredVal, LoadedTy);
124 StoredVal = Helper.CreateBitCast(StoredVal, LoadedTy);
127 if (
auto *
C = dyn_cast<Constant>(StoredVal))
129 StoredVal = FoldedStoredVal;
155 uint64_t WriteSizeInBits,
162 int64_t StoreOffset = 0, LoadOffset = 0;
166 if (StoreBase != LoadBase)
179 if ((WriteSizeInBits & 7) | (LoadSize & 7))
181 uint64_t StoreSize = WriteSizeInBits / 8;
184 bool isAAFailure =
false;
185 if (StoreOffset < LoadOffset)
186 isAAFailure = StoreOffset + int64_t(StoreSize) <= LoadOffset;
188 isAAFailure = LoadOffset + int64_t(LoadSize) <= StoreOffset;
197 if (StoreOffset > LoadOffset ||
198 StoreOffset + StoreSize < LoadOffset + LoadSize)
203 return LoadOffset - StoreOffset;
239 int64_t LoadOffs = 0;
240 const Value *LoadBase =
245 LoadBase, LoadOffs, LoadSize, DepLI);
251 assert(DepLI->
isSimple() &&
"Cannot widen volatile/atomic load!");
290 unsigned AS = Src->getType()->getPointerAddressSpace();
305 template <
class T,
class HelperClass>
309 LLVMContext &Ctx = SrcVal->getType()->getContext();
314 if (SrcVal->getType()->isPointerTy() && LoadTy->
isPointerTy() &&
315 cast<PointerType>(SrcVal->getType())->getAddressSpace() ==
316 cast<PointerType>(LoadTy)->getAddressSpace()) {
324 if (SrcVal->getType()->isPtrOrPtrVectorTy())
325 SrcVal = Helper.CreatePtrToInt(SrcVal, DL.
getIntPtrType(SrcVal->getType()));
326 if (!SrcVal->getType()->isIntegerTy())
327 SrcVal = Helper.CreateBitCast(SrcVal,
IntegerType::get(Ctx, StoreSize * 8));
332 ShiftAmt = Offset * 8;
334 ShiftAmt = (StoreSize - LoadSize -
Offset) * 8;
336 SrcVal = Helper.CreateLShr(SrcVal,
339 if (LoadSize != StoreSize)
340 SrcVal = Helper.CreateTruncOrBitCast(SrcVal,
375 if (Offset + LoadSize > SrcValStoreSize) {
376 assert(SrcVal->
isSimple() &&
"Cannot widen volatile/atomic load!");
380 unsigned NewLoadSize = Offset + LoadSize;
392 Builder.SetCurrentDebugLocation(SrcVal->
getDebugLoc());
393 PtrVal = Builder.CreateBitCast(PtrVal, DestPTy);
394 LoadInst *NewLoad = Builder.CreateLoad(PtrVal);
405 RV = Builder.CreateLShr(RV, (NewLoadSize - SrcValStoreSize) * 8);
406 RV = Builder.CreateTrunc(RV, SrcVal->
getType());
419 if (Offset + LoadSize > SrcValStoreSize)
424 template <
class T,
class HelperClass>
426 Type *LoadTy, HelperClass &Helper,
433 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
436 T *Val = cast<T>(MSI->getValue());
443 for (
unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
445 if (NumBytesSet * 2 <= LoadSize) {
446 T *ShVal = Helper.CreateShl(
448 Val = Helper.CreateOr(Val, ShVal);
455 Val = Helper.CreateOr(OneElt, ShVal);
485 return getMemInstValueForLoadHelper<Value, IRBuilder<>>(SrcInst,
Offset,
486 LoadTy, Builder, DL);
493 if (
auto *MSI = dyn_cast<MemSetInst>(SrcInst))
494 if (!isa<Constant>(MSI->getValue()))
497 return getMemInstValueForLoadHelper<Constant, ConstantFolder>(SrcInst,
Offset,
Value * getValueOperand()
A parsed version of the target data layout string in and methods for querying it. ...
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
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...
This class represents lattice values for constants.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant *> IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space...
This class wraps the llvm.memset intrinsic.
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
An instruction for reading from memory.
static IntegerType * getInt64Ty(LLVMContext &C)
Value * getLength() const
Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
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...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions (including addrspacecast) that ...
Value * coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, IRBuilder<> &IRB, const DataLayout &DL)
If we saw a store of a value to memory, and then a load from a must-aliased pointer of a different ty...
static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs, unsigned MemLocSize, const LoadInst *LI)
Looks at a memory location for a load (specified by MemLocBase, Offs, and Size) and compares it again...
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
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...
Constant * getConstantStoreValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
bool isIntegerTy() const
True if this is an instance of IntegerType.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Attempt to fold the constant using the specified DataLayout.
Type * getType() const
All values are typed, get the type of this value.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset...
bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, const DataLayout &DL)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
static T * getStoreValueForLoadHelper(T *SrcVal, unsigned Offset, Type *LoadTy, HelperClass &Helper, const DataLayout &DL)
ConstantFolder - Create constants with minimum, target independent, folding.
bool isLittleEndian() const
Layout endianness...
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void takeName(Value *V)
Transfer the name from V to this value.
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...
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This is an important base class in LLVM.
Constant * getConstantLoadValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
bool isPointerTy() const
True if this is an instance of PointerType.
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 ...
Value * getPointerOperand()
Value * getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingLoad returned an offset, this function can be used to actually perform th...
void setAlignment(unsigned Align)
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, const DataLayout &DL)
ConstantFoldLoadFromConstPtr - Return the value that a load from C would produce if it is constant an...
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value...
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is the common base class for memset/memcpy/memmove.
This is the shared class of boolean and integer constants.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static T * coerceAvailableValueToLoadTypeHelper(T *StoredVal, Type *LoadedTy, HelperClass &Helper, const DataLayout &DL)
InstListType::iterator iterator
Instruction iterators...
bool isNonIntegralPointerType(PointerType *PT) const
uint64_t getTypeSizeInBits(Type *Ty) const
Size examples:
This class wraps the llvm.memcpy/memmove intrinsics.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
unsigned getAlignment() const
Return the alignment of the access that is being performed.
Value * getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingStore returned an offset, this function can be used to actually perform t...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
T * getMemInstValueForLoadHelper(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, HelperClass &Helper, const DataLayout &DL)
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it...
Value * getPointerOperand()
static IntegerType * getInt8Ty(LLVMContext &C)
bool isStructTy() const
True if this is an instance of StructType.
bool isArrayTy() const
True if this is an instance of ArrayType.
const BasicBlock * getParent() const