aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 7d3e3f4..8d90530 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3746,21 +3746,23 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
// getSCEV(Base)->getType() has the same address space as Base->getType()
// because SCEV::getType() preserves the address space.
Type *IntIdxTy = getEffectiveSCEVType(BaseExpr->getType());
- const bool AssumeInBoundsFlags = [&]() {
- if (!GEP->isInBounds())
- return false;
-
+ GEPNoWrapFlags NW = GEP->getNoWrapFlags();
+ if (NW != GEPNoWrapFlags::none()) {
// We'd like to propagate flags from the IR to the corresponding SCEV nodes,
// but to do that, we have to ensure that said flag is valid in the entire
// defined scope of the SCEV.
- auto *GEPI = dyn_cast<Instruction>(GEP);
// TODO: non-instructions have global scope. We might be able to prove
// some global scope cases
- return GEPI && isSCEVExprNeverPoison(GEPI);
- }();
+ auto *GEPI = dyn_cast<Instruction>(GEP);
+ if (!GEPI || !isSCEVExprNeverPoison(GEPI))
+ NW = GEPNoWrapFlags::none();
+ }
- SCEV::NoWrapFlags OffsetWrap =
- AssumeInBoundsFlags ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
+ SCEV::NoWrapFlags OffsetWrap = SCEV::FlagAnyWrap;
+ if (NW.hasNoUnsignedSignedWrap())
+ OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNSW);
+ if (NW.hasNoUnsignedWrap())
+ OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNUW);
Type *CurTy = GEP->getType();
bool FirstIter = true;
@@ -3806,8 +3808,9 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
// Add the base address and the offset. We cannot use the nsw flag, as the
// base address is unsigned. However, if we know that the offset is
// non-negative, we can use nuw.
- SCEV::NoWrapFlags BaseWrap = AssumeInBoundsFlags && isKnownNonNegative(Offset)
- ? SCEV::FlagNUW : SCEV::FlagAnyWrap;
+ bool NUW = NW.hasNoUnsignedWrap() ||
+ (NW.hasNoUnsignedSignedWrap() && isKnownNonNegative(Offset));
+ SCEV::NoWrapFlags BaseWrap = NUW ? SCEV::FlagNUW : SCEV::FlagAnyWrap;
auto *GEPExpr = getAddExpr(BaseExpr, Offset, BaseWrap);
assert(BaseExpr->getType() == GEPExpr->getType() &&
"GEP should not change type mid-flight.");