16
16
#include " llvm/ADT/STLExtras.h"
17
17
#include " llvm/ADT/Statistic.h"
18
18
#include " llvm/Analysis/AliasAnalysis.h"
19
+ #include " llvm/Analysis/AssumptionCache.h"
19
20
#include " llvm/Analysis/TargetFolder.h"
20
21
#include " llvm/Analysis/TargetLibraryInfo.h"
21
22
#include " llvm/Analysis/Utils/Local.h"
25
26
#include " llvm/IR/Constants.h"
26
27
#include " llvm/IR/DataLayout.h"
27
28
#include " llvm/IR/DerivedTypes.h"
29
+ #include " llvm/IR/Dominators.h"
28
30
#include " llvm/IR/Function.h"
29
31
#include " llvm/IR/GlobalAlias.h"
30
32
#include " llvm/IR/GlobalVariable.h"
@@ -590,19 +592,31 @@ Value *llvm::lowerObjectSizeCall(IntrinsicInst *ObjectSize,
590
592
const TargetLibraryInfo *TLI,
591
593
bool MustSucceed) {
592
594
return lowerObjectSizeCall (ObjectSize, DL, TLI, /* AAResults=*/ nullptr ,
593
- MustSucceed);
595
+ /* DT=*/ nullptr ,
596
+ /* AC=*/ nullptr , MustSucceed);
594
597
}
595
598
596
599
Value *llvm::lowerObjectSizeCall (
597
600
IntrinsicInst *ObjectSize, const DataLayout &DL,
598
601
const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
599
602
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) {
600
612
assert (ObjectSize->getIntrinsicID () == Intrinsic::objectsize &&
601
613
" ObjectSize must be a call to llvm.objectsize!" );
602
614
603
615
bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand (1 ))->isZero ();
604
616
ObjectSizeOpts EvalOptions;
605
617
EvalOptions.AA = AA;
618
+ EvalOptions.DT = DT;
619
+ EvalOptions.AC = AC;
606
620
607
621
// Unless we have to fold this to something, try to be as accurate as
608
622
// possible.
@@ -716,7 +730,6 @@ OffsetSpan ObjectSizeOffsetVisitor::computeImpl(Value *V) {
716
730
// value that is passed to computeImpl.
717
731
IntTyBits = DL.getIndexTypeSizeInBits (V->getType ());
718
732
Zero = APInt::getZero (IntTyBits);
719
-
720
733
OffsetSpan ORT = computeValue (V);
721
734
722
735
bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
@@ -794,6 +807,19 @@ OffsetSpan ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
794
807
Size = Size .umul_ov (NumElems, Overflow);
795
808
return Overflow ? ObjectSizeOffsetVisitor::unknown ()
796
809
: 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 ()));
797
823
}
798
824
return ObjectSizeOffsetVisitor::unknown ();
799
825
}
@@ -811,7 +837,23 @@ OffsetSpan ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
811
837
}
812
838
813
839
OffsetSpan 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
+ }))
815
857
return OffsetSpan (Zero, *Size );
816
858
return ObjectSizeOffsetVisitor::unknown ();
817
859
}
@@ -856,6 +898,42 @@ OffsetSpan ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) {
856
898
return OffsetSpan (Zero, align (Size , GV.getAlign ()));
857
899
}
858
900
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
+
859
937
OffsetSpan ObjectSizeOffsetVisitor::visitIntToPtrInst (IntToPtrInst &) {
860
938
// clueless
861
939
return ObjectSizeOffsetVisitor::unknown ();
0 commit comments