@@ -668,10 +668,14 @@ STATISTIC(ObjectVisitorArgument,
668668STATISTIC (ObjectVisitorLoad,
669669 " Number of load instructions with unsolved size and offset" );
670670
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) {
672675 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;
675679}
676680
677681ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor (const DataLayout &DL,
@@ -733,8 +737,19 @@ OffsetSpan ObjectSizeOffsetVisitor::computeImpl(Value *V) {
733737 ORT.After = APInt ();
734738 }
735739 // 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;
738753}
739754
740755OffsetSpan ObjectSizeOffsetVisitor::computeValue (Value *V) {
@@ -780,8 +795,9 @@ OffsetSpan ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
780795 if (!isUIntN (IntTyBits, ElemSize.getKnownMinValue ()))
781796 return ObjectSizeOffsetVisitor::unknown ();
782797 APInt Size (IntTyBits, ElemSize.getKnownMinValue ());
798+
783799 if (!I.isArrayAllocation ())
784- return OffsetSpan (Zero, align (Size, I.getAlign ()));
800+ return OffsetSpan (Zero, alignAndCap (Size, I.getAlign ()));
785801
786802 Value *ArraySize = I.getArraySize ();
787803 if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
@@ -791,8 +807,9 @@ OffsetSpan ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
791807
792808 bool Overflow;
793809 Size = Size.umul_ov (NumElems, Overflow);
810+
794811 return Overflow ? ObjectSizeOffsetVisitor::unknown ()
795- : OffsetSpan (Zero, align (Size, I.getAlign ()));
812+ : OffsetSpan (Zero, alignAndCap (Size, I.getAlign ()));
796813 }
797814 return ObjectSizeOffsetVisitor::unknown ();
798815}
@@ -806,12 +823,16 @@ OffsetSpan ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
806823 }
807824
808825 APInt Size (IntTyBits, DL.getTypeAllocSize (MemoryTy));
809- return OffsetSpan (Zero, align (Size, A.getParamAlign ()));
826+ return OffsetSpan (Zero, alignAndCap (Size, A.getParamAlign ()));
810827}
811828
812829OffsetSpan 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 ();
814834 return OffsetSpan (Zero, *Size);
835+ }
815836 return ObjectSizeOffsetVisitor::unknown ();
816837}
817838
@@ -852,7 +873,7 @@ OffsetSpan ObjectSizeOffsetVisitor::visitGlobalVariable(GlobalVariable &GV) {
852873 return ObjectSizeOffsetVisitor::unknown ();
853874
854875 APInt Size (IntTyBits, DL.getTypeAllocSize (GV.getValueType ()));
855- return OffsetSpan (Zero, align (Size, GV.getAlign ()));
876+ return OffsetSpan (Zero, alignAndCap (Size, GV.getAlign ()));
856877}
857878
858879OffsetSpan ObjectSizeOffsetVisitor::visitIntToPtrInst (IntToPtrInst &) {
@@ -944,7 +965,11 @@ OffsetSpan ObjectSizeOffsetVisitor::findLoadOffsetRange(
944965 if (!C)
945966 return Unknown ();
946967
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});
948973 }
949974
950975 return Unknown ();
0 commit comments