7#define DEBUG_TYPE "vncoerce"
20 if (StoredTy == LoadTy)
24 TypeSize MinStoreSize =
DL.getTypeSizeInBits(StoredTy);
25 TypeSize LoadSize =
DL.getTypeSizeInBits(LoadTy);
26 if (isa<ScalableVectorType>(StoredTy) && isa<ScalableVectorType>(LoadTy) &&
27 MinStoreSize == LoadSize)
33 if (isa<ScalableVectorType>(StoredTy) && isa<FixedVectorType>(LoadTy)) {
39 const auto &Attrs =
F->getAttributes().getFnAttrs();
40 unsigned MinVScale = Attrs.getVScaleRangeMin();
59 if (StoredNI != LoadNI) {
63 if (
auto *CI = dyn_cast<Constant>(StoredVal))
64 return CI->isNullValue();
66 }
else if (StoredNI && LoadNI &&
75 if (StoredNI && (StoredTy->
isScalableTy() || MinStoreSize != LoadSize))
93 "precondition violation - materialization can't fail");
95 if (
auto *
C = dyn_cast<Constant>(StoredVal))
103 if (isa<ScalableVectorType>(StoredVal->
getType()) &&
104 isa<FixedVectorType>(LoadedTy)) {
109 TypeSize StoredValSize =
DL.getTypeSizeInBits(StoredValTy);
110 TypeSize LoadedValSize =
DL.getTypeSizeInBits(LoadedTy);
113 if (StoredValSize == LoadedValSize) {
120 StoredValTy =
DL.getIntPtrType(StoredValTy);
124 Type *TypeToCastTo = LoadedTy;
126 TypeToCastTo =
DL.getIntPtrType(TypeToCastTo);
128 if (StoredValTy != TypeToCastTo)
136 if (
auto *
C = dyn_cast<ConstantExpr>(StoredVal))
146 "canCoerceMustAliasedValueToLoad fail");
150 StoredValTy =
DL.getIntPtrType(StoredValTy);
162 if (
DL.isBigEndian()) {
163 uint64_t ShiftAmt =
DL.getTypeStoreSizeInBits(StoredValTy).getFixedValue() -
164 DL.getTypeStoreSizeInBits(LoadedTy).getFixedValue();
166 StoredVal, ConstantInt::get(StoredVal->
getType(), ShiftAmt));
173 if (LoadedTy != NewIntTy) {
182 if (
auto *
C = dyn_cast<Constant>(StoredVal))
205 int64_t StoreOffset = 0, LoadOffset = 0;
209 if (StoreBase != LoadBase)
212 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue();
214 if ((WriteSizeInBits & 7) | (LoadSize & 7))
216 uint64_t StoreSize = WriteSizeInBits / 8;
223 if (StoreOffset > LoadOffset ||
224 StoreOffset + int64_t(StoreSize) < LoadOffset + int64_t(LoadSize))
229 return LoadOffset - StoreOffset;
272 ConstantInt *SizeCst = dyn_cast<ConstantInt>(
MI->getLength());
279 if (
const auto *memset_inst = dyn_cast<MemSetInst>(
MI)) {
281 auto *CI = dyn_cast<ConstantInt>(memset_inst->getValue());
282 if (!CI || !CI->isZero())
310 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
325 cast<PointerType>(SrcVal->
getType())->getAddressSpace() ==
326 cast<PointerType>(LoadTy)->getAddressSpace()) {
332 if (isa<ScalableVectorType>(LoadTy)) {
333 assert(
Offset == 0 &&
"Expected a zero offset for scalable types");
340 if (isa<ScalableVectorType>(SrcVal->
getType()) &&
341 isa<FixedVectorType>(LoadTy)) {
348 (
DL.getTypeSizeInBits(SrcVal->
getType()).getFixedValue() + 7) / 8;
349 uint64_t LoadSize = (
DL.getTypeSizeInBits(LoadTy).getFixedValue() + 7) / 8;
361 if (
DL.isLittleEndian())
364 ShiftAmt = (StoreSize - LoadSize -
Offset) * 8;
367 ConstantInt::get(SrcVal->
getType(), ShiftAmt));
369 if (LoadSize != StoreSize)
380 TypeSize LoadSize =
DL.getTypeStoreSize(LoadTy);
384 F->getAttributes().getFnAttrs().getVScaleRangeMin());
386 "Expected Offset + LoadSize <= SrcValSize");
389 "Expected offset of zero and LoadSize <= SrcValSize");
399 unsigned SrcValSize =
DL.getTypeStoreSize(SrcVal->
getType()).getFixedValue();
400 unsigned LoadSize =
DL.getTypeStoreSize(LoadTy).getFixedValue();
412 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
417 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
420 Value *Val = MSI->getValue();
427 for (
unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {
429 if (NumBytesSet * 2 <= LoadSize) {
431 Val, ConstantInt::get(Val->
getType(), NumBytesSet * 8));
440 Val = Builder.
CreateOr(OneElt, ShVal);
451 unsigned IndexSize =
DL.getIndexTypeSizeInBits(Src->getType());
459 uint64_t LoadSize =
DL.getTypeSizeInBits(LoadTy).getFixedValue() / 8;
463 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {
464 auto *Val = dyn_cast<ConstantInt>(MSI->getValue());
468 Val = ConstantInt::get(Ctx,
APInt::getSplat(LoadSize * 8, Val->getValue()));
475 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)
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
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...
const Function * getFunction() const
Return the function this instruction belongs to.
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()
static constexpr TypeSize getFixed(ScalarTy ExactSize)
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.
bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
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.
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
@ 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 ...
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)
Value * coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, IRBuilderBase &IRB, Function *F)
If we saw a store of a value to memory, and then a load from a must-aliased pointer of a different ty...
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)
Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, Function *F)
If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...
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, Function *F)
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...