[llvm] [polly] [SCEV] Rename SCEVNoWrapFlags to SCEVFlags (NFC) (PR #225179)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 29 01:17:03 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/225179
>From ee88feadba83a30e1861b139e98d0fa6d30370ca Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 21 Sep 2026 20:20:32 +0100
Subject: [PATCH] [SCEV] Rename SCEVNoWrapFlags to SCEVFlags (NFC)
In preparation to extend the flags that ScalarEvolution can represent,
rename SCEVNoWrapFlags to the more general SCEVFlags. In particular, we
preserve the (get|set)NoWrapFlags interface, which simply masks the
no-wrap flags from the newly-introduced (get|set)Flags.
See also: #225065
---
llvm/include/llvm/Analysis/IVDescriptors.h | 9 +-
llvm/include/llvm/Analysis/ScalarEvolution.h | 107 +++++++-------
.../Analysis/ScalarEvolutionExpressions.h | 41 ++++--
.../Analysis/ScalarEvolutionPatternMatch.h | 4 +-
.../Utils/ScalarEvolutionExpander.h | 4 +-
llvm/lib/Analysis/IVDescriptors.cpp | 2 +-
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 2 +-
llvm/lib/Analysis/LoopCacheAnalysis.cpp | 6 +-
llvm/lib/Analysis/ScalarEvolution.cpp | 130 ++++++++----------
llvm/lib/Analysis/ScalarEvolutionDivision.cpp | 4 +-
.../Utils/ScalarEvolutionExpander.cpp | 9 +-
polly/lib/Support/SCEVAffinator.cpp | 4 +-
12 files changed, 160 insertions(+), 162 deletions(-)
diff --git a/llvm/include/llvm/Analysis/IVDescriptors.h b/llvm/include/llvm/Analysis/IVDescriptors.h
index 7548ea1c871fe..08bde23b8f328 100644
--- a/llvm/include/llvm/Analysis/IVDescriptors.h
+++ b/llvm/include/llvm/Analysis/IVDescriptors.h
@@ -30,7 +30,7 @@ class ScalarEvolution;
class SCEV;
class SCEVPredicate;
class StoreInst;
-enum class SCEVNoWrapFlags;
+enum class SCEVFlags;
/// These are the kinds of recurrences that we support.
enum class RecurKind {
@@ -515,13 +515,12 @@ class ConditionalInductionDescriptor {
const SCEV *getStepSCEV() const { return StepSCEV; }
/// Returns the SCEV no-wrap flags that apply to StepInst.
- SCEVNoWrapFlags getSCEVNoWrapFlags() const { return NoWrapFlags; }
+ SCEVFlags getSCEVNoWrapFlags() const { return NoWrapFlags; }
private:
ConditionalInductionDescriptor(PHINode *HeaderPHI, PHINode *BackedgePHI,
Instruction *StepInst, const SCEV *StartSCEV,
- const SCEV *StepSCEV,
- SCEVNoWrapFlags NoWrapFlags)
+ const SCEV *StepSCEV, SCEVFlags NoWrapFlags)
: HeaderPHI(HeaderPHI), BackedgePHI(BackedgePHI), StepInst(StepInst),
StartSCEV(StartSCEV), StepSCEV(StepSCEV), NoWrapFlags(NoWrapFlags) {}
@@ -543,7 +542,7 @@ class ConditionalInductionDescriptor {
const SCEV *StepSCEV = nullptr;
/// The SCEV no-wrap flags that apply to StepInst.
- SCEVNoWrapFlags NoWrapFlags{};
+ SCEVFlags NoWrapFlags{};
};
} // end namespace llvm
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 28ae51ae850a8..7e8fcff7380ba 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -69,7 +69,7 @@ enum SCEVTypes : unsigned short;
LLVM_ABI extern bool VerifySCEV;
-/// NoWrapFlags are bitfield indices into SCEV's SubclassData.
+/// SCEVFlags are bitfield indices into SCEV's SubclassData.
///
/// Add and Mul expressions may have no-unsigned-wrap <NUW> or
/// no-signed-wrap <NSW> properties, which are derived from the IR
@@ -107,11 +107,12 @@ LLVM_ABI extern bool VerifySCEV;
/// can trap) can be defined per these rules in regions where it would trap
/// at runtime. A SCEV being defined does not require the existence of any
/// instruction within the defined scope.
-enum class SCEVNoWrapFlags {
+enum class SCEVFlags {
FlagNone = 0, // No guarantee.
FlagNW = (1 << 0), // No self-wrap.
FlagNUW = (1 << 1), // No unsigned wrap.
FlagNSW = (1 << 2), // No signed wrap.
+ FlagsNoWrapMask = (1 << 3) - 1,
FlagsMask = (1 << 3) - 1,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/FlagsMask)
};
@@ -126,11 +127,11 @@ struct SCEVUseT : private PointerIntPair<SCEVPtrT, 2> {
SCEVUseT() : Base(nullptr, 0) {}
SCEVUseT(SCEVPtrT S) : Base(S, 0) {}
- /// Construct with NoWrapFlags; only NUW/NSW are encoded, NW is dropped. \p S
+ /// Construct with SCEVFlags; only NUW/NSW are encoded, NW is dropped. \p S
/// must be an expression supporting flags. Only flags not already present on
/// \p S are added. Note that the expression may gain flags also part of the
- /// SCEVUse later, via settNoWrapFlags.
- SCEVUseT(SCEVPtrT S, SCEVNoWrapFlags Flags);
+ /// SCEVUse later, via setFlags.
+ SCEVUseT(SCEVPtrT S, SCEVFlags Flags);
template <typename OtherPtrT, typename = std::enable_if_t<
std::is_convertible_v<OtherPtrT, SCEVPtrT>>>
SCEVUseT(const SCEVUseT<OtherPtrT> &Other)
@@ -149,18 +150,19 @@ struct SCEVUseT : private PointerIntPair<SCEVPtrT, 2> {
/// Return the canonical SCEV for this SCEVUse.
const SCEV *getCanonical() const;
- /// Return the no-wrap flags for this SCEVUse, which is the union of the
- /// use-specific flags and the underlying SCEV's flags, masked by \p Mask.
- SCEVNoWrapFlags
- getNoWrapFlags(SCEVNoWrapFlags Mask = SCEVNoWrapFlags::FlagsMask) const;
-
- /// Return only the use-specific no-wrap flags (NUW/NSW) without the
- /// underlying SCEV's flags.
- SCEVNoWrapFlags getUseNoWrapFlags() const {
- SCEVNoWrapFlags UseFlags =
- static_cast<SCEVNoWrapFlags>(Base::getInt() << 1);
- if (any(UseFlags & (SCEVNoWrapFlags::FlagNUW | SCEVNoWrapFlags::FlagNSW)))
- UseFlags |= SCEVNoWrapFlags::FlagNW;
+ /// Return the flags for this SCEVUse, which is the union of the use-specific
+ /// flags and the underlying SCEV's flags, masked by \p Mask.
+ SCEVFlags getFlags(SCEVFlags Mask = SCEVFlags::FlagsMask) const;
+ SCEVFlags getNoWrapFlags(SCEVFlags Mask = SCEVFlags::FlagsNoWrapMask) const;
+
+ /// Return only the use-specific flags without the underlying SCEV's flags.
+ SCEVFlags getUseNoWrapFlags() const {
+ return getUseFlags() & SCEVFlags::FlagsNoWrapMask;
+ }
+ SCEVFlags getUseFlags() const {
+ SCEVFlags UseFlags = static_cast<SCEVFlags>(Base::getInt() << 1);
+ if (any(UseFlags & (SCEVFlags::FlagNUW | SCEVFlags::FlagNSW)))
+ UseFlags |= SCEVFlags::FlagNW;
return UseFlags;
}
@@ -197,13 +199,13 @@ using SCEVUse = SCEVUseT<const SCEV *>;
struct SCEVFlagsPair {
/// Flags applied directly to a SCEV expression, must be valid wherever the
/// expression is valid.
- SCEVNoWrapFlags ExprFlags;
+ SCEVFlags ExprFlags;
/// Flags only applied to a SCEVUse.
- SCEVNoWrapFlags UseFlags;
+ SCEVFlags UseFlags;
- constexpr SCEVFlagsPair(SCEVNoWrapFlags ExprFlags = SCEVNoWrapFlags::FlagNone,
- SCEVNoWrapFlags UseFlags = SCEVNoWrapFlags::FlagNone)
+ constexpr SCEVFlagsPair(SCEVFlags ExprFlags = SCEVFlags::FlagNone,
+ SCEVFlags UseFlags = SCEVFlags::FlagNone)
: ExprFlags(ExprFlags), UseFlags(UseFlags) {}
};
@@ -293,12 +295,12 @@ class SCEV : public FoldingSetNode {
Type *const Ty;
public:
- using NoWrapFlags = SCEVNoWrapFlags;
- static constexpr auto FlagNone = SCEVNoWrapFlags::FlagNone;
- static constexpr auto FlagNW = SCEVNoWrapFlags::FlagNW;
- static constexpr auto FlagNUW = SCEVNoWrapFlags::FlagNUW;
- static constexpr auto FlagNSW = SCEVNoWrapFlags::FlagNSW;
- static constexpr auto FlagsMask = SCEVNoWrapFlags::FlagsMask;
+ static constexpr auto FlagNone = SCEVFlags::FlagNone;
+ static constexpr auto FlagNW = SCEVFlags::FlagNW;
+ static constexpr auto FlagNUW = SCEVFlags::FlagNUW;
+ static constexpr auto FlagNSW = SCEVFlags::FlagNSW;
+ static constexpr auto FlagsNoWrapMask = SCEVFlags::FlagsNoWrapMask;
+ static constexpr auto FlagsMask = SCEVFlags::FlagsMask;
explicit SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
unsigned short ExpressionSize, Type *Ty)
@@ -642,20 +644,17 @@ class ScalarEvolution {
/// Convenient NoWrapFlags manipulation. TODO: Replace with & operator of
/// enum class.
- [[nodiscard]] static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags,
- SCEV::NoWrapFlags Mask) {
+ [[nodiscard]] static SCEVFlags maskFlags(SCEVFlags Flags, SCEVFlags Mask) {
return Flags & Mask;
}
- [[nodiscard]] static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags,
- SCEV::NoWrapFlags OnFlags) {
+ [[nodiscard]] static SCEVFlags setFlags(SCEVFlags Flags, SCEVFlags OnFlags) {
return Flags | OnFlags;
}
- [[nodiscard]] static SCEV::NoWrapFlags
- clearFlags(SCEV::NoWrapFlags Flags, SCEV::NoWrapFlags OffFlags) {
+ [[nodiscard]] static SCEVFlags clearFlags(SCEVFlags Flags,
+ SCEVFlags OffFlags) {
return Flags & ~OffFlags;
}
- [[nodiscard]] static bool hasFlags(SCEV::NoWrapFlags Flags,
- SCEV::NoWrapFlags TestFlags) {
+ [[nodiscard]] static bool hasFlags(SCEVFlags Flags, SCEVFlags TestFlags) {
return TestFlags == maskFlags(Flags, TestFlags);
};
@@ -717,7 +716,7 @@ class ScalarEvolution {
/// Does not mutate the original instruction. Returns std::nullopt if it could
/// not deduce more precise flags than the instruction already has, otherwise
/// returns proven flags.
- LLVM_ABI std::optional<SCEV::NoWrapFlags>
+ LLVM_ABI std::optional<SCEVFlags>
getStrengthenedNoWrapFlagsFromBinOp(const OverflowingBinaryOperator *OBO);
/// Notify this ScalarEvolution that \p User directly uses SCEVs in \p Ops.
@@ -745,9 +744,8 @@ class ScalarEvolution {
LLVM_ABI const SCEV *getTruncateExpr(SCEVUse Op, Type *Ty,
unsigned Depth = 0);
LLVM_ABI const SCEV *getVScale(Type *Ty);
- LLVM_ABI const SCEV *
- getElementCount(Type *Ty, ElementCount EC,
- SCEV::NoWrapFlags Flags = SCEV::FlagNone);
+ LLVM_ABI const SCEV *getElementCount(Type *Ty, ElementCount EC,
+ SCEVFlags Flags = SCEV::FlagNone);
LLVM_ABI const SCEV *getZeroExtendExpr(SCEVUse Op, Type *Ty,
unsigned Depth = 0);
LLVM_ABI const SCEV *getZeroExtendExprImpl(SCEVUse Op, Type *Ty,
@@ -864,8 +862,8 @@ class ScalarEvolution {
unsigned FieldNo);
/// Return the SCEV object corresponding to -V.
- LLVM_ABI const SCEV *
- getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags = SCEV::FlagNone);
+ LLVM_ABI const SCEV *getNegativeSCEV(const SCEV *V,
+ SCEVFlags Flags = SCEV::FlagNone);
/// Return the SCEV object corresponding to ~V.
LLVM_ABI const SCEV *getNotSCEV(const SCEV *V);
@@ -878,7 +876,7 @@ class ScalarEvolution {
/// explicitly convert the arguments using getPtrToAddrExpr(), for pointer
/// types that support it.
LLVM_ABI const SCEV *getMinusSCEV(SCEVUse LHS, SCEVUse RHS,
- SCEV::NoWrapFlags Flags = SCEV::FlagNone,
+ SCEVFlags Flags = SCEV::FlagNone,
unsigned Depth = 0);
/// Compute ceil(N / D). N and D are treated as unsigned values.
@@ -1574,7 +1572,7 @@ class ScalarEvolution {
/// Update no-wrap flags of an AddRec. This may drop the cached info about
/// this AddRec (such as range info) in case if new flags may potentially
/// sharpen it.
- LLVM_ABI void setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEV::NoWrapFlags Flags);
+ LLVM_ABI void setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEVFlags Flags);
class LoopGuards {
DenseMap<const SCEV *, const SCEV *> RewriteMap;
@@ -2018,7 +2016,7 @@ class ScalarEvolution {
/// Determines the range for the affine SCEVAddRecExpr {\p Start,+,\p Step},
/// and whether it may wrap. Helper for \c getRange.
- std::pair<ConstantRange, SCEV::NoWrapFlags>
+ std::pair<ConstantRange, SCEVFlags>
getRangeForAffineAR(const SCEV *Start, const SCEV *Step,
const APInt &MaxBECount);
/// If \p S is a SCEVConstant, return the wrapped constant or nullptr
@@ -2236,7 +2234,7 @@ class ScalarEvolution {
///
/// \p ControlsOnlyExit is true when the LHS < RHS condition directly controls
/// the branch (loops exits only if condition is true). In this case, we can
- /// use NoWrapFlags to skip overflow checks.
+ /// use no-wrap flags to skip overflow checks.
///
/// If \p AllowPredicates is set, this call will try to use a minimal set of
/// SCEV predicates in order to return an exact answer.
@@ -2401,8 +2399,7 @@ class ScalarEvolution {
SCEVUse RHS);
/// Try to match the Expr as "(L + R)<Flags>".
- bool splitBinaryAdd(SCEVUse Expr, SCEVUse &L, SCEVUse &R,
- SCEV::NoWrapFlags &Flags);
+ bool splitBinaryAdd(SCEVUse Expr, SCEVUse &L, SCEVUse &R, SCEVFlags &Flags);
/// Forget predicated/non-predicated backedge taken counts for the given loop.
void forgetBackedgeTakenCounts(const Loop *L, bool Predicated);
@@ -2443,11 +2440,11 @@ class ScalarEvolution {
/// Try to prove NSW on \p AR by proving facts about conditions known on
/// entry and backedge.
- SCEV::NoWrapFlags proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR);
+ SCEVFlags proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR);
/// Try to prove NUW on \p AR by proving facts about conditions known on
/// entry and backedge.
- SCEV::NoWrapFlags proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR);
+ SCEVFlags proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR);
std::optional<MonotonicPredicateType>
getMonotonicPredicateTypeImpl(const SCEVAddRecExpr *LHS,
@@ -2456,7 +2453,7 @@ class ScalarEvolution {
/// Return SCEV no-wrap flags that can be proven based on reasoning about
/// how poison produced from no-wrap flags on this value (e.g. a nuw add)
/// would trigger undefined behavior on overflow.
- SCEV::NoWrapFlags getNoWrapFlagsFromUB(const Value *V);
+ SCEVFlags getNoWrapFlagsFromUB(const Value *V);
/// Return a scope which provides an upper bound on the defining scope of
/// 'S'. Specifically, return the first instruction in said bounding scope.
@@ -2555,16 +2552,14 @@ class ScalarEvolution {
bool Invert = false);
/// Get add expr already created or create a new one.
- const SCEV *getOrCreateAddExpr(ArrayRef<SCEVUse> Ops,
- SCEV::NoWrapFlags Flags);
+ const SCEV *getOrCreateAddExpr(ArrayRef<SCEVUse> Ops, SCEVFlags Flags);
/// Get mul expr already created or create a new one.
- const SCEV *getOrCreateMulExpr(ArrayRef<SCEVUse> Ops,
- SCEV::NoWrapFlags Flags);
+ const SCEV *getOrCreateMulExpr(ArrayRef<SCEVUse> Ops, SCEVFlags Flags);
// Get addrec expr already created or create a new one.
const SCEV *getOrCreateAddRecExpr(ArrayRef<SCEVUse> Ops, const Loop *L,
- SCEV::NoWrapFlags Flags);
+ SCEVFlags Flags);
// Get UDiv expression already created or create a new one.
const SCEV *getOrCreateUDivExpr(SCEVUse LHS, SCEVUse RHS);
@@ -2803,7 +2798,7 @@ template <> inline const SCEV *SCEVUseT<const SCEV *>::getCanonical() const {
template <typename SCEVPtrT>
void SCEVUseT<SCEVPtrT>::print(raw_ostream &OS) const {
getPointer()->print(OS);
- SCEV::NoWrapFlags Flags = getUseNoWrapFlags();
+ SCEVFlags Flags = getUseNoWrapFlags();
if (any(Flags & SCEV::FlagNUW))
OS << "<u nuw>";
if (any(Flags & SCEV::FlagNSW))
diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
index feb62d73079bb..ca0390867094b 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -210,8 +210,11 @@ class SCEVNAryExpr : public SCEV {
ArrayRef<SCEVUse> operands() const { return ArrayRef(Operands, NumOperands); }
- NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = FlagsMask) const {
- return static_cast<NoWrapFlags>(SubclassData) & Mask;
+ SCEVFlags getFlags(SCEVFlags Mask = FlagsMask) const {
+ return static_cast<SCEVFlags>(SubclassData) & Mask;
+ }
+ SCEVFlags getNoWrapFlags(SCEVFlags Mask = FlagsNoWrapMask) const {
+ return getFlags(Mask & SCEV::FlagsNoWrapMask);
}
bool hasNoUnsignedWrap() const { return getNoWrapFlags(FlagNUW) != FlagNone; }
@@ -246,9 +249,12 @@ class SCEVCommutativeExpr : public SCEVNAryExpr {
}
/// Set flags for a non-recurrence without clearing previously set flags.
- void setNoWrapFlags(NoWrapFlags Flags) {
+ void setFlags(SCEVFlags Flags) {
SubclassData |= static_cast<unsigned short>(Flags);
}
+ void setNoWrapFlags(SCEVFlags Flags) {
+ setFlags(Flags & SCEV::FlagsNoWrapMask);
+ }
};
/// This node represents an addition of some number of SCEVs.
@@ -362,7 +368,9 @@ class SCEVAddRecExpr : public SCEVNAryExpr {
/// Set flags for a recurrence without clearing any previously set flags.
/// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
/// to make it easier to propagate flags.
- void setNoWrapFlags(NoWrapFlags Flags) {
+ void setNoWrapFlags(SCEVFlags Flags) {
+ if (!any(Flags & FlagsNoWrapMask))
+ return;
if (any(Flags & (FlagNUW | FlagNSW)))
Flags = ScalarEvolution::setFlags(Flags, FlagNW);
SubclassData |= static_cast<unsigned short>(Flags);
@@ -377,8 +385,7 @@ class SCEVAddRecExpr : public SCEVNAryExpr {
/// number. Takes an explicit list of operands to represent an AddRec.
LLVM_ABI static SCEVUse
evaluateAtIteration(ArrayRef<SCEVUse> Operands, const SCEV *It,
- ScalarEvolution &SE,
- SCEV::NoWrapFlags UseFlags = SCEV::FlagNone);
+ ScalarEvolution &SE, SCEVFlags UseFlags = SCEV::FlagNone);
/// Return the value of this recurrences when its loop exits, i.e. its value
/// at the loop's exact backedge-taken count, or SCEVCouldNotCompute if that
@@ -504,9 +511,12 @@ class SCEVSequentialMinMaxExpr : public SCEVNAryExpr {
}
/// Set flags for a non-recurrence without clearing previously set flags.
- void setNoWrapFlags(NoWrapFlags Flags) {
+ void setFlags(SCEVFlags Flags) {
SubclassData |= static_cast<unsigned short>(Flags);
}
+ void setNoWrapFlags(SCEVFlags Flags) {
+ setFlags(Flags & SCEV::FlagsNoWrapMask);
+ }
protected:
/// Note: Constructing subclasses via this constructor is allowed
@@ -997,9 +1007,8 @@ class SCEVLoopAddRecRewriter
};
template <typename SCEVPtrT>
-inline SCEVUseT<SCEVPtrT>::SCEVUseT(SCEVPtrT S, SCEVNoWrapFlags Flags)
- : Base(S, 0) {
- if (any(Flags)) {
+inline SCEVUseT<SCEVPtrT>::SCEVUseT(SCEVPtrT S, SCEVFlags Flags) : Base(S, 0) {
+ if (any(Flags & SCEVFlags::FlagsNoWrapMask)) {
assert((isa<SCEVAddExpr, SCEVMulExpr, SCEVAddRecExpr>(S)) &&
"use flags require an expression that can carry no-wrap flags");
// Drop flags already present on S.
@@ -1009,14 +1018,18 @@ inline SCEVUseT<SCEVPtrT>::SCEVUseT(SCEVPtrT S, SCEVNoWrapFlags Flags)
}
template <typename SCEVPtrT>
-inline SCEVNoWrapFlags
-SCEVUseT<SCEVPtrT>::getNoWrapFlags(SCEVNoWrapFlags Mask) const {
- SCEVNoWrapFlags Flags = SCEVNoWrapFlags::FlagNone;
+inline SCEVFlags SCEVUseT<SCEVPtrT>::getFlags(SCEVFlags Mask) const {
+ SCEVFlags Flags = SCEVFlags::FlagNone;
if (auto *NAry = dyn_cast<SCEVNAryExpr>(Base::getPointer()))
- Flags = NAry->getNoWrapFlags();
+ Flags = NAry->getFlags();
return (Flags | getUseNoWrapFlags()) & Mask;
}
+template <typename SCEVPtrT>
+inline SCEVFlags SCEVUseT<SCEVPtrT>::getNoWrapFlags(SCEVFlags Mask) const {
+ return getFlags(Mask & SCEVFlags::FlagsNoWrapMask);
+}
+
} // end namespace llvm
#endif // LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
index 771ec41bc21f1..0d37cb09b89f3 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
@@ -200,7 +200,7 @@ m_scev_Trunc(const Op0_t &Op0) {
/// Match a binary SCEV.
template <typename SCEVTy, typename Op0_t, typename Op1_t,
- SCEV::NoWrapFlags WrapFlags = SCEV::FlagNone, bool Commutable = false>
+ SCEVFlags WrapFlags = SCEV::FlagNone, bool Commutable = false>
struct SCEVBinaryExpr_match {
Op0_t Op0;
Op1_t Op1;
@@ -222,7 +222,7 @@ struct SCEVBinaryExpr_match {
};
template <typename SCEVTy, typename Op0_t, typename Op1_t,
- SCEV::NoWrapFlags WrapFlags = SCEV::FlagNone, bool Commutable = false>
+ SCEVFlags WrapFlags = SCEV::FlagNone, bool Commutable = false>
inline SCEVBinaryExpr_match<SCEVTy, Op0_t, Op1_t, WrapFlags, Commutable>
m_scev_Binary(const Op0_t &Op0, const Op1_t &Op1) {
return SCEVBinaryExpr_match<SCEVTy, Op0_t, Op1_t, WrapFlags, Commutable>(Op0,
diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
index 48bdd0c5a1e00..d068037310835 100644
--- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
+++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
@@ -473,7 +473,7 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// avoid inserting an obviously redundant operation, and hoisting to an
/// outer loop when the opportunity is there and it is safe.
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS,
- SCEV::NoWrapFlags Flags, bool IsSafeToHoist);
+ SCEVFlags Flags, bool IsSafeToHoist);
/// We want to cast \p V. What would be the best place for such a cast?
BasicBlock::iterator GetOptimalInsertionPointForCastOf(Value *V) const;
@@ -490,7 +490,7 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// Expand a SCEVAddExpr with a pointer type into a GEP instead of using
/// ptrtoint+arithmetic+inttoptr.
- Value *expandAddToGEP(SCEVUse Op, Value *V, SCEV::NoWrapFlags Flags);
+ Value *expandAddToGEP(SCEVUse Op, Value *V, SCEVFlags Flags);
/// Find a previous Value in ExprValueMap for expand.
/// DropPoisonGeneratingInsts is populated with instructions for which
diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index 2def6fa521c71..d281dd0cfc695 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -1765,7 +1765,7 @@ bool ConditionalInductionDescriptor::isConditionalInductionPHI(
Value *Start = PN->getIncomingValueForBlock(Preheader);
const SCEV *StartSCEV = SE.getSCEV(Start);
- SCEV::NoWrapFlags NoWrapFlags = SCEV::FlagNone;
+ SCEVFlags NoWrapFlags = SCEV::FlagNone;
if (auto *GEP = dyn_cast<GEPOperator>(StepInst)) {
// With NUSW, we can add NUW if the step is non-negative. We can't add NSW
// as the base address is unsigned.
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 804ffe5bb2edd..00b67ed4b63f0 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -1105,7 +1105,7 @@ isNoWrap(PredicatedScalarEvolution &PSE, const SCEVAddRecExpr *AR, Value *Ptr,
std::optional<int64_t> Stride = std::nullopt,
SmallVectorImpl<const SCEVPredicate *> *Predicates = nullptr) {
// FIXME: This should probably only return true for NUW.
- if (any(AR->getNoWrapFlags(SCEV::FlagsMask)))
+ if (any(AR->getNoWrapFlags()))
return true;
// An nusw getelementptr that is an AddRec cannot wrap. If it would wrap,
diff --git a/llvm/lib/Analysis/LoopCacheAnalysis.cpp b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
index 3c70f7cbba2a3..e60bdd0644d3f 100644
--- a/llvm/lib/Analysis/LoopCacheAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
@@ -415,9 +415,9 @@ bool IndexedReference::delinearize(const LoopInfo &LI) {
const SCEV *StepRec = AccessFnAR ? AccessFnAR->getStepRecurrence(SE) : nullptr;
if (StepRec && SE.isKnownNegative(StepRec))
- AccessFn = SE.getAddRecExpr(
- AccessFnAR->getStart(), SE.getNegativeSCEV(StepRec),
- AccessFnAR->getLoop(), SCEV::NoWrapFlags::FlagNone);
+ AccessFn = SE.getAddRecExpr(AccessFnAR->getStart(),
+ SE.getNegativeSCEV(StepRec),
+ AccessFnAR->getLoop(), SCEVFlags::FlagNone);
const SCEV *Div = SE.getUDivExactExpr(AccessFn, ElemSize);
Subscripts.push_back(Div);
Sizes.push_back(ElemSize);
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index cbadeaf7b347d..8ab9c309dbb13 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -502,7 +502,7 @@ const SCEV *ScalarEvolution::getVScale(Type *Ty) {
}
const SCEV *ScalarEvolution::getElementCount(Type *Ty, ElementCount EC,
- SCEV::NoWrapFlags Flags) {
+ SCEVFlags Flags) {
const SCEV *Res = getConstant(Ty, EC.getKnownMinValue());
if (EC.isScalable())
Res = getMulExpr(Res, getVScale(Ty), Flags);
@@ -985,7 +985,7 @@ const SCEV *SCEVAddRecExpr::evaluateAtIteration(const SCEV *It,
SCEVUse SCEVAddRecExpr::evaluateAtIteration(ArrayRef<SCEVUse> Operands,
const SCEV *It, ScalarEvolution &SE,
- SCEV::NoWrapFlags UseFlags) {
+ SCEVFlags UseFlags) {
assert(Operands.size() > 0);
assert((Operands.size() == 2 || UseFlags == SCEV::FlagNone) &&
"use-specific flags only supported for affine AddRecs");
@@ -1252,7 +1252,7 @@ struct ExtendOpTraitsBase {
template <typename ExtendOp> struct ExtendOpTraits {
// Members present:
//
- // static const SCEV::NoWrapFlags WrapType;
+ // static const SCEVFlags WrapType;
//
// static const ExtendOpTraitsBase::GetExtendExprTy GetExtendExpr;
//
@@ -1263,7 +1263,7 @@ template <typename ExtendOp> struct ExtendOpTraits {
template <>
struct ExtendOpTraits<SCEVSignExtendExpr> : public ExtendOpTraitsBase {
- static const SCEV::NoWrapFlags WrapType = SCEV::FlagNSW;
+ static const SCEVFlags WrapType = SCEV::FlagNSW;
static const GetExtendExprTy GetExtendExpr;
@@ -1279,7 +1279,7 @@ const ExtendOpTraitsBase::GetExtendExprTy ExtendOpTraits<
template <>
struct ExtendOpTraits<SCEVZeroExtendExpr> : public ExtendOpTraitsBase {
- static const SCEV::NoWrapFlags WrapType = SCEV::FlagNUW;
+ static const SCEVFlags WrapType = SCEV::FlagNUW;
static const GetExtendExprTy GetExtendExpr;
@@ -2368,14 +2368,13 @@ bool ScalarEvolution::willNotOverflow(Instruction::BinaryOps BinOp, bool Signed,
}
}
-std::optional<SCEV::NoWrapFlags>
-ScalarEvolution::getStrengthenedNoWrapFlagsFromBinOp(
+std::optional<SCEVFlags> ScalarEvolution::getStrengthenedNoWrapFlagsFromBinOp(
const OverflowingBinaryOperator *OBO) {
// It cannot be done any better.
if (OBO->hasNoUnsignedWrap() && OBO->hasNoSignedWrap())
return std::nullopt;
- SCEV::NoWrapFlags Flags = SCEV::NoWrapFlags::FlagNone;
+ SCEVFlags Flags = SCEVFlags::FlagNone;
if (OBO->hasNoUnsignedWrap())
Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
@@ -2427,10 +2426,8 @@ ScalarEvolution::getStrengthenedNoWrapFlagsFromBinOp(
// We're trying to construct a SCEV of type `Type' with `Ops' as operands and
// `OldFlags' as can't-wrap behavior. Infer a more aggressive set of
// can't-overflow flags for the operation if possible.
-static SCEV::NoWrapFlags StrengthenNoWrapFlags(ScalarEvolution *SE,
- SCEVTypes Type,
- ArrayRef<SCEVUse> Ops,
- SCEV::NoWrapFlags Flags) {
+static SCEVFlags StrengthenNoWrapFlags(ScalarEvolution *SE, SCEVTypes Type,
+ ArrayRef<SCEVUse> Ops, SCEVFlags Flags) {
using namespace std::placeholders;
using OBO = OverflowingBinaryOperator;
@@ -2440,8 +2437,8 @@ static SCEV::NoWrapFlags StrengthenNoWrapFlags(ScalarEvolution *SE,
(void)CanAnalyze;
assert(CanAnalyze && "don't call from other places!");
- SCEV::NoWrapFlags SignOrUnsignMask = SCEV::FlagNUW | SCEV::FlagNSW;
- SCEV::NoWrapFlags SignOrUnsignWrap =
+ SCEVFlags SignOrUnsignMask = SCEV::FlagNUW | SCEV::FlagNSW;
+ SCEVFlags SignOrUnsignWrap =
ScalarEvolution::maskFlags(Flags, SignOrUnsignMask);
// If FlagNSW is true and all the operands are non-negative, infer FlagNUW.
@@ -2516,8 +2513,8 @@ bool ScalarEvolution::isAvailableAtLoopEntry(const SCEV *S, const Loop *L) {
/// Get a canonical add expression, or something simpler if possible.
SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
SCEVFlagsPair Flags, unsigned Depth) {
- SCEV::NoWrapFlags ExprFlags = Flags.ExprFlags;
- SCEV::NoWrapFlags UseFlags = Flags.UseFlags;
+ SCEVFlags ExprFlags = Flags.ExprFlags;
+ SCEVFlags UseFlags = Flags.UseFlags;
assert(!(ExprFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
"only nuw or nsw allowed");
assert(!(UseFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
@@ -2668,7 +2665,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
if (AddExpr && C && isa<SCEVConstant>(AddExpr->getOperand(0))) {
auto C1 = cast<SCEVConstant>(AddExpr->getOperand(0))->getAPInt();
auto C2 = C->getAPInt();
- SCEV::NoWrapFlags PreservedFlags = SCEV::FlagNone;
+ SCEVFlags PreservedFlags = SCEV::FlagNone;
APInt ConstAdd = C1 + C2;
auto AddFlags = AddExpr->getNoWrapFlags();
@@ -2728,7 +2725,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
// If the original flags and all inlined SCEVAddExprs are NUW, use the
// common NUW flag for expression after inlining. Other flags cannot be
// preserved, because they may depend on the original order of operations.
- SCEV::NoWrapFlags CommonFlags = maskFlags(ExprFlags, SCEV::FlagNUW);
+ SCEVFlags CommonFlags = maskFlags(ExprFlags, SCEV::FlagNUW);
while (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[Idx])) {
if (Ops.size() > AddOpsInlineThreshold ||
Add->getNumOperands() > AddOpsInlineThreshold)
@@ -2898,7 +2895,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
// the addrec. Temporarily push it as an operand for that purpose. These
// flags are valid in the scope of the addrec only.
LIOps.push_back(AddRec);
- SCEV::NoWrapFlags Flags = ComputeFlags(LIOps);
+ SCEVFlags Flags = ComputeFlags(LIOps);
LIOps.pop_back();
// NLI + LI + {Start,+,Step} --> NLI + {LI+Start,+,Step}
@@ -2916,7 +2913,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
// Proving that entry to the outer scope neccesitates entry to the inner
// scope, thus proves the program undefined if the flags would be violated
// in the outer scope.
- SCEV::NoWrapFlags AddFlags = Flags;
+ SCEVFlags AddFlags = Flags;
if (AddFlags != SCEV::FlagNone) {
auto *DefI = getDefiningScopeBound(LIOps);
auto *ReachI = &*AddRecLoop->getHeader()->begin();
@@ -2993,7 +2990,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
}
const SCEV *ScalarEvolution::getOrCreateAddExpr(ArrayRef<SCEVUse> Ops,
- SCEV::NoWrapFlags Flags) {
+ SCEVFlags Flags) {
FoldingSetNodeID ID;
ID.AddInteger(scAddExpr);
for (SCEVUse Op : Ops)
@@ -3015,7 +3012,7 @@ const SCEV *ScalarEvolution::getOrCreateAddExpr(ArrayRef<SCEVUse> Ops,
const SCEV *ScalarEvolution::getOrCreateAddRecExpr(ArrayRef<SCEVUse> Ops,
const Loop *L,
- SCEV::NoWrapFlags Flags) {
+ SCEVFlags Flags) {
FoldingSetNodeID ID;
ID.AddInteger(scAddRecExpr);
for (SCEVUse Op : Ops)
@@ -3039,7 +3036,7 @@ const SCEV *ScalarEvolution::getOrCreateAddRecExpr(ArrayRef<SCEVUse> Ops,
}
const SCEV *ScalarEvolution::getOrCreateMulExpr(ArrayRef<SCEVUse> Ops,
- SCEV::NoWrapFlags Flags) {
+ SCEVFlags Flags) {
FoldingSetNodeID ID;
ID.AddInteger(scMulExpr);
for (SCEVUse Op : Ops)
@@ -3132,8 +3129,8 @@ static bool containsConstantInAddMulChain(const SCEV *StartExpr) {
/// Get a canonical multiply expression, or something simpler if possible.
SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
SCEVFlagsPair Flags, unsigned Depth) {
- SCEVNoWrapFlags ExprFlags = Flags.ExprFlags;
- SCEVNoWrapFlags UseFlags = Flags.UseFlags;
+ SCEVFlags ExprFlags = Flags.ExprFlags;
+ SCEVFlags UseFlags = Flags.UseFlags;
assert(ExprFlags == maskFlags(ExprFlags, SCEV::FlagNUW | SCEV::FlagNSW) &&
"only nuw or nsw allowed");
assert(UseFlags == maskFlags(UseFlags, SCEV::FlagNUW | SCEV::FlagNSW) &&
@@ -3331,8 +3328,7 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
// If both the mul and addrec are nsw, we can only preserve nsw if either
// a) they are also nuw, or
// b) all multiplications of addrec operands with scale are nsw.
- SCEV::NoWrapFlags Flags =
- AddRec->getNoWrapFlags(ComputeFlags({Scale, AddRec}));
+ SCEVFlags Flags = AddRec->getNoWrapFlags(ComputeFlags({Scale, AddRec}));
for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) {
NewOps.push_back(getMulExpr(Scale, AddRec->getOperand(i),
@@ -3703,8 +3699,8 @@ SCEVUse ScalarEvolution::getAddRecExpr(SCEVUse Start, SCEVUse Step,
/// expression as much as possible.
SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
const Loop *L, SCEVFlagsPair NWFlags) {
- SCEVNoWrapFlags ExprFlags = NWFlags.ExprFlags;
- SCEVNoWrapFlags UseFlags = NWFlags.UseFlags;
+ SCEVFlags ExprFlags = NWFlags.ExprFlags;
+ SCEVFlags UseFlags = NWFlags.UseFlags;
assert(!(UseFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
"only nuw or nsw allowed");
if (Operands.size() == 1) return Operands[0];
@@ -3757,7 +3753,7 @@ SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
//
// The outer recurrence keeps its NW flag but only keeps NUW/NSW if the
// inner recurrence has the same property.
- SCEV::NoWrapFlags OuterFlags =
+ SCEVFlags OuterFlags =
maskFlags(ExprFlags, SCEV::FlagNW | NestedAR->getNoWrapFlags());
NestedOperands[0] = getAddRecExpr(Operands, L, OuterFlags);
@@ -3770,7 +3766,7 @@ SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
//
// The inner recurrence keeps its NW flag but only keeps NUW/NSW if
// the outer recurrence has the same property.
- SCEV::NoWrapFlags InnerFlags =
+ SCEVFlags InnerFlags =
maskFlags(NestedAR->getNoWrapFlags(), SCEV::FlagNW | ExprFlags);
return getAddRecExpr(NestedOperands, NestedLoop, InnerFlags);
}
@@ -3810,7 +3806,7 @@ const SCEV *ScalarEvolution::getGEPExpr(GEPOperator *GEP,
const SCEV *ScalarEvolution::getGEPExpr(SCEVUse BaseExpr,
ArrayRef<SCEVUse> IndexExprs,
Type *SrcElementTy, GEPNoWrapFlags NW) {
- SCEV::NoWrapFlags OffsetWrap = SCEV::FlagNone;
+ SCEVFlags OffsetWrap = SCEV::FlagNone;
if (NW.hasNoUnsignedSignedWrap())
OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNSW);
if (NW.hasNoUnsignedWrap())
@@ -3863,7 +3859,7 @@ const SCEV *ScalarEvolution::getGEPExpr(SCEVUse BaseExpr,
// non-negative, we can use nuw.
bool NUW = NW.hasNoUnsignedWrap() ||
(NW.hasNoUnsignedSignedWrap() && isKnownNonNegative(Offset));
- SCEV::NoWrapFlags BaseWrap = NUW ? SCEV::FlagNUW : SCEV::FlagNone;
+ SCEVFlags BaseWrap = NUW ? SCEV::FlagNUW : SCEV::FlagNone;
const SCEV *GEPExpr = getAddExpr(BaseExpr, Offset, BaseWrap);
assert(BaseExpr->getType() == GEPExpr->getType() &&
"GEP should not change type mid-flight.");
@@ -3881,7 +3877,7 @@ SCEV *ScalarEvolution::findExistingSCEVInCache(SCEVTypes SCEVType,
}
const SCEV *ScalarEvolution::getAbsExpr(const SCEV *Op, bool IsNSW) {
- SCEV::NoWrapFlags Flags = IsNSW ? SCEV::FlagNSW : SCEV::FlagNone;
+ SCEVFlags Flags = IsNSW ? SCEV::FlagNSW : SCEV::FlagNone;
return getSMaxExpr(Op, getNegativeSCEV(Op, Flags));
}
@@ -4118,7 +4114,7 @@ static bool scevUnconditionallyPropagatesPoisonFromOperands(SCEVTypes Kind) {
namespace {
// The only way poison may be introduced in a SCEV expression is from a
// poison SCEVUnknown (ConstantExprs are also represented as SCEVUnknown,
-// not SCEVConstant). Notably, nowrap flags in SCEV nodes can *not*
+// not SCEVConstant). Notably, SCEFlags on SCEV nodes can *not*
// introduce poison -- they encode guaranteed, non-speculated knowledge.
//
// Additionally, all SCEV nodes propagate poison from inputs to outputs,
@@ -4579,8 +4575,7 @@ const SCEV *ScalarEvolution::getExistingSCEV(Value *V) {
}
/// Return a SCEV corresponding to -V = -1*V
-const SCEV *ScalarEvolution::getNegativeSCEV(const SCEV *V,
- SCEV::NoWrapFlags Flags) {
+const SCEV *ScalarEvolution::getNegativeSCEV(const SCEV *V, SCEVFlags Flags) {
if (const SCEVConstant *VC = dyn_cast<SCEVConstant>(V))
return getConstant(
cast<ConstantInt>(ConstantExpr::getNeg(VC->getValue())));
@@ -4660,8 +4655,7 @@ const SCEV *ScalarEvolution::removePointerBase(const SCEV *P) {
}
const SCEV *ScalarEvolution::getMinusSCEV(SCEVUse LHS, SCEVUse RHS,
- SCEV::NoWrapFlags Flags,
- unsigned Depth) {
+ SCEVFlags Flags, unsigned Depth) {
// Fast path: X - X --> 0.
if (LHS == RHS)
return getZero(LHS->getType());
@@ -5085,9 +5079,9 @@ void ScalarEvolution::inferNoWrapViaConstantRanges(const SCEVAddRecExpr *AR) {
}
}
-SCEV::NoWrapFlags
+SCEVFlags
ScalarEvolution::proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR) {
- SCEV::NoWrapFlags Result = AR->getNoWrapFlags();
+ SCEVFlags Result = AR->getNoWrapFlags();
if (AR->hasNoSignedWrap())
return Result;
@@ -5138,9 +5132,9 @@ ScalarEvolution::proveNoSignedWrapViaInduction(const SCEVAddRecExpr *AR) {
}
return Result;
}
-SCEV::NoWrapFlags
+SCEVFlags
ScalarEvolution::proveNoUnsignedWrapViaInduction(const SCEVAddRecExpr *AR) {
- SCEV::NoWrapFlags Result = AR->getNoWrapFlags();
+ SCEVFlags Result = AR->getNoWrapFlags();
if (AR->hasNoUnsignedWrap())
return Result;
@@ -5703,9 +5697,9 @@ bool PredicatedScalarEvolution::areAddRecsEqualWithPreds(
return true;
}
-static SCEV::NoWrapFlags
-getNoWrapFlagsForGEP(GEPOperator *GEP, const SCEV *Accum, ScalarEvolution &SE) {
- SCEV::NoWrapFlags Flags = SCEV::FlagNone;
+static SCEVFlags getNoWrapFlagsForGEP(GEPOperator *GEP, const SCEV *Accum,
+ ScalarEvolution &SE) {
+ SCEVFlags Flags = SCEV::FlagNone;
GEPNoWrapFlags NW = GEP->getNoWrapFlags();
// If the increment has any nowrap flags, then we know the address
// space cannot be wrapped around.
@@ -5735,7 +5729,7 @@ const SCEV *ScalarEvolution::createSimpleAffineAddRec(PHINode *PN,
assert(BEValueV && StartValueV);
const SCEV *Accum = nullptr;
- SCEV::NoWrapFlags Flags = SCEV::FlagNone;
+ SCEVFlags Flags = SCEV::FlagNone;
if (auto BO = MatchBinaryOp(BEValueV, getDataLayout(), AC, DT, PN)) {
if (BO->Opcode != Instruction::Add)
return nullptr;
@@ -5862,7 +5856,7 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
if (isLoopInvariant(Accum, L) ||
(isa<SCEVAddRecExpr>(Accum) &&
cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) {
- SCEV::NoWrapFlags Flags = SCEV::FlagNone;
+ SCEVFlags Flags = SCEV::FlagNone;
if (auto BO = MatchBinaryOp(BEValueV, getDataLayout(), AC, DT, PN)) {
if (BO->Opcode == Instruction::Add && BO->LHS == PN) {
@@ -6449,10 +6443,10 @@ static std::optional<ConstantRange> GetRangeFromMetadata(Value *V) {
return std::nullopt;
}
-void ScalarEvolution::setNoWrapFlags(SCEVAddRecExpr *AddRec,
- SCEV::NoWrapFlags Flags) {
- if (AddRec->getNoWrapFlags(Flags) != Flags) {
- AddRec->setNoWrapFlags(Flags);
+void ScalarEvolution::setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEVFlags Flags) {
+ SCEVFlags NWFlags = Flags & SCEV::FlagsNoWrapMask;
+ if (AddRec->getNoWrapFlags(NWFlags) != NWFlags) {
+ AddRec->setNoWrapFlags(NWFlags);
UnsignedRanges.erase(AddRec);
SignedRanges.erase(AddRec);
ConstantMultipleCache.erase(AddRec);
@@ -7114,7 +7108,7 @@ getRangeForAffineARHelper(APInt Step, const ConstantRange &StartRange,
!Overflow};
}
-std::pair<ConstantRange, SCEV::NoWrapFlags>
+std::pair<ConstantRange, SCEVFlags>
ScalarEvolution::getRangeForAffineAR(const SCEV *Start, const SCEV *Step,
const APInt &MaxBECount) {
assert(getTypeSizeInBits(Start->getType()) ==
@@ -7140,7 +7134,7 @@ ScalarEvolution::getRangeForAffineAR(const SCEV *Start, const SCEV *Step,
getUnsignedRangeMax(Step), getUnsignedRange(Start), MaxBECount,
/*Signed=*/false);
- SCEV::NoWrapFlags Flags = SCEV::FlagNone;
+ SCEVFlags Flags = SCEV::FlagNone;
if (NUW)
Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
if (NSW1 && NSW2)
@@ -7332,13 +7326,13 @@ ConstantRange ScalarEvolution::getRangeViaFactoring(const SCEV *Start,
return TrueRange.unionWith(FalseRange);
}
-SCEV::NoWrapFlags ScalarEvolution::getNoWrapFlagsFromUB(const Value *V) {
+SCEVFlags ScalarEvolution::getNoWrapFlagsFromUB(const Value *V) {
if (isa<ConstantExpr>(V))
return SCEV::FlagNone;
const BinaryOperator *BinOp = cast<BinaryOperator>(V);
// Return early if there are no flags to propagate to the SCEV.
- SCEV::NoWrapFlags Flags = SCEV::FlagNone;
+ SCEVFlags Flags = SCEV::FlagNone;
if (auto *PDI = dyn_cast<PossiblyDisjointInst>(BinOp);
PDI && PDI->isDisjoint()) {
Flags = ScalarEvolution::setFlags(SCEV::FlagNUW, SCEV::FlagNSW);
@@ -7882,7 +7876,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
// addition - they may not apply to other additions that can be
// formed with operands from AddOps.
const SCEV *RHS = getSCEV(BO->RHS);
- SCEV::NoWrapFlags Flags = getNoWrapFlagsFromUB(BO->Op);
+ SCEVFlags Flags = getNoWrapFlagsFromUB(BO->Op);
if (Flags != SCEV::FlagNone) {
const SCEV *LHS = getSCEV(BO->LHS);
if (BO->Opcode == Instruction::Sub)
@@ -7920,7 +7914,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
break;
}
- SCEV::NoWrapFlags Flags = getNoWrapFlagsFromUB(BO->Op);
+ SCEVFlags Flags = getNoWrapFlagsFromUB(BO->Op);
if (Flags != SCEV::FlagNone) {
LHS = getSCEV(BO->LHS);
RHS = getSCEV(BO->RHS);
@@ -7950,7 +7944,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
RHS = getSCEV(BO->RHS);
return getURemExpr(LHS, RHS);
case Instruction::Sub: {
- SCEV::NoWrapFlags Flags = SCEV::FlagNone;
+ SCEVFlags Flags = SCEV::FlagNone;
if (BO->Op)
Flags = getNoWrapFlagsFromUB(BO->Op);
@@ -11768,12 +11762,11 @@ bool ScalarEvolution::isKnownPredicateViaNoOverflow(CmpPredicate Pred,
// consider them as X + 0 and Y + 0 respectively. C1 and C2 are returned via
// OutC1 and OutC2.
auto MatchBinaryAddToConst = [this](SCEVUse X, SCEVUse Y, APInt &OutC1,
- APInt &OutC2,
- SCEV::NoWrapFlags ExpectedFlags) {
+ APInt &OutC2, SCEVFlags ExpectedFlags) {
SCEVUse XNonConstOp, XConstOp;
SCEVUse YNonConstOp, YConstOp;
- SCEV::NoWrapFlags XFlagsPresent;
- SCEV::NoWrapFlags YFlagsPresent;
+ SCEVFlags XFlagsPresent;
+ SCEVFlags YFlagsPresent;
if (!splitBinaryAdd(X, XConstOp, XNonConstOp, XFlagsPresent)) {
XConstOp = getZero(X->getType());
@@ -11944,7 +11937,7 @@ bool ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,
// LatchBECount times. This means the backdege condition at Latch is
// equivalent to "{0,+,1} u< LatchBECount".
Type *Ty = LatchBECount->getType();
- auto NoWrapFlags = SCEV::NoWrapFlags(SCEV::FlagNUW | SCEV::FlagNW);
+ auto NoWrapFlags = SCEVFlags(SCEV::FlagNUW | SCEV::FlagNW);
const SCEV *LoopCounter =
getAddRecExpr(getZero(Ty), getOne(Ty), L, NoWrapFlags);
if (isImpliedCond(Pred, LHS, RHS, ICmpInst::ICMP_ULT, LoopCounter,
@@ -12422,7 +12415,7 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
}
bool ScalarEvolution::splitBinaryAdd(SCEVUse Expr, SCEVUse &L, SCEVUse &R,
- SCEV::NoWrapFlags &Flags) {
+ SCEVFlags &Flags) {
if (!match(Expr, m_scev_Add(m_SCEV(L), m_SCEV(R))))
return false;
@@ -12927,8 +12920,7 @@ static bool IsKnownPredicateViaAddRecStart(ScalarEvolution &SE,
return false;
const SCEVAddRecExpr *LAR = cast<SCEVAddRecExpr>(LHS);
const SCEVAddRecExpr *RAR = cast<SCEVAddRecExpr>(RHS);
- SCEV::NoWrapFlags NW = ICmpInst::isSigned(Pred) ?
- SCEV::FlagNSW : SCEV::FlagNUW;
+ SCEVFlags NW = ICmpInst::isSigned(Pred) ? SCEV::FlagNSW : SCEV::FlagNUW;
if (!LAR->getNoWrapFlags(NW) || !RAR->getNoWrapFlags(NW))
return false;
@@ -15530,7 +15522,7 @@ bool SCEVWrapPredicate::implies(const SCEVPredicate *N,
}
bool SCEVWrapPredicate::isAlwaysTrue() const {
- SCEV::NoWrapFlags ScevFlags = AR->getNoWrapFlags();
+ SCEVFlags ScevFlags = AR->getNoWrapFlags();
IncrementWrapFlags IFlags = Flags;
if (ScalarEvolution::setFlags(ScevFlags, SCEV::FlagNSW) == ScevFlags)
@@ -16329,7 +16321,7 @@ const SCEV *ScalarEvolution::LoopGuards::rewrite(const SCEV *Expr) const {
const DenseMap<const SCEV *, const SCEV *> ⤅
const SmallDenseSet<std::pair<const SCEV *, const SCEV *>> ≠
- SCEV::NoWrapFlags FlagMask = SCEV::FlagNone;
+ SCEVFlags FlagMask = SCEV::FlagNone;
public:
SCEVLoopGuardRewriter(ScalarEvolution &SE,
diff --git a/llvm/lib/Analysis/ScalarEvolutionDivision.cpp b/llvm/lib/Analysis/ScalarEvolutionDivision.cpp
index cb328a1f7dcba..5038ecf93a29c 100644
--- a/llvm/lib/Analysis/ScalarEvolutionDivision.cpp
+++ b/llvm/lib/Analysis/ScalarEvolutionDivision.cpp
@@ -139,9 +139,9 @@ void SCEVDivision::visitAddRecExpr(const SCEVAddRecExpr *Numerator) {
return cannotDivide(Numerator);
Quotient = SE.getAddRecExpr(StartQ, StepQ, Numerator->getLoop(),
- SCEV::NoWrapFlags::FlagNone);
+ SCEVFlags::FlagNone);
Remainder = SE.getAddRecExpr(StartR, StepR, Numerator->getLoop(),
- SCEV::NoWrapFlags::FlagNone);
+ SCEVFlags::FlagNone);
}
void SCEVDivision::visitAddExpr(const SCEVAddExpr *Numerator) {
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 7ce2542551fff..d8ad13994ca2a 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -277,9 +277,9 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) {
/// InsertBinop - Insert the specified binary operator, doing a small amount
/// of work to avoid inserting an obviously redundant operation, and hoisting
/// to an outer loop when the opportunity is there and it is safe.
-Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
- Value *LHS, Value *RHS,
- SCEV::NoWrapFlags Flags, bool IsSafeToHoist) {
+Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
+ Value *RHS, SCEVFlags Flags,
+ bool IsSafeToHoist) {
// Fold a binop with constant operands.
if (Constant *CLHS = dyn_cast<Constant>(LHS))
if (Constant *CRHS = dyn_cast<Constant>(RHS))
@@ -378,8 +378,7 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
/// loop-invariant portions of expressions, after considering what
/// can be folded using target addressing modes.
///
-Value *SCEVExpander::expandAddToGEP(SCEVUse Offset, Value *V,
- SCEV::NoWrapFlags Flags) {
+Value *SCEVExpander::expandAddToGEP(SCEVUse Offset, Value *V, SCEVFlags Flags) {
assert(!isa<Instruction>(V) ||
SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint()));
diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp
index a36083fb8b3bb..c9493f0c9d6d0 100644
--- a/polly/lib/Support/SCEVAffinator.cpp
+++ b/polly/lib/Support/SCEVAffinator.cpp
@@ -59,10 +59,10 @@ static bool isTooComplex(PWACtx PWAC) {
}
/// Return the flag describing the possible wrapping of @p Expr.
-static SCEV::NoWrapFlags getNoWrapFlags(const SCEV *Expr) {
+static SCEVFlags getNoWrapFlags(const SCEV *Expr) {
if (auto *NAry = dyn_cast<SCEVNAryExpr>(Expr))
return NAry->getNoWrapFlags();
- return SCEV::FlagsMask;
+ return SCEV::FlagsNoWrapMask;
}
static PWACtx combine(PWACtx PWAC0, PWACtx PWAC1,
More information about the llvm-commits
mailing list