@@ -668,10 +668,14 @@ STATISTIC(ObjectVisitorArgument,
668
668
STATISTIC (ObjectVisitorLoad,
669
669
" Number of load instructions with unsolved size and offset" );
670
670
671
- APInt ObjectSizeOffsetVisitor::align (APInt Size, MaybeAlign Alignment) {
671
+ // / Align \p Size according to \p Alignment. If \p Size is greater than
672
+ // / getSignedMaxValue(), set it as unknown as we can only represent signed value
673
+ // / in OffsetSpan.
674
+ APInt ObjectSizeOffsetVisitor::alignAndCap (APInt Size, MaybeAlign Alignment) {
672
675
if (Options.RoundToAlign && Alignment)
673
- return APInt (IntTyBits, alignTo (Size.getZExtValue (), *Alignment));
674
- return Size;
676
+ Size = APInt (IntTyBits, alignTo (Size.getZExtValue (), *Alignment));
677
+
678
+ return Size.isNegative () ? APInt () : Size;
675
679
}
676
680
677
681
ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor (const DataLayout &DL,
@@ -733,8 +737,19 @@ OffsetSpan ObjectSizeOffsetVisitor::computeImpl(Value *V) {
733
737
ORT.After = APInt ();
734
738
}
735
739
// If the computed bound is "unknown" we cannot add the stripped offset.
736
- return {(ORT.knownBefore () ? ORT.Before + Offset : ORT.Before ),
737
- (ORT.knownAfter () ? ORT.After - Offset : ORT.After )};
740
+ if (ORT.knownBefore ()) {
741
+ bool Overflow;
742
+ ORT.Before = ORT.Before .sadd_ov (Offset, Overflow);
743
+ if (Overflow)
744
+ ORT.Before = APInt ();
745
+ }
746
+ if (ORT.knownAfter ()) {
747
+ bool Overflow;
748
+ ORT.After = ORT.After .ssub_ov (Offset, Overflow);
749
+ if (Overflow)
750
+ ORT.After = APInt ();
751
+ }
752
+ return ORT;
738
753
}
739
754
740
755
OffsetSpan ObjectSizeOffsetVisitor::computeValue (Value *V) {
@@ -780,8 +795,9 @@ OffsetSpan ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
780
795
if (!isUIntN (IntTyBits, ElemSize.getKnownMinValue ()))
781
796
return ObjectSizeOffsetVisitor::unknown ();
782
797
APInt Size (IntTyBits, ElemSize.getKnownMinValue ());
798
+
783
799
if (!I.isArrayAllocation ())
784
- return OffsetSpan (Zero, align (Size, I.getAlign ()));
800
+ return OffsetSpan (Zero, alignAndCap (Size, I.getAlign ()));
785
801
786
802
Value *ArraySize = I.getArraySize ();
787
803
if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
@@ -791,8 +807,9 @@ OffsetSpan ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
791
807
792
808
bool Overflow;
793
809
Size = Size.umul_ov (NumElems, Overflow);
810
+
794
811
return Overflow ? ObjectSizeOffsetVisitor::unknown ()
795
- : OffsetSpan (Zero, align (Size, I.getAlign ()));
812
+ : OffsetSpan (Zero, alignAndCap (Size, I.getAlign ()));
796
813
}
797
814
return ObjectSizeOffsetVisitor::unknown ();
798
815
}
@@ -806,12 +823,16 @@ OffsetSpan ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
806
823
}
807
824
808
825
APInt Size (IntTyBits, DL.getTypeAllocSize (MemoryTy));
809
- return OffsetSpan (Zero, align (Size, A.getParamAlign ()));
826
+ return OffsetSpan (Zero, alignAndCap (Size, A.getParamAlign ()));
810
827
}
811
828
812
829
OffsetSpan ObjectSizeOffsetVisitor::visitCallBase (CallBase &CB) {
813
- if (std::optional<APInt> Size = getAllocSize (&CB, TLI))
830
+ if (std::optional<APInt> Size = getAllocSize (&CB, TLI)) {
831
+ // Very large unsigned value cannot be represented as OffsetSpan.
832
+ if (Size->isNegative ())
833
+ return ObjectSizeOffsetVisitor::unknown ();
814
834
return OffsetSpan (Zero, *Size);
835
+ }
815
836
return ObjectSizeOffsetVisitor::unknown ();
816
837
}
817
838
@@ -852,7 +873,7 @@ OffsetSpan ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) {
852
873
return ObjectSizeOffsetVisitor::unknown ();
853
874
854
875
APInt Size (IntTyBits, DL.getTypeAllocSize (GV.getValueType ()));
855
- return OffsetSpan (Zero, align (Size, GV.getAlign ()));
876
+ return OffsetSpan (Zero, alignAndCap (Size, GV.getAlign ()));
856
877
}
857
878
858
879
OffsetSpan ObjectSizeOffsetVisitor::visitIntToPtrInst (IntToPtrInst &) {
@@ -944,7 +965,11 @@ OffsetSpan ObjectSizeOffsetVisitor::findLoadOffsetRange(
944
965
if (!C)
945
966
return Unknown ();
946
967
947
- return Known ({APInt (C->getValue ().getBitWidth (), 0 ), C->getValue ()});
968
+ APInt CSize = C->getValue ();
969
+ if (CSize.isNegative ())
970
+ return Unknown ();
971
+
972
+ return Known ({APInt (CSize.getBitWidth (), 0 ), CSize});
948
973
}
949
974
950
975
return Unknown ();
0 commit comments