7#define DEBUG_TYPE "vncoerce"
21 if (StoredTy == LoadTy)
24 if (isa<ScalableVectorType>(StoredTy) && isa<ScalableVectorType>(LoadTy) &&
25 DL.getTypeSizeInBits(StoredTy) ==
DL.getTypeSizeInBits(LoadTy))
34 uint64_t StoreSize =
DL.getTypeSizeInBits(StoredTy).getFixedValue();
41 if (StoreSize <
DL.getTypeSizeInBits(LoadTy).getFixedValue())
47 if (StoredNI != LoadNI) {
51 if (
auto *CI = dyn_cast<Constant>(StoredVal))
52 return CI->isNullValue();
54 }
else if (StoredNI && LoadNI &&
64 if (StoredNI && StoreSize !=
DL.getTypeSizeInBits(LoadTy).getFixedValue())
83 "precondition violation - materialization can't fail");
84 if (
auto *
C = dyn_cast<Constant>(StoredVal))
90 TypeSize StoredValSize =
DL.getTypeSizeInBits(StoredValTy);
91 TypeSize LoadedValSize =
DL.getTypeSizeInBits(LoadedTy);
94 if (StoredValSize == LoadedValSize) {
101 StoredValTy =
DL.getIntPtrType(StoredValTy);
105 Type *TypeToCastTo = LoadedTy;
107 TypeToCastTo =
DL.getIntPtrType(TypeToCastTo);
109 if (StoredValTy != TypeToCastTo)
117 if (
auto *
C = dyn_cast<ConstantExpr>(StoredVal))
127 "canCoerceMustAliasedValueToLoad fail");
131 StoredValTy =
DL.getIntPtrType(StoredValTy);
143 if (
DL.isBigEndian()) {
144 uint64_t ShiftAmt =
DL.getTypeStoreSizeInBits(StoredValTy).getFixedValue() -
145 DL.getTypeStoreSizeInBits(LoadedTy).getFixedValue();
147 StoredVal, ConstantInt::get(StoredVal->
getType(), ShiftAmt));
154 if (LoadedTy != NewIntTy) {
163 if (
auto *
C = dyn_cast<Constant>(StoredVal))
186 int64_t StoreOffset = 0, LoadOffset = 0;
190 if (StoreBase != LoadBase)
193 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue();
195 if ((WriteSizeInBits & 7) | (LoadSize & 7))
197 uint64_t StoreSize = WriteSizeInBits / 8;
204 if (StoreOffset > LoadOffset ||
205 StoreOffset + int64_t(StoreSize) < LoadOffset + int64_t(LoadSize))
210 return LoadOffset - StoreOffset;
253 ConstantInt *SizeCst = dyn_cast<ConstantInt>(
MI->getLength());
260 if (
const auto *memset_inst = dyn_cast<MemSetInst>(
MI)) {
262 auto *CI = dyn_cast<ConstantInt>(memset_inst->getValue());
263 if (!CI || !CI->isZero())
291 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
306 cast<PointerType>(SrcVal->
getType())->getAddressSpace() ==
307 cast<PointerType>(LoadTy)->getAddressSpace()) {
313 if (isa<ScalableVectorType>(LoadTy)) {
314 assert(
Offset == 0 &&
"Expected a zero offset for scalable types");
319 (
DL.getTypeSizeInBits(SrcVal->
getType()).getFixedValue() + 7) / 8;
320 uint64_t LoadSize = (
DL.getTypeSizeInBits(LoadTy).getFixedValue() + 7) / 8;
332 if (
DL.isLittleEndian())
335 ShiftAmt = (StoreSize - LoadSize -
Offset) * 8;
338 ConstantInt::get(SrcVal->
getType(), ShiftAmt));
340 if (LoadSize != StoreSize)
350 TypeSize LoadSize =
DL.getTypeStoreSize(LoadTy);
353 "Expected Offset + LoadSize <= SrcValSize");
356 "Expected scalable type sizes to match");
366 unsigned SrcValSize =
DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
367 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
379 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
384 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
387 Value *Val = MSI->getValue();
394 for (
unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
396 if (NumBytesSet * 2 <= LoadSize) {
398 Val, ConstantInt::get(Val->
getType(), NumBytesSet * 8));
407 Val = Builder.
CreateOr(OneElt, ShVal);
417 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
425 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
429 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
430 auto *Val = dyn_cast<ConstantInt>(MSI->getValue());
434 Val = ConstantInt::get(Ctx,
APInt::getSplat(LoadSize * 8, Val->getValue()));
441 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.
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
@ 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...