8#define DEBUG_TYPE "vncoerce"
22 if (StoredTy == LoadTy)
31 uint64_t StoreSize =
DL.getTypeSizeInBits(StoredTy).getFixedValue();
38 if (StoreSize <
DL.getTypeSizeInBits(LoadTy).getFixedValue())
44 if (StoredNI != LoadNI) {
48 if (
auto *CI = dyn_cast<Constant>(StoredVal))
49 return CI->isNullValue();
51 }
else if (StoredNI && LoadNI &&
61 if (StoredNI && StoreSize !=
DL.getTypeSizeInBits(LoadTy).getFixedValue())
80 "precondition violation - materialization can't fail");
81 if (
auto *
C = dyn_cast<Constant>(StoredVal))
87 uint64_t StoredValSize =
DL.getTypeSizeInBits(StoredValTy).getFixedValue();
88 uint64_t LoadedValSize =
DL.getTypeSizeInBits(LoadedTy).getFixedValue();
91 if (StoredValSize == LoadedValSize) {
98 StoredValTy =
DL.getIntPtrType(StoredValTy);
102 Type *TypeToCastTo = LoadedTy;
104 TypeToCastTo =
DL.getIntPtrType(TypeToCastTo);
106 if (StoredValTy != TypeToCastTo)
114 if (
auto *
C = dyn_cast<ConstantExpr>(StoredVal))
122 assert(StoredValSize >= LoadedValSize &&
123 "canCoerceMustAliasedValueToLoad fail");
127 StoredValTy =
DL.getIntPtrType(StoredValTy);
139 if (
DL.isBigEndian()) {
140 uint64_t ShiftAmt =
DL.getTypeStoreSizeInBits(StoredValTy).getFixedValue() -
141 DL.getTypeStoreSizeInBits(LoadedTy).getFixedValue();
143 StoredVal, ConstantInt::get(StoredVal->
getType(), ShiftAmt));
150 if (LoadedTy != NewIntTy) {
159 if (
auto *
C = dyn_cast<Constant>(StoredVal))
182 int64_t StoreOffset = 0, LoadOffset = 0;
186 if (StoreBase != LoadBase)
189 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue();
191 if ((WriteSizeInBits & 7) | (LoadSize & 7))
193 uint64_t StoreSize = WriteSizeInBits / 8;
200 if (StoreOffset > LoadOffset ||
201 StoreOffset + int64_t(StoreSize) < LoadOffset + int64_t(LoadSize))
206 return LoadOffset - StoreOffset;
249 ConstantInt *SizeCst = dyn_cast<ConstantInt>(
MI->getLength());
256 if (
const auto *memset_inst = dyn_cast<MemSetInst>(
MI)) {
258 auto *CI = dyn_cast<ConstantInt>(memset_inst->getValue());
259 if (!CI || !CI->isZero())
287 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
302 cast<PointerType>(SrcVal->
getType())->getAddressSpace() ==
303 cast<PointerType>(LoadTy)->getAddressSpace()) {
308 (
DL.getTypeSizeInBits(SrcVal->
getType()).getFixedValue() + 7) / 8;
309 uint64_t LoadSize = (
DL.getTypeSizeInBits(LoadTy).getFixedValue() + 7) / 8;
321 if (
DL.isLittleEndian())
324 ShiftAmt = (StoreSize - LoadSize -
Offset) * 8;
327 ConstantInt::get(SrcVal->
getType(), ShiftAmt));
329 if (LoadSize != StoreSize)
339 unsigned SrcValSize =
DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
340 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
351 unsigned SrcValSize =
DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
352 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
364 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
369 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
372 Value *Val = MSI->getValue();
379 for (
unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
381 if (NumBytesSet * 2 <= LoadSize) {
383 Val, ConstantInt::get(Val->
getType(), NumBytesSet * 8));
392 Val = Builder.
CreateOr(OneElt, ShVal);
402 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
410 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
414 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
415 auto *Val = dyn_cast<ConstantInt>(MSI->getValue());
419 Val = ConstantInt::get(Ctx,
APInt::getSplat(LoadSize * 8, Val->getValue()));
426 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
static 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 * CreateZExtOrBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, 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...
static 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()
The instances of the Type class are immutable: once they are created, they are never changed.
bool isArrayTy() const
True if this is an instance of ArrayType.
bool isPointerTy() const
True if this is an instance of PointerType.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isStructTy() const
True if this is an instance of StructType.
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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
@ C
The default llvm calling convention, compatible with C.
Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...
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 * coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, IRBuilderBase &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 Value * getStoreValueForLoadHelper(Value *SrcVal, unsigned Offset, Type *LoadTy, IRBuilderBase &Builder, const DataLayout &DL)
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...
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...
Constant * getConstantValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
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...
Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
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...
static bool isFirstClassAggregateOrScalableType(Type *Ty)
bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, const DataLayout &DL)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
This is an optimization pass for GlobalISel generic memory operations.
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.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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...