@@ -866,8 +866,6 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
866
866
ArrayRef<Constant *> Ops,
867
867
const DataLayout &DL,
868
868
const TargetLibraryInfo *TLI) {
869
- bool InBounds = GEP->isInBounds ();
870
-
871
869
Type *SrcElemTy = GEP->getSourceElementType ();
872
870
Type *ResTy = GEP->getType ();
873
871
if (!SrcElemTy->isSized () || isa<ScalableVectorType>(SrcElemTy))
@@ -898,8 +896,10 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
898
896
InRange = InRange->sextOrTrunc (BitWidth);
899
897
900
898
// If this is a GEP of a GEP, fold it all into a single GEP.
899
+ GEPNoWrapFlags NW = GEP->getNoWrapFlags ();
900
+ bool Overflow = false ;
901
901
while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
902
- InBounds &= GEP->isInBounds ();
902
+ NW &= GEP->getNoWrapFlags ();
903
903
904
904
SmallVector<Value *, 4 > NestedOps (llvm::drop_begin (GEP->operands ()));
905
905
@@ -923,9 +923,16 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
923
923
924
924
Ptr = cast<Constant>(GEP->getOperand (0 ));
925
925
SrcElemTy = GEP->getSourceElementType ();
926
- Offset += APInt (BitWidth, DL.getIndexedOffsetInType (SrcElemTy, NestedOps));
926
+ Offset = Offset.sadd_ov (
927
+ APInt (BitWidth, DL.getIndexedOffsetInType (SrcElemTy, NestedOps)),
928
+ Overflow);
927
929
}
928
930
931
+ // Preserving nusw (without inbounds) also requires that the offset
932
+ // additions did not overflow.
933
+ if (NW.hasNoUnsignedSignedWrap () && !NW.isInBounds () && Overflow)
934
+ NW = NW.withoutNoUnsignedSignedWrap ();
935
+
929
936
// If the base value for this address is a literal integer value, fold the
930
937
// getelementptr to the resulting integer value casted to the pointer type.
931
938
APInt BasePtr (BitWidth, 0 );
@@ -944,17 +951,19 @@ Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
944
951
}
945
952
946
953
// Try to infer inbounds for GEPs of globals.
947
- if (!InBounds && Offset.isNonNegative ()) {
954
+ // TODO(gep_nowrap): Also infer nuw flag.
955
+ if (!NW.isInBounds () && Offset.isNonNegative ()) {
948
956
bool CanBeNull, CanBeFreed;
949
957
uint64_t DerefBytes =
950
958
Ptr->getPointerDereferenceableBytes (DL, CanBeNull, CanBeFreed);
951
- InBounds = DerefBytes != 0 && !CanBeNull && Offset.sle (DerefBytes);
959
+ if (DerefBytes != 0 && !CanBeNull && Offset.sle (DerefBytes))
960
+ NW |= GEPNoWrapFlags::inBounds ();
952
961
}
953
962
954
963
// Otherwise canonicalize this to a single ptradd.
955
964
LLVMContext &Ctx = Ptr->getContext ();
956
965
return ConstantExpr::getGetElementPtr (Type::getInt8Ty (Ctx), Ptr,
957
- ConstantInt::get (Ctx, Offset), InBounds ,
966
+ ConstantInt::get (Ctx, Offset), NW ,
958
967
InRange);
959
968
}
960
969
0 commit comments