bool llvm::isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT) { // When dereferenceability information is provided by a dereferenceable // attribute, we know exactly how many bytes are dereferenceable. If we can // determine the exact offset to the attributed variable, we can use that // information here. Type *VTy = V->getType(); Type *Ty = VTy->getPointerElementType(); // Require ABI alignment for loads without alignment specification if (Align == 0) Align = DL.getABITypeAlignment(Ty); if (!Ty->isSized()) return false; SmallPtrSet<const Value *, 32> Visited; return ::isDereferenceableAndAlignedPointer( V, Align, APInt(DL.getIndexTypeSizeInBits(VTy), DL.getTypeStoreSize(Ty)), DL, CtxI, DT, Visited); }
/// Test if V is always a pointer to allocated and suitably aligned memory for /// a simple load or store. static bool isDereferenceableAndAlignedPointer( const Value *V, unsigned Align, const APInt &Size, const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, SmallPtrSetImpl<const Value *> &Visited) { // Already visited? Bail out, we've likely hit unreachable code. if (!Visited.insert(V).second) return false; // Note that it is not safe to speculate into a malloc'd region because // malloc may return null. // bitcast instructions are no-ops as far as dereferenceability is concerned. if (const BitCastOperator *BC = dyn_cast<BitCastOperator>(V)) return isDereferenceableAndAlignedPointer(BC->getOperand(0), Align, Size, DL, CtxI, DT, Visited); bool CheckForNonNull = false; APInt KnownDerefBytes(Size.getBitWidth(), V->getPointerDereferenceableBytes(DL, CheckForNonNull)); if (KnownDerefBytes.getBoolValue()) { if (KnownDerefBytes.uge(Size)) if (!CheckForNonNull || isKnownNonZero(V, DL, 0, nullptr, CtxI, DT)) return isAligned(V, Align, DL); } // For GEPs, determine if the indexing lands within the allocated object. if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { const Value *Base = GEP->getPointerOperand(); APInt Offset(DL.getIndexTypeSizeInBits(GEP->getType()), 0); if (!GEP->accumulateConstantOffset(DL, Offset) || Offset.isNegative() || !Offset.urem(APInt(Offset.getBitWidth(), Align)).isMinValue()) return false; // If the base pointer is dereferenceable for Offset+Size bytes, then the // GEP (== Base + Offset) is dereferenceable for Size bytes. If the base // pointer is aligned to Align bytes, and the Offset is divisible by Align // then the GEP (== Base + Offset == k_0 * Align + k_1 * Align) is also // aligned to Align bytes. // Offset and Size may have different bit widths if we have visited an // addrspacecast, so we can't do arithmetic directly on the APInt values. return isDereferenceableAndAlignedPointer( Base, Align, Offset + Size.sextOrTrunc(Offset.getBitWidth()), DL, CtxI, DT, Visited); } // For gc.relocate, look through relocations if (const GCRelocateInst *RelocateInst = dyn_cast<GCRelocateInst>(V)) return isDereferenceableAndAlignedPointer( RelocateInst->getDerivedPtr(), Align, Size, DL, CtxI, DT, Visited); if (const AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(V)) return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, Size, DL, CtxI, DT, Visited); if (auto CS = ImmutableCallSite(V)) if (auto *RP = getArgumentAliasingToReturnedPointer(CS)) return isDereferenceableAndAlignedPointer(RP, Align, Size, DL, CtxI, DT, Visited); // If we don't know, assume the worst. return false; }