7#define DEBUG_TYPE "vncoerce"
21 if (StoredTy == LoadTy)
30 uint64_t StoreSize =
DL.getTypeSizeInBits(StoredTy).getFixedValue();
37 if (StoreSize <
DL.getTypeSizeInBits(LoadTy).getFixedValue())
43 if (StoredNI != LoadNI) {
47 if (
auto *CI = dyn_cast<Constant>(StoredVal))
48 return CI->isNullValue();
50 }
else if (StoredNI && LoadNI &&
60 if (StoredNI && StoreSize !=
DL.getTypeSizeInBits(LoadTy).getFixedValue())
79 "precondition violation - materialization can't fail");
80 if (
auto *
C = dyn_cast<Constant>(StoredVal))
86 uint64_t StoredValSize =
DL.getTypeSizeInBits(StoredValTy).getFixedValue();
87 uint64_t LoadedValSize =
DL.getTypeSizeInBits(LoadedTy).getFixedValue();
90 if (StoredValSize == LoadedValSize) {
97 StoredValTy =
DL.getIntPtrType(StoredValTy);
101 Type *TypeToCastTo = LoadedTy;
103 TypeToCastTo =
DL.getIntPtrType(TypeToCastTo);
105 if (StoredValTy != TypeToCastTo)
113 if (
auto *
C = dyn_cast<ConstantExpr>(StoredVal))
121 assert(StoredValSize >= LoadedValSize &&
122 "canCoerceMustAliasedValueToLoad fail");
126 StoredValTy =
DL.getIntPtrType(StoredValTy);
138 if (
DL.isBigEndian()) {
139 uint64_t ShiftAmt =
DL.getTypeStoreSizeInBits(StoredValTy).getFixedValue() -
140 DL.getTypeStoreSizeInBits(LoadedTy).getFixedValue();
142 StoredVal, ConstantInt::get(StoredVal->
getType(), ShiftAmt));
149 if (LoadedTy != NewIntTy) {
158 if (
auto *
C = dyn_cast<Constant>(StoredVal))
181 int64_t StoreOffset = 0, LoadOffset = 0;
185 if (StoreBase != LoadBase)
188 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue();
190 if ((WriteSizeInBits & 7) | (LoadSize & 7))
192 uint64_t StoreSize = WriteSizeInBits / 8;
199 if (StoreOffset > LoadOffset ||
200 StoreOffset + int64_t(StoreSize) < LoadOffset + int64_t(LoadSize))
205 return LoadOffset - StoreOffset;
248 ConstantInt *SizeCst = dyn_cast<ConstantInt>(
MI->getLength());
255 if (
const auto *memset_inst = dyn_cast<MemSetInst>(
MI)) {
257 auto *CI = dyn_cast<ConstantInt>(memset_inst->getValue());
258 if (!CI || !CI->isZero())
286 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
301 cast<PointerType>(SrcVal->
getType())->getAddressSpace() ==
302 cast<PointerType>(LoadTy)->getAddressSpace()) {
307 (
DL.getTypeSizeInBits(SrcVal->
getType()).getFixedValue() + 7) / 8;
308 uint64_t LoadSize = (
DL.getTypeSizeInBits(LoadTy).getFixedValue() + 7) / 8;
320 if (
DL.isLittleEndian())
323 ShiftAmt = (StoreSize - LoadSize -
Offset) * 8;
326 ConstantInt::get(SrcVal->
getType(), ShiftAmt));
328 if (LoadSize != StoreSize)
338 unsigned SrcValSize =
DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
339 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
350 unsigned SrcValSize =
DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
351 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
363 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
368 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
371 Value *Val = MSI->getValue();
378 for (
unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
380 if (NumBytesSet * 2 <= LoadSize) {
382 Val, ConstantInt::get(Val->
getType(), NumBytesSet * 8));
391 Val = Builder.
CreateOr(OneElt, ShVal);
401 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
409 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
413 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
414 auto *Val = dyn_cast<ConstantInt>(MSI->getValue());
418 Val = ConstantInt::get(Ctx,
APInt::getSplat(LoadSize * 8, Val->getValue()));
425 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...