Index: include/llvm/Analysis/ValueTracking.h =================================================================== --- include/llvm/Analysis/ValueTracking.h +++ include/llvm/Analysis/ValueTracking.h @@ -240,7 +240,8 @@ /// pointer. If the context instruction is specified perform context-sensitive /// analysis and return true if the pointer is dereferenceable at the /// specified instruction. - bool isDereferenceablePointer(const Value *V, const DataLayout &DL, + bool isDereferenceablePointer(const Value *V, uint64_t Size, + const DataLayout &DL, const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr); @@ -249,8 +250,8 @@ /// greater or equal than requested. If the context instruction is specified /// performs context-sensitive analysis and returns true if the pointer is /// dereferenceable at the specified instruction. - bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, - const DataLayout &DL, + bool isDereferenceableAndAlignedPointer(const Value *V, uint64_t Size, + unsigned Align, const DataLayout &DL, const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr); Index: lib/Analysis/Loads.cpp =================================================================== --- lib/Analysis/Loads.cpp +++ lib/Analysis/Loads.cpp @@ -66,12 +66,15 @@ Instruction *ScanFrom) { const DataLayout &DL = ScanFrom->getModule()->getDataLayout(); + Type *ElemTy = V->getType()->getPointerElementType(); + uint64_t Size = DL.getTypeStoreSize(ElemTy); + // Zero alignment means that the load has the ABI alignment for the target if (Align == 0) - Align = DL.getABITypeAlignment(V->getType()->getPointerElementType()); + Align = DL.getABITypeAlignment(ElemTy); assert(isPowerOf2_32(Align)); - if (isDereferenceableAndAlignedPointer(V, Align, DL)) + if (isDereferenceableAndAlignedPointer(V, Size, Align, DL)) return true; int64_t ByteOffset = 0; Index: lib/Analysis/MemDerefPrinter.cpp =================================================================== --- lib/Analysis/MemDerefPrinter.cpp +++ lib/Analysis/MemDerefPrinter.cpp @@ -56,9 +56,13 @@ for (auto &I: instructions(F)) { if (LoadInst *LI = dyn_cast(&I)) { Value *PO = LI->getPointerOperand(); - if (isDereferenceablePointer(PO, DL)) + uint64_t Size = DL.getTypeStoreSize(LI->getType()); + unsigned Align = LI->getAlignment(); + if (Align == 0) + Align = DL.getABITypeAlignment(LI->getType()); + if (isDereferenceablePointer(PO, Size, DL)) Deref.push_back(PO); - if (isDereferenceableAndAlignedPointer(PO, LI->getAlignment(), DL)) + if (isDereferenceableAndAlignedPointer(PO, Size, Align, DL)) DerefAndAligned.insert(PO); } } Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3126,12 +3126,11 @@ } static bool isDereferenceableFromAttribute(const Value *BV, APInt Offset, - Type *Ty, const DataLayout &DL, + uint64_t Size, const Instruction *CtxI, const DominatorTree *DT, const TargetLibraryInfo *TLI) { assert(Offset.isNonNegative() && "offset can't be negative"); - assert(Ty->isSized() && "must be sized"); APInt DerefBytes(Offset.getBitWidth(), 0); bool CheckForNonNull = false; @@ -3163,26 +3162,13 @@ } if (DerefBytes.getBoolValue()) - if (DerefBytes.uge(Offset + DL.getTypeStoreSize(Ty))) + if (DerefBytes.uge(Offset + Size)) if (!CheckForNonNull || isKnownNonNullAt(BV, CtxI, DT, TLI)) return true; return false; } -static bool isDereferenceableFromAttribute(const Value *V, const DataLayout &DL, - const Instruction *CtxI, - const DominatorTree *DT, - const TargetLibraryInfo *TLI) { - Type *VTy = V->getType(); - Type *Ty = VTy->getPointerElementType(); - if (!Ty->isSized()) - return false; - - APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0); - return isDereferenceableFromAttribute(V, Offset, Ty, DL, CtxI, DT, TLI); -} - static bool isAligned(const Value *Base, APInt Offset, unsigned Align, const DataLayout &DL) { APInt BaseAlign(Offset.getBitWidth(), getAlignment(Base, DL)); @@ -3210,8 +3196,8 @@ /// 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 DataLayout &DL, - const Instruction *CtxI, const DominatorTree *DT, + const Value *V, uint64_t Size, unsigned Align, + const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, const TargetLibraryInfo *TLI, SmallPtrSetImpl &Visited) { // Note that it is not safe to speculate into a malloc'd region because // malloc may return null. @@ -3230,11 +3216,18 @@ if (const BitCastOperator *BC = dyn_cast(V)) { Type *STy = BC->getSrcTy()->getPointerElementType(), *DTy = BC->getDestTy()->getPointerElementType(); - if (STy->isSized() && DTy->isSized() && - (DL.getTypeStoreSize(STy) >= DL.getTypeStoreSize(DTy)) && - (DL.getABITypeAlignment(STy) >= DL.getABITypeAlignment(DTy))) - return isDereferenceableAndAlignedPointer(BC->getOperand(0), Align, DL, - CtxI, DT, TLI, Visited); + if (STy->isSized() && DTy->isSized()) { + uint64_t SSize = DL.getTypeStoreSize(STy); + uint64_t DSize = DL.getTypeStoreSize(DTy); + unsigned SAlign = DL.getABITypeAlignment(STy); + unsigned DAlign = DL.getABITypeAlignment(DTy); + if (SSize >= DSize && SAlign >= DAlign) { + if (Align == DAlign) + Align = SAlign; + return isDereferenceableAndAlignedPointer(BC->getOperand(0), SSize, Align, + DL, CtxI, DT, TLI, Visited); + } + } } // Global variables which can't collapse to null are ok. @@ -3247,49 +3240,55 @@ if (A->hasByValAttr()) return isAligned(V, Align, DL); - if (isDereferenceableFromAttribute(V, DL, CtxI, DT, TLI)) + Type *VTy = V->getType(); + APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0); + if(isDereferenceableFromAttribute(V, Offset, Size, CtxI, DT, TLI)) return isAligned(V, Align, DL); // For GEPs, determine if the indexing lands within the allocated object. if (const GEPOperator *GEP = dyn_cast(V)) { - Type *Ty = GEP->getResultElementType(); const Value *Base = GEP->getPointerOperand(); // Conservatively require that the base pointer be fully dereferenceable // and aligned. if (!Visited.insert(Base).second) return false; - if (!isDereferenceableAndAlignedPointer(Base, Align, DL, CtxI, DT, TLI, - Visited)) + + Type *BaseType = GEP->getSourceElementType(); + uint64_t BaseSize = DL.getTypeAllocSize(BaseType); + unsigned BaseAlign = DL.getABITypeAlignment(BaseType); + if (BaseAlign < Align) + BaseAlign = Align; + if (!isDereferenceableAndAlignedPointer(Base, BaseSize, BaseAlign, + DL, CtxI, DT, TLI, Visited)) return false; - APInt Offset(DL.getPointerTypeSizeInBits(GEP->getType()), 0); if (!GEP->accumulateConstantOffset(DL, Offset)) return false; // Check if the load is within the bounds of the underlying object // and offset is aligned. - uint64_t LoadSize = DL.getTypeStoreSize(Ty); - Type *BaseType = GEP->getSourceElementType(); assert(isPowerOf2_32(Align) && "must be a power of 2!"); - return (Offset + LoadSize).ule(DL.getTypeAllocSize(BaseType)) && + return (Offset + Size).ule(BaseSize) && !(Offset & APInt(Offset.getBitWidth(), Align-1)); } // For gc.relocate, look through relocations if (const GCRelocateInst *RelocateInst = dyn_cast(V)) return isDereferenceableAndAlignedPointer( - RelocateInst->getDerivedPtr(), Align, DL, CtxI, DT, TLI, Visited); + RelocateInst->getDerivedPtr(), Size, Align, + DL, CtxI, DT, TLI, Visited); if (const AddrSpaceCastInst *ASC = dyn_cast(V)) - return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, DL, - CtxI, DT, TLI, Visited); + return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Size, Align, + DL, CtxI, DT, TLI, Visited); // If we don't know, assume the worst. return false; } -bool llvm::isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, +bool llvm::isDereferenceableAndAlignedPointer(const Value *V, uint64_t Size, + unsigned Align, const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, @@ -3298,33 +3297,25 @@ // 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); + APInt Offset(DL.getTypeStoreSizeInBits(V->getType()), 0); + const Value *BV = V->stripAndAccumulateInBoundsConstantOffsets(DL, Offset); - if (Ty->isSized()) { - APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0); - const Value *BV = V->stripAndAccumulateInBoundsConstantOffsets(DL, Offset); - - if (Offset.isNonNegative()) - if (isDereferenceableFromAttribute(BV, Offset, Ty, DL, CtxI, DT, TLI) && - isAligned(BV, Offset, Align, DL)) - return true; - } + if (Offset.isNonNegative()) + if (isDereferenceableFromAttribute(BV, Offset, Size, CtxI, DT, TLI) && + isAligned(BV, Offset, Align, DL)) + return true; SmallPtrSet Visited; - return ::isDereferenceableAndAlignedPointer(V, Align, DL, CtxI, DT, TLI, - Visited); + return ::isDereferenceableAndAlignedPointer(V, Size, Align, DL, + CtxI, DT, TLI, Visited); } -bool llvm::isDereferenceablePointer(const Value *V, const DataLayout &DL, +bool llvm::isDereferenceablePointer(const Value *V, uint64_t Size, + const DataLayout &DL, const Instruction *CtxI, const DominatorTree *DT, const TargetLibraryInfo *TLI) { - return isDereferenceableAndAlignedPointer(V, 1, DL, CtxI, DT, TLI); + return isDereferenceableAndAlignedPointer(V, Size, 1, DL, CtxI, DT, TLI); } bool llvm::isSafeToSpeculativelyExecute(const Value *V, @@ -3381,8 +3372,12 @@ Attribute::SanitizeAddress)) return false; const DataLayout &DL = LI->getModule()->getDataLayout(); + uint64_t Size = DL.getTypeStoreSize(LI->getType()); + unsigned Align = LI->getAlignment(); + if (Align == 0) + Align = DL.getABITypeAlignment(LI->getType()); return isDereferenceableAndAlignedPointer( - LI->getPointerOperand(), LI->getAlignment(), DL, CtxI, DT, TLI); + LI->getPointerOperand(), Size, Align, DL, CtxI, DT, TLI); } case Instruction::Call: { if (const IntrinsicInst *II = dyn_cast(Inst)) { Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3145,6 +3145,7 @@ SDValue Ptr = getValue(SV); Type *Ty = I.getType(); + uint64_t Size = DAG.getDataLayout().getTypeStoreSize(Ty); bool isVolatile = I.isVolatile(); bool isNonTemporal = I.getMetadata(LLVMContext::MD_nontemporal) != nullptr; @@ -3158,7 +3159,7 @@ // throughout the function's lifetime. bool isInvariant = I.getMetadata(LLVMContext::MD_invariant_load) != nullptr && - isDereferenceablePointer(SV, DAG.getDataLayout()); + isDereferenceablePointer(SV, Size, DAG.getDataLayout()); unsigned Alignment = I.getAlignment(); AAMDNodes AAInfo; @@ -3178,8 +3179,7 @@ if (isVolatile || NumValues > MaxParallelChains) // Serialize volatile loads with other side effects. Root = getRoot(); - else if (AA->pointsToConstantMemory(MemoryLocation( - SV, DAG.getDataLayout().getTypeStoreSize(Ty), AAInfo))) { + else if (AA->pointsToConstantMemory(MemoryLocation(SV, Size, AAInfo))) { // Do not serialize (non-volatile) loads of constant memory with anything. Root = DAG.getEntryNode(); ConstantMemory = true; Index: lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- lib/Transforms/IPO/ArgumentPromotion.cpp +++ lib/Transforms/IPO/ArgumentPromotion.cpp @@ -85,7 +85,7 @@ bool isDenselyPacked(Type *type, const DataLayout &DL); bool canPaddingBeAccessed(Argument *Arg); CallGraphNode *PromoteArguments(CallGraphNode *CGN); - bool isSafeToPromoteArgument(Argument *Arg, bool isByVal, + bool isSafeToPromoteArgument(Argument *Arg, Type *ElemTy, bool isByVal, AAResults &AAR) const; CallGraphNode *DoPromotion(Function *F, SmallPtrSetImpl &ArgsToPromote, @@ -328,7 +328,7 @@ } // Otherwise, see if we can promote the pointer to its value. - if (isSafeToPromoteArgument(PtrArg, PtrArg->hasByValOrInAllocaAttr(), AAR)) + if (isSafeToPromoteArgument(PtrArg, AgTy, PtrArg->hasByValOrInAllocaAttr(), AAR)) ArgsToPromote.insert(PtrArg); } @@ -341,11 +341,12 @@ /// AllCallersPassInValidPointerForArgument - Return true if we can prove that /// all callees pass in a valid pointer for the specified function argument. -static bool AllCallersPassInValidPointerForArgument(Argument *Arg) { +static bool AllCallersPassInValidPointerForArgument(Argument *Arg, Type *ElemTy) { Function *Callee = Arg->getParent(); const DataLayout &DL = Callee->getParent()->getDataLayout(); unsigned ArgNo = Arg->getArgNo(); + uint64_t Size = DL.getTypeStoreSize(ElemTy); // Look at all call sites of the function. At this pointer we know we only // have direct callees. @@ -353,7 +354,7 @@ CallSite CS(U); assert(CS && "Should only have direct calls!"); - if (!isDereferenceablePointer(CS.getArgument(ArgNo), DL)) + if (!isDereferenceablePointer(CS.getArgument(ArgNo), Size, DL)) return false; } return true; @@ -428,7 +429,7 @@ /// This method limits promotion of aggregates to only promote up to three /// elements of the aggregate in order to avoid exploding the number of /// arguments passed in. -bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, +bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, Type *ElemTy, bool isByValOrInAlloca, AAResults &AAR) const { typedef std::set GEPIndicesSet; @@ -462,7 +463,7 @@ GEPIndicesSet ToPromote; // If the pointer is always valid, any load with first index 0 is valid. - if (isByValOrInAlloca || AllCallersPassInValidPointerForArgument(Arg)) + if (isByValOrInAlloca || AllCallersPassInValidPointerForArgument(Arg, ElemTy)) SafeToUnconditionallyLoad.insert(IndicesVector(1, 0)); // First, iterate the entry block and mark loads of (geps of) arguments as @@ -518,7 +519,7 @@ // TODO: This runs the above loop over and over again for dead GEPs // Couldn't we just do increment the UI iterator earlier and erase the // use? - return isSafeToPromoteArgument(Arg, isByValOrInAlloca, AAR); + return isSafeToPromoteArgument(Arg, ElemTy, isByValOrInAlloca, AAR); } // Ensure that all of the indices are constants. Index: lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCalls.cpp +++ lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1776,7 +1776,7 @@ II->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull); // isDereferenceablePointer -> deref attribute - if (isDereferenceablePointer(DerivedPtr, DL)) { + if (isDereferenceablePointer(DerivedPtr, 1, DL)) { if (Argument *A = dyn_cast(DerivedPtr)) { uint64_t Bytes = A->getDereferenceableBytes(); II->addDereferenceableAttr(AttributeSet::ReturnIndex, Bytes);