aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2024-06-20 14:39:03 +0200
committerNikita Popov <npopov@redhat.com>2024-06-20 14:45:02 +0200
commit7f09aa9e3670778217a3d61702a4cf3343e6449d (patch)
treea89770f371015f48dc5fa29ebfc781106b53d649 /llvm/lib/Analysis/ScalarEvolution.cpp
parent3808ba78dea8ef81b108862d795ff21cb463bdb1 (diff)
downloadllvm-7f09aa9e3670778217a3d61702a4cf3343e6449d.zip
llvm-7f09aa9e3670778217a3d61702a4cf3343e6449d.tar.gz
llvm-7f09aa9e3670778217a3d61702a4cf3343e6449d.tar.bz2
[SCEV] Transfer gep nusw and nuw flags
nusw implies nsw offset and nuw base+offset arithmetic if offset is non-negative. nuw implies nuw offset and base+offset arithmetic. As usual, we can only transfer is poison implies UB.
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.");