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();
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;
253 const Value *LIBase =
258 if (LIBase != MemLocBase)
268 if (MemLocOffs < LIOffs)
278 int64_t MemLocEnd = MemLocOffs + MemLocSize;
281 if (LIOffs + LoadAlign < MemLocEnd)
292 if (NewLoadByteSize > LoadAlign ||
293 !
DL.fitsInLegalInteger(NewLoadByteSize * 8))
296 if (LIOffs + NewLoadByteSize > MemLocEnd &&
298 Attribute::SanitizeAddress) ||
300 Attribute::SanitizeHWAddress)))
307 if (LIOffs + NewLoadByteSize >= MemLocEnd)
308 return NewLoadByteSize;
310 NewLoadByteSize <<= 1;
334 int64_t LoadOffs = 0;
335 const Value *LoadBase =
337 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
346 assert(DepLI->
isSimple() &&
"Cannot widen volatile/atomic load!");
355 ConstantInt *SizeCst = dyn_cast<ConstantInt>(
MI->getLength());
362 if (
const auto *memset_inst = dyn_cast<MemSetInst>(
MI)) {
364 auto *CI = dyn_cast<ConstantInt>(memset_inst->getValue());
365 if (!CI || !CI->isZero())
393 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
408 cast<PointerType>(SrcVal->
getType())->getAddressSpace() ==
409 cast<PointerType>(LoadTy)->getAddressSpace()) {
414 (
DL.getTypeSizeInBits(SrcVal->
getType()).getFixedValue() + 7) / 8;
415 uint64_t LoadSize = (
DL.getTypeSizeInBits(LoadTy).getFixedValue() + 7) / 8;
427 if (
DL.isLittleEndian())
430 ShiftAmt = (StoreSize - LoadSize -
Offset) * 8;
432 SrcVal =
Builder.CreateLShr(SrcVal,
435 if (LoadSize != StoreSize)
436 SrcVal =
Builder.CreateTruncOrBitCast(SrcVal,
467 unsigned SrcValStoreSize =
468 DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
469 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
470 if (
Offset + LoadSize > SrcValStoreSize) {
471 assert(SrcVal->
isSimple() &&
"Cannot widen volatile/atomic load!");
486 PtrVal =
Builder.CreateBitCast(PtrVal, DestPTy);
497 if (
DL.isBigEndian())
498 RV =
Builder.CreateLShr(RV, (NewLoadSize - SrcValStoreSize) * 8);
510 unsigned SrcValStoreSize =
511 DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
512 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
513 if (
Offset + LoadSize > SrcValStoreSize)
524 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
529 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
532 Value *Val = MSI->getValue();
539 for (
unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
541 if (NumBytesSet * 2 <= LoadSize) {
544 Val =
Builder.CreateOr(Val, ShVal);
552 Val =
Builder.CreateOr(OneElt, ShVal);
562 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
570 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
574 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
575 auto *Val = dyn_cast<ConstantInt>(MSI->getValue());
586 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.
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
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.
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 hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
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)
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...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
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.
void setAlignment(Align Align)
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the access that is being performed.
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
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.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
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.
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.
@ 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 ...
Constant * getConstantLoadValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
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)
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...
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 * 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...
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...
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...
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)
Constant * getConstantStoreValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
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 and pointer casts from the specified value,...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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...
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
uint64_t value() const
This is a hole in the type system and should not be abused.