1616#include " llvm/ADT/STLExtras.h"
1717#include " llvm/ADT/Statistic.h"
1818#include " llvm/Analysis/AliasAnalysis.h"
19+ #include " llvm/Analysis/AssumptionCache.h"
1920#include " llvm/Analysis/TargetFolder.h"
2021#include " llvm/Analysis/TargetLibraryInfo.h"
2122#include " llvm/Analysis/Utils/Local.h"
2526#include " llvm/IR/Constants.h"
2627#include " llvm/IR/DataLayout.h"
2728#include " llvm/IR/DerivedTypes.h"
29+ #include " llvm/IR/Dominators.h"
2830#include " llvm/IR/Function.h"
2931#include " llvm/IR/GlobalAlias.h"
3032#include " llvm/IR/GlobalVariable.h"
@@ -590,19 +592,31 @@ Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
590592 const TargetLibraryInfo *TLI,
591593 bool MustSucceed) {
592594 return lowerObjectSizeCall (ObjectSize, DL, TLI, /* AAResults=*/ nullptr ,
593- MustSucceed);
595+ /* DT=*/ nullptr ,
596+ /* AC=*/ nullptr , MustSucceed);
594597}
595598
596599Value *llvm::lowerObjectSizeCall (
597600 IntrinsicInst *ObjectSize, const DataLayout &DL,
598601 const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
599602 SmallVectorImpl<Instruction *> *InsertedInstructions) {
603+ return lowerObjectSizeCall (ObjectSize, DL, TLI, AA, /* DT=*/ nullptr ,
604+ /* AC=*/ nullptr , MustSucceed, InsertedInstructions);
605+ }
606+
607+ Value *llvm::lowerObjectSizeCall (
608+ IntrinsicInst *ObjectSize, const DataLayout &DL,
609+ const TargetLibraryInfo *TLI, AAResults *AA, DominatorTree *DT,
610+ AssumptionCache *AC, bool MustSucceed,
611+ SmallVectorImpl<Instruction *> *InsertedInstructions) {
600612 assert (ObjectSize->getIntrinsicID () == Intrinsic::objectsize &&
601613 " ObjectSize must be a call to llvm.objectsize!" );
602614
603615 bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand (1 ))->isZero ();
604616 ObjectSizeOpts EvalOptions;
605617 EvalOptions.AA = AA;
618+ EvalOptions.DT = DT;
619+ EvalOptions.AC = AC;
606620
607621 // Unless we have to fold this to something, try to be as accurate as
608622 // possible.
@@ -716,7 +730,6 @@ OffsetSpan ObjectSizeOffsetVisitor::computeImpl(Value *V) {
716730 // value that is passed to computeImpl.
717731 IntTyBits = DL.getIndexTypeSizeInBits (V->getType ());
718732 Zero = APInt::getZero (IntTyBits);
719-
720733 OffsetSpan ORT = computeValue (V);
721734
722735 bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
@@ -794,6 +807,19 @@ OffsetSpan ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
794807 Size = Size.umul_ov (NumElems, Overflow);
795808 return Overflow ? ObjectSizeOffsetVisitor::unknown ()
796809 : OffsetSpan (Zero, align (Size, I.getAlign ()));
810+ } else {
811+ ConstantRange CR = computeConstantRange (ArraySize, /* ForSigned*/ false ,
812+ /* UseInstrInfo*/ true ,
813+ /* AssumptionCache=*/ Options.AC ,
814+ /* CtxtI=*/ &I, /* DT=*/ Options.DT );
815+ if (CR.isFullSet ())
816+ return ObjectSizeOffsetVisitor::unknown ();
817+ APInt Bound;
818+ if (Options.EvalMode == ObjectSizeOpts::Mode::Max)
819+ Bound = CR.getUnsignedMax ();
820+ else
821+ Bound = CR.getUnsignedMin ();
822+ return OffsetSpan (Zero, align (Bound, I.getAlign ()));
797823 }
798824 return ObjectSizeOffsetVisitor::unknown ();
799825}
@@ -811,7 +837,23 @@ OffsetSpan ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
811837}
812838
813839OffsetSpan ObjectSizeOffsetVisitor::visitCallBase (CallBase &CB) {
814- if (std::optional<APInt> Size = getAllocSize (&CB, TLI))
840+ if (std::optional<APInt> Size =
841+ getAllocSize (&CB, TLI, [&CB, this ](const Value *V) -> const Value * {
842+ if (!V->getType ()->isIntegerTy ())
843+ return V;
844+ ConstantRange CR = computeConstantRange (
845+ V, /* ForSigned*/ false , /* UseInstrInfo*/ true ,
846+ /* AssumptionCache=*/ Options.AC ,
847+ /* CtxtI=*/ &CB, /* DT=*/ Options.DT );
848+ if (CR.isFullSet ())
849+ return V;
850+ APInt Bound;
851+ if (Options.EvalMode == ObjectSizeOpts::Mode::Max)
852+ Bound = CR.getUnsignedMax ();
853+ else
854+ Bound = CR.getUnsignedMin ();
855+ return ConstantInt::get (V->getType (), Bound);
856+ }))
815857 return OffsetSpan (Zero, *Size);
816858 return ObjectSizeOffsetVisitor::unknown ();
817859}
@@ -856,6 +898,42 @@ OffsetSpan ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) {
856898 return OffsetSpan (Zero, align (Size, GV.getAlign ()));
857899}
858900
901+ OffsetSpan ObjectSizeOffsetVisitor::visitGetElementPtr (GetElementPtrInst &GEP) {
902+ OffsetSpan PtrData = computeImpl (GEP.getPointerOperand ());
903+ if (!PtrData.bothKnown ())
904+ return ObjectSizeOffsetVisitor::unknown ();
905+
906+ if (Options.EvalMode == ObjectSizeOpts::Mode::Min ||
907+ Options.EvalMode == ObjectSizeOpts::Mode::Max) {
908+ unsigned BitWidth = PtrData.After .getBitWidth ();
909+ APInt ConstantOffset = Zero;
910+ SmallMapVector<Value *, APInt, 4 > VariableOffsets;
911+ if (!GEP.collectOffset (DL, BitWidth, VariableOffsets, ConstantOffset))
912+ return ObjectSizeOffsetVisitor::unknown ();
913+
914+ ConstantRange AccumulatedRange = ConstantOffset;
915+ for (auto const &VO : VariableOffsets) {
916+ ConstantRange CR = computeConstantRange (
917+ VO.first , /* ForSigned*/ true , /* UseInstrInfo*/ true ,
918+ /* AssumptionCache=*/ Options.AC ,
919+ /* CtxtI=*/ &GEP, /* DT=*/ Options.DT );
920+ if (CR.isFullSet ())
921+ return ObjectSizeOffsetVisitor::unknown ();
922+
923+ AccumulatedRange = AccumulatedRange.add (CR.multiply (VO.second ));
924+ }
925+
926+ APInt Bound;
927+ if (Options.EvalMode == ObjectSizeOpts::Mode::Min)
928+ Bound = AccumulatedRange.getSignedMax ();
929+ else
930+ Bound = AccumulatedRange.getSignedMin ();
931+
932+ return {PtrData.Before + Bound, PtrData.After - Bound};
933+ }
934+ return ObjectSizeOffsetVisitor::unknown ();
935+ }
936+
859937OffsetSpan ObjectSizeOffsetVisitor::visitIntToPtrInst (IntToPtrInst &) {
860938 // clueless
861939 return ObjectSizeOffsetVisitor::unknown ();
0 commit comments