30 return Base->getPointerAlignment(
DL) >= Alignment;
40 assert(V->getType()->isPointerTy() &&
"Base must be pointer");
47 if (!Visited.
insert(V).second)
73 CtxI, AC, DT, TLI, Visited,
MaxDepth);
78 if (BC->getSrcTy()->isPointerTy())
80 BC->getOperand(0), Alignment,
Size,
DL, CtxI, AC, DT, TLI,
85 if (
const SelectInst *Sel = dyn_cast<SelectInst>(V)) {
87 Size,
DL, CtxI, AC, DT, TLI,
90 Size,
DL, CtxI, AC, DT, TLI,
94 auto IsKnownDeref = [&]() {
95 bool CheckForNonNull, CheckForFreed;
96 if (!
Size.ule(V->getPointerDereferenceableBytes(
DL, CheckForNonNull,
100 if (CheckForNonNull &&
111 auto *
I = dyn_cast<Instruction>(V);
112 if (
I && !isa<AllocaInst>(
I))
116 if (IsKnownDeref()) {
127 if (
const auto *Call = dyn_cast<CallBase>(V)) {
147 APInt KnownDerefBytes(
Size.getBitWidth(), ObjSize);
161 if (
const GCRelocateInst *RelocateInst = dyn_cast<GCRelocateInst>(V))
163 Alignment,
Size,
DL, CtxI, AC, DT,
168 Size,
DL, CtxI, AC, DT, TLI,
176 bool IsAligned = V->getPointerAlignment(
DL) >= Alignment;
178 V, {Attribute::Dereferenceable, Attribute::Alignment}, AC,
182 if (RK.AttrKind == Attribute::Alignment)
183 AlignRK = std::max(AlignRK, RK);
184 if (RK.AttrKind == Attribute::Dereferenceable)
185 DerefRK = std::max(DerefRK, RK);
186 IsAligned |= AlignRK && AlignRK.
ArgValue >= Alignment.
value();
187 if (IsAligned && DerefRK &&
210 return ::isDereferenceableAndAlignedPointer(V, Alignment,
Size,
DL, CtxI, AC,
211 DT, TLI, Visited, 16);
228 APInt AccessSize(
DL.getPointerTypeSizeInBits(V->getType()),
229 DL.getTypeStoreSize(Ty));
265 if (isa<BinaryOperator>(
A) || isa<CastInst>(
A) || isa<PHINode>(
A) ||
266 isa<GetElementPtrInst>(
A))
268 if (cast<Instruction>(
A)->isIdenticalToWhenDefined(BI))
281 APInt EltSize(
DL.getIndexTypeSizeInBits(
Ptr->getType()),
282 DL.getTypeStoreSize(LI->
getType()).getFixedValue());
285 Instruction *HeaderFirstNonPHI = L->getHeader()->getFirstNonPHI();
289 if (L->isLoopInvariant(
Ptr))
291 HeaderFirstNonPHI, AC, &DT);
295 auto *AddRec = dyn_cast<SCEVAddRecExpr>(SE.
getSCEV(
Ptr));
296 if (!AddRec || AddRec->getLoop() != L || !AddRec->isAffine())
298 auto* Step = dyn_cast<SCEVConstant>(AddRec->getStepRecurrence(SE));
308 if (EltSize.
sgt(Step->getAPInt()))
316 APInt AccessSize = TC * Step->getAPInt();
319 "implied by addrec definition");
321 if (
auto *StartS = dyn_cast<SCEVUnknown>(AddRec->getStart())) {
322 Base = StartS->getValue();
323 }
else if (
auto *StartS = dyn_cast<SCEVAddExpr>(AddRec->getStart())) {
325 const auto *
Offset = dyn_cast<SCEVConstant>(StartS->getOperand(0));
326 const auto *NewBase = dyn_cast<SCEVUnknown>(StartS->getOperand(1));
327 if (StartS->getNumOperands() == 2 &&
Offset && NewBase) {
332 if (
Offset->getAPInt().isNegative())
338 if (
Offset->getAPInt().urem(Alignment.
value()) != 0)
340 Base = NewBase->getValue();
341 bool Overflow =
false;
342 AccessSize = AccessSize.
uadd_ov(
Offset->getAPInt(), Overflow);
354 if (EltSize.
urem(Alignment.
value()) != 0)
357 HeaderFirstNonPHI, AC, &DT);
363 return F.hasFnAttribute(Attribute::SanitizeThread) ||
365 F.hasFnAttribute(Attribute::SanitizeAddress) ||
366 F.hasFnAttribute(Attribute::SanitizeHWAddress);
403 if (
Size.getBitWidth() > 64)
417 V = V->stripPointerCasts();
424 if (isa<CallInst>(BBI) && BBI->mayWriteToMemory() &&
425 !isa<LifetimeIntrinsic>(BBI) && !isa<DbgInfoIntrinsic>(BBI))
431 if (
LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
435 if (LI->isVolatile())
437 AccessedPtr = LI->getPointerOperand();
438 AccessedTy = LI->getType();
439 AccessedAlign = LI->getAlign();
440 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(BBI)) {
442 if (SI->isVolatile())
444 AccessedPtr = SI->getPointerOperand();
445 AccessedTy = SI->getValueOperand()->getType();
446 AccessedAlign = SI->getAlign();
450 if (AccessedAlign < Alignment)
454 if (AccessedPtr == V &&
455 TypeSize::isKnownLE(LoadSize,
DL.getTypeStoreSize(AccessedTy)))
459 TypeSize::isKnownLE(LoadSize,
DL.getTypeStoreSize(AccessedTy)))
487 cl::desc(
"Use this to specify the default maximum number of instructions "
488 "to scan backward from a given instruction, when searching for "
489 "available loaded value"));
493 unsigned MaxInstsToScan,
495 unsigned *NumScanedInst) {
497 if (!Load->isUnordered())
502 ScanBB, ScanFrom, MaxInstsToScan, AA, IsLoad,
510 const Value *StorePtr,
513 APInt LoadOffset(
DL.getIndexTypeSizeInBits(LoadPtr->
getType()), 0);
514 APInt StoreOffset(
DL.getIndexTypeSizeInBits(StorePtr->
getType()), 0);
516 DL, LoadOffset,
false);
518 DL, StoreOffset,
false);
519 if (LoadBase != StoreBase)
524 LoadOffset + LoadAccessSize.toRaw());
526 StoreOffset + StoreAccessSize.toRaw());
531 Type *AccessTy,
bool AtLeastAtomic,
536 if (
LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
539 if (LI->isAtomic() < AtLeastAtomic)
556 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
559 if (SI->isAtomic() < AtLeastAtomic)
562 Value *StorePtr = SI->getPointerOperand()->stripPointerCasts();
569 Value *Val = SI->getValueOperand();
574 TypeSize LoadSize =
DL.getTypeSizeInBits(AccessTy);
575 if (TypeSize::isKnownLE(LoadSize, StoreSize))
576 if (
auto *
C = dyn_cast<Constant>(Val))
580 if (
auto *MSI = dyn_cast<MemSetInst>(Inst)) {
586 auto *Val = dyn_cast<ConstantInt>(MSI->getValue());
587 auto *Len = dyn_cast<ConstantInt>(MSI->getLength());
592 Value *Dst = MSI->getDest();
599 TypeSize LoadTypeSize =
DL.getTypeSizeInBits(AccessTy);
605 if ((Len->getValue() * 8).ult(LoadSize))
609 : Val->getValue().trunc(LoadSize);
624 if (MaxInstsToScan == 0)
625 MaxInstsToScan = ~0U;
630 while (ScanFrom != ScanBB->
begin()) {
644 if (MaxInstsToScan-- == 0)
650 AtLeastAtomic,
DL, IsLoadCSE))
654 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
655 Value *StorePtr = SI->getPointerOperand()->stripPointerCasts();
660 if ((isa<AllocaInst>(StrippedPtr) || isa<GlobalVariable>(StrippedPtr)) &&
661 (isa<AllocaInst>(StorePtr) || isa<GlobalVariable>(StorePtr)) &&
662 StrippedPtr != StorePtr)
671 Loc.
Ptr, AccessTy, SI->getPointerOperand(),
672 SI->getValueOperand()->getType(),
DL))
706 unsigned MaxInstsToScan) {
708 Value *StrippedPtr = Load->getPointerOperand()->stripPointerCasts();
710 Type *AccessTy = Load->getType();
711 bool AtLeastAtomic = Load->isAtomic();
713 if (!Load->isUnordered())
722 if (Inst.isDebugOrPseudoInst())
725 if (MaxInstsToScan-- == 0)
729 AtLeastAtomic,
DL, IsLoadCSE);
733 if (Inst.mayWriteToMemory())
756 while (!Worklist.empty() && --Limit) {
757 auto *
User = Worklist.pop_back_val();
760 if (isa<ICmpInst, PtrToIntInst>(
User))
762 if (isa<PHINode, SelectInst>(
User))
777 if (isa<ConstantPointerNull>(To))
779 if (isa<Constant>(To) &&
788 assert(U->getType() == To->
getType() &&
"values must have matching types");
802 if (!
From->getType()->isPointerTy())
813 if (
auto *LI = dyn_cast<LoadInst>(&
I)) {
816 }
else if (
I.mayReadFromMemory() ||
I.mayWriteToMemory() ||
I.mayThrow())
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
@ Available
We know the block is fully available. This is a fixpoint.
static const unsigned MaxDepth
static bool isAligned(const Value *Base, Align Alignment, const DataLayout &DL)
static bool AreEquivalentAddressValues(const Value *A, const Value *B)
Test if A and B will obviously have the same value.
static bool isDereferenceableAndAlignedPointer(const Value *V, Align Alignment, const APInt &Size, const DataLayout &DL, const Instruction *CtxI, AssumptionCache *AC, const DominatorTree *DT, const TargetLibraryInfo *TLI, SmallPtrSetImpl< const Value * > &Visited, unsigned MaxDepth)
Test if V is always a pointer to allocated and suitably aligned memory for a simple load or store.
static bool isPointerAlwaysReplaceable(const Value *From, const Value *To, const DataLayout &DL)
static bool areNonOverlapSameBaseLoadAndStore(const Value *LoadPtr, Type *LoadTy, const Value *StorePtr, Type *StoreTy, const DataLayout &DL)
static bool isPointerUseReplacable(const Use &U)
static Value * getAvailableLoadStore(Instruction *Inst, const Value *Ptr, Type *AccessTy, bool AtLeastAtomic, const DataLayout &DL, bool *IsLoadCSE)
static bool suppressSpeculativeLoadForSanitizers(const Instruction &CtxI)
This file provides utility analysis objects describing memory locations.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
bool sgt(const APInt &RHS) const
Signed greater than comparison.
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
static APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
bool getBoolValue() const
Convert APInt to a boolean value.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
InstListType::iterator iterator
Instruction iterators...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
static bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op.
This is the shared class of boolean and integer constants.
This class represents a range of values.
bool isEmptySet() const
Return true if this set contains no members.
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Represents calls to the gc.relocate intrinsic.
bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
const Function * getFunction() const
Return the function this instruction belongs to.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
An instruction for reading from memory.
Value * getPointerOperand()
Align getAlign() const
Return the alignment of the access that is being performed.
static LocationSize precise(uint64_t Value)
Represents a single loop in the control flow graph.
Representation for a specific memory location.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
const Value * Ptr
The address of the start of the location.
The main scalar evolution driver.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
This class represents the LLVM 'select' instruction.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Provides information about what library functions are available for the current target.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isScalableTy(SmallPtrSetImpl< const Type * > &Visited) const
Return true if this is a type whose size is a known multiple of vscale.
static IntegerType * getInt8Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
self_iterator getIterator()
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
const Value * getArgumentAliasingToReturnedPointer(const CallBase *Call, bool MustPreserveNullness)
This function returns call pointer argument that is considered the same by aliasing rules.
bool isDereferenceableAndAlignedPointer(const Value *V, Type *Ty, Align Alignment, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Returns true if V is always a dereferenceable pointer with alignment greater or equal than requested.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Value * findAvailablePtrLoadStore(const MemoryLocation &Loc, Type *AccessTy, bool AtLeastAtomic, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan, BatchAAResults *AA, bool *IsLoadCSE, unsigned *NumScanedInst)
Scan backwards to see if we have the value of the given pointer available locally within a small numb...
bool mustSuppressSpeculation(const LoadInst &LI)
Return true if speculation of the given load must be suppressed to avoid ordering or interfering with...
Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, BatchAAResults *AA=nullptr, bool *IsLoadCSE=nullptr, unsigned *NumScanedInst=nullptr)
Scan backwards to see if we have the value of the given load available locally within a small number ...
bool isDereferenceableReadOnlyLoop(Loop *L, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Return true if the loop L cannot fault on any iteration and only contains read-only memory accesses.
RetainedKnowledge getKnowledgeForValue(const Value *V, ArrayRef< Attribute::AttrKind > AttrKinds, AssumptionCache *AC=nullptr, function_ref< bool(RetainedKnowledge, Instruction *, const CallBase::BundleOpInfo *)> Filter=[](auto...) { return true;})
Return a valid Knowledge associated to the Value V if its Attribute kind is in AttrKinds and it match...
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
bool canReplacePointersInUseIfEqual(const Use &U, const Value *To, const DataLayout &DL)
bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
bool isModSet(const ModRefInfo MRI)
bool isSafeToLoadUnconditionally(Value *V, Align Alignment, const APInt &Size, const DataLayout &DL, Instruction *ScanFrom, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if we know that executing a load from this value cannot trap.
Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
cl::opt< unsigned > DefMaxInstsToScan
The default number of maximum instructions to scan in the block, used by FindAvailableLoadedValue().
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
const Value * getUnderlyingObjectAggressive(const Value *V)
Like getUnderlyingObject(), but will try harder to find a single underlying object.
bool isDereferenceablePointer(const Value *V, Type *Ty, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if this is always a dereferenceable pointer.
bool isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT, AssumptionCache *AC=nullptr, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Return true if we can prove that the given load (which is assumed to be within the specified loop) wo...
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.
Represent one information held inside an operand bundle of an llvm.assume.