[llvm] [polly] [SCEV] Refactor SCEV flags, in preparation to extend (NFC) (PR #225179)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 07:24:41 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/225179
>From 1cfaf3f00d13eb9867a268ad3ffab66cada1f854 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] Refactor SCEV flags, in preparation to extend (NFC)
In preparation to extend the flags that ScalarEvolution can represent,
rename SCEV::NoWrapFlags to the more general SCEVFlags. This is a large
refactoring non-functional change.
See also: #225065
---
llvm/include/llvm/Analysis/IVDescriptors.h | 9 +-
llvm/include/llvm/Analysis/ScalarEvolution.h | 146 ++++----
.../Analysis/ScalarEvolutionExpressions.h | 54 +--
.../Analysis/ScalarEvolutionPatternMatch.h | 24 +-
.../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 | 332 +++++++++---------
llvm/lib/Analysis/ScalarEvolutionDivision.cpp | 4 +-
.../Analysis/ScalarEvolutionNormalization.cpp | 4 +-
.../Transforms/Scalar/LoopStrengthReduce.cpp | 10 +-
.../Utils/ScalarEvolutionExpander.cpp | 30 +-
.../Vectorize/LoopVectorizationLegality.cpp | 2 +-
llvm/lib/Transforms/Vectorize/VPlanUtils.cpp | 14 +-
llvm/unittests/Analysis/IVDescriptorsTest.cpp | 2 +-
.../Analysis/ScalarEvolutionTest.cpp | 100 +++---
.../Utils/ScalarEvolutionExpanderTest.cpp | 8 +-
polly/lib/Analysis/ScopInfo.cpp | 2 +-
polly/lib/CodeGen/IslNodeBuilder.cpp | 6 +-
polly/lib/Support/SCEVAffinator.cpp | 4 +-
21 files changed, 375 insertions(+), 390 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 85988fa18d858..5fc413e044fbc 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,30 +107,30 @@ 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 {
- FlagAnyWrap = 0, // No guarantee.
+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.
- NoWrapMask = (1 << 3) - 1,
- LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/NoWrapMask)
+ FlagsMask = (1 << 3) - 1,
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/FlagsMask)
};
class SCEV;
template <typename SCEVPtrT = const SCEV *>
-struct SCEVUseT : private PointerIntPair<SCEVPtrT, 2> {
- using Base = PointerIntPair<SCEVPtrT, 2>;
+struct SCEVUseT : private PointerIntPair<SCEVPtrT, 3> {
+ using Base = PointerIntPair<SCEVPtrT, 3>;
using Base::getOpaqueValue;
using Base::getPointer;
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 +149,20 @@ 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::NoWrapMask) 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::FlagsMask) const;
+
+ /// Return only the use-specific flags without the underlying SCEV's flags.
+ SCEVFlags getUseNoWrapFlags() const {
+ return getUseFlags() &
+ (SCEVFlags::FlagNUW | SCEVFlags::FlagNSW | SCEVFlags::FlagNW);
+ }
+ SCEVFlags getUseFlags() const {
+ SCEVFlags UseFlags = static_cast<SCEVFlags>(Base::getInt() << 1);
+ if (any(UseFlags & (SCEVFlags::FlagNUW | SCEVFlags::FlagNSW)))
+ UseFlags |= SCEVFlags::FlagNW;
return UseFlags;
}
@@ -193,18 +195,14 @@ template <typename SCEVPtrT> SCEVUseT(SCEVPtrT) -> SCEVUseT<SCEVPtrT>;
using SCEVUse = SCEVUseT<const SCEV *>;
/// The no-wrap flags to apply when creating a SCEV expression, to the
-/// expression and use respectively.
-struct SCEVFlags {
- /// Flags applied directly to a SCEV expression, must be valid wherever the
- /// expression is valid.
- SCEVNoWrapFlags ExprFlags;
-
- /// Flags only applied to a SCEVUse.
- SCEVNoWrapFlags UseFlags;
-
- constexpr SCEVFlags(SCEVNoWrapFlags ExprFlags = SCEVNoWrapFlags::FlagAnyWrap,
- SCEVNoWrapFlags UseFlags = SCEVNoWrapFlags::FlagAnyWrap)
- : ExprFlags(ExprFlags), UseFlags(UseFlags) {}
+/// expression and use: the first component of the pair is applied directly to a
+/// SCEV expression, and the second component is only applied to a SCEVUse.
+struct SCEVFlagInfo : public std::pair<SCEVFlags, SCEVFlags> {
+ using BaseT = std::pair<SCEVFlags, SCEVFlags>;
+
+ constexpr SCEVFlagInfo(SCEVFlags ExprFlags = SCEVFlags::FlagNone,
+ SCEVFlags UseFlags = SCEVFlags::FlagNone)
+ : BaseT(ExprFlags, UseFlags) {}
};
/// Provide PointerLikeTypeTraits for SCEVUse, so it can be used with
@@ -293,12 +291,11 @@ class SCEV : public FoldingSetNode {
Type *const Ty;
public:
- using NoWrapFlags = SCEVNoWrapFlags;
- static constexpr auto FlagAnyWrap = SCEVNoWrapFlags::FlagAnyWrap;
- static constexpr auto FlagNW = SCEVNoWrapFlags::FlagNW;
- static constexpr auto FlagNUW = SCEVNoWrapFlags::FlagNUW;
- static constexpr auto FlagNSW = SCEVNoWrapFlags::FlagNSW;
- static constexpr auto NoWrapMask = SCEVNoWrapFlags::NoWrapMask;
+ 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 FlagsMask = SCEVFlags::FlagsMask;
explicit SCEV(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
unsigned short ExpressionSize, Type *Ty)
@@ -642,20 +639,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 +711,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 +739,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::FlagAnyWrap);
+ 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,
@@ -760,26 +753,26 @@ class ScalarEvolution {
LLVM_ABI const SCEV *getAnyExtendExpr(SCEVUse Op, Type *Ty);
LLVM_ABI SCEVUse getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
- SCEVFlags Flags = {}, unsigned Depth = 0);
- SCEVUse getAddExpr(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags = {},
+ SCEVFlagInfo Flags = {}, unsigned Depth = 0);
+ SCEVUse getAddExpr(SCEVUse LHS, SCEVUse RHS, SCEVFlagInfo Flags = {},
unsigned Depth = 0) {
SmallVector<SCEVUse, 2> Ops = {LHS, RHS};
return getAddExpr(Ops, Flags, Depth);
}
SCEVUse getAddExpr(SCEVUse Op0, SCEVUse Op1, SCEVUse Op2,
- SCEVFlags Flags = {}, unsigned Depth = 0) {
+ SCEVFlagInfo Flags = {}, unsigned Depth = 0) {
SmallVector<SCEVUse, 3> Ops = {Op0, Op1, Op2};
return getAddExpr(Ops, Flags, Depth);
}
LLVM_ABI SCEVUse getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
- SCEVFlags Flags = {}, unsigned Depth = 0);
- SCEVUse getMulExpr(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags = {},
+ SCEVFlagInfo Flags = {}, unsigned Depth = 0);
+ SCEVUse getMulExpr(SCEVUse LHS, SCEVUse RHS, SCEVFlagInfo Flags = {},
unsigned Depth = 0) {
SmallVector<SCEVUse, 2> Ops = {LHS, RHS};
return getMulExpr(Ops, Flags, Depth);
}
SCEVUse getMulExpr(SCEVUse Op0, SCEVUse Op1, SCEVUse Op2,
- SCEVFlags Flags = {}, unsigned Depth = 0) {
+ SCEVFlagInfo Flags = {}, unsigned Depth = 0) {
SmallVector<SCEVUse, 3> Ops = {Op0, Op1, Op2};
return getMulExpr(Ops, Flags, Depth);
}
@@ -787,11 +780,11 @@ class ScalarEvolution {
LLVM_ABI const SCEV *getUDivExactExpr(SCEVUse LHS, SCEVUse RHS);
LLVM_ABI const SCEV *getURemExpr(SCEVUse LHS, SCEVUse RHS);
LLVM_ABI SCEVUse getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L,
- SCEVFlags Flags);
+ SCEVFlagInfo Flags);
LLVM_ABI SCEVUse getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
- const Loop *L, SCEVFlags Flags);
+ const Loop *L, SCEVFlagInfo Flags);
SCEVUse getAddRecExpr(const SmallVectorImpl<SCEVUse> &Operands, const Loop *L,
- SCEVFlags Flags) {
+ SCEVFlagInfo Flags) {
SmallVector<SCEVUse, 4> NewOp(Operands.begin(), Operands.end());
return getAddRecExpr(NewOp, L, Flags);
}
@@ -864,8 +857,8 @@ class ScalarEvolution {
unsigned FieldNo);
/// Return the SCEV object corresponding to -V.
- LLVM_ABI const SCEV *
- getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
+ 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 +871,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::FlagAnyWrap,
+ SCEVFlags Flags = SCEV::FlagNone,
unsigned Depth = 0);
/// Compute ceil(N / D). N and D are treated as unsigned values.
@@ -1574,7 +1567,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 +2011,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 +2229,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 +2394,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 +2435,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 +2448,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 +2547,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 +2793,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 ace050bd2c2c1..d59cec6864235 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -210,19 +210,18 @@ class SCEVNAryExpr : public SCEV {
ArrayRef<SCEVUse> operands() const { return ArrayRef(Operands, NumOperands); }
- NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
- return static_cast<NoWrapFlags>(SubclassData) & Mask;
+ SCEVFlags getFlags(SCEVFlags Mask = FlagsMask) const {
+ return static_cast<SCEVFlags>(SubclassData) & Mask;
}
-
- bool hasNoUnsignedWrap() const {
- return getNoWrapFlags(FlagNUW) != FlagAnyWrap;
+ SCEVFlags getNoWrapFlags(SCEVFlags Mask = FlagsMask) const {
+ return getFlags(Mask & (SCEV::FlagNUW | SCEV::FlagNSW | SCEV::FlagNW));
}
- bool hasNoSignedWrap() const {
- return getNoWrapFlags(FlagNSW) != FlagAnyWrap;
- }
+ bool hasNoUnsignedWrap() const { return getNoWrapFlags(FlagNUW) != FlagNone; }
- bool hasNoSelfWrap() const { return getNoWrapFlags(FlagNW) != FlagAnyWrap; }
+ bool hasNoSignedWrap() const { return getNoWrapFlags(FlagNSW) != FlagNone; }
+
+ bool hasNoSelfWrap() const { return getNoWrapFlags(FlagNW) != FlagNone; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEV *S) {
@@ -251,9 +250,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::FlagNUW | SCEV::FlagNSW | SCEV::FlagNW));
+ }
};
/// This node represents an addition of some number of SCEVs.
@@ -350,7 +352,7 @@ class SCEVAddRecExpr : public SCEVNAryExpr {
if (isAffine())
return getOperand(1);
return SE.getAddRecExpr(SmallVector<SCEVUse, 3>(operands().drop_front()),
- getLoop(), FlagAnyWrap);
+ getLoop(), FlagNone);
}
/// Return true if this represents an expression A + B*x where A
@@ -369,7 +371,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 & (FlagNUW | FlagNSW | FlagNW)))
+ return;
if (any(Flags & (FlagNUW | FlagNSW)))
Flags = ScalarEvolution::setFlags(Flags, FlagNW);
SubclassData |= static_cast<unsigned short>(Flags);
@@ -384,8 +388,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::FlagAnyWrap);
+ 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
@@ -511,9 +514,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::FlagNUW | SCEV::FlagNSW | SCEV::FlagNW));
+ }
protected:
/// Note: Constructing subclasses via this constructor is allowed
@@ -1005,26 +1011,30 @@ class SCEVLoopAddRecRewriter
};
template <typename SCEVPtrT>
-inline SCEVUseT<SCEVPtrT>::SCEVUseT(SCEVPtrT S, SCEVNoWrapFlags Flags)
- : Base(S, 0) {
+inline SCEVUseT<SCEVPtrT>::SCEVUseT(SCEVPtrT S, SCEVFlags Flags) : Base(S, 0) {
if (any(Flags)) {
assert((isa<SCEVAddExpr, SCEVMulExpr, SCEVAddRecExpr>(S)) &&
"use flags require an expression that can carry no-wrap flags");
// Drop flags already present on S.
- Flags &= ~cast<SCEVNAryExpr>(S)->getNoWrapFlags();
+ Flags &= ~cast<SCEVNAryExpr>(S)->getFlags();
}
Base::setInt(static_cast<unsigned>(Flags) >> 1);
}
template <typename SCEVPtrT>
-inline SCEVNoWrapFlags
-SCEVUseT<SCEVPtrT>::getNoWrapFlags(SCEVNoWrapFlags Mask) const {
- SCEVNoWrapFlags Flags = SCEVNoWrapFlags::FlagAnyWrap;
+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::FlagNUW | SCEVFlags::FlagNSW | SCEVFlags::FlagNW));
+}
+
} // 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 0ed08989e483b..0d37cb09b89f3 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h
@@ -200,8 +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::FlagAnyWrap,
- bool Commutable = false>
+ SCEVFlags WrapFlags = SCEV::FlagNone, bool Commutable = false>
struct SCEVBinaryExpr_match {
Op0_t Op0;
Op1_t Op1;
@@ -223,8 +222,7 @@ struct SCEVBinaryExpr_match {
};
template <typename SCEVTy, typename Op0_t, typename Op1_t,
- SCEV::NoWrapFlags WrapFlags = SCEV::FlagAnyWrap,
- 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,
@@ -244,10 +242,10 @@ m_scev_Mul(const Op0_t &Op0, const Op1_t &Op1) {
}
template <typename Op0_t, typename Op1_t>
-inline SCEVBinaryExpr_match<SCEVMulExpr, Op0_t, Op1_t, SCEV::FlagAnyWrap, true>
+inline SCEVBinaryExpr_match<SCEVMulExpr, Op0_t, Op1_t, SCEV::FlagNone, true>
m_scev_c_Mul(const Op0_t &Op0, const Op1_t &Op1) {
- return m_scev_Binary<SCEVMulExpr, Op0_t, Op1_t, SCEV::FlagAnyWrap, true>(Op0,
- Op1);
+ return m_scev_Binary<SCEVMulExpr, Op0_t, Op1_t, SCEV::FlagNone, true>(Op0,
+ Op1);
}
template <typename Op0_t, typename Op1_t>
@@ -264,17 +262,17 @@ m_scev_UDiv(const Op0_t &Op0, const Op1_t &Op1) {
}
template <typename Op0_t, typename Op1_t>
-inline SCEVBinaryExpr_match<SCEVSMaxExpr, Op0_t, Op1_t, SCEV::FlagAnyWrap, true>
+inline SCEVBinaryExpr_match<SCEVSMaxExpr, Op0_t, Op1_t, SCEV::FlagNone, true>
m_scev_SMax(const Op0_t &Op0, const Op1_t &Op1) {
- return m_scev_Binary<SCEVSMaxExpr, Op0_t, Op1_t, SCEV::FlagAnyWrap, true>(
- Op0, Op1);
+ return m_scev_Binary<SCEVSMaxExpr, Op0_t, Op1_t, SCEV::FlagNone, true>(Op0,
+ Op1);
}
template <typename Op0_t, typename Op1_t>
-inline SCEVBinaryExpr_match<SCEVUMaxExpr, Op0_t, Op1_t, SCEV::FlagAnyWrap, true>
+inline SCEVBinaryExpr_match<SCEVUMaxExpr, Op0_t, Op1_t, SCEV::FlagNone, true>
m_scev_UMax(const Op0_t &Op0, const Op1_t &Op1) {
- return m_scev_Binary<SCEVUMaxExpr, Op0_t, Op1_t, SCEV::FlagAnyWrap, true>(
- Op0, Op1);
+ return m_scev_Binary<SCEVUMaxExpr, Op0_t, Op1_t, SCEV::FlagNone, true>(Op0,
+ Op1);
}
template <typename Op0_t, typename Op1_t>
diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
index 4470de17518db..635437f98a0f7 100644
--- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
+++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
@@ -470,7 +470,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;
@@ -487,7 +487,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 d79624e071f3e..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::FlagAnyWrap;
+ 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 8b0e17f71ef66..409d9ceb5b812 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::NoWrapMask)))
+ if (any(AR->getNoWrapFlags(SCEV::FlagsMask)))
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 caf1b1a655632..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::FlagAnyWrap);
+ 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 1e91c6c2beb0c..9ddd2727f547f 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,9 +985,9 @@ 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::FlagAnyWrap) &&
+ assert((Operands.size() == 2 || UseFlags == SCEV::FlagNone) &&
"use-specific flags only supported for affine AddRecs");
SCEVUse Result = Operands[0].getPointer();
for (unsigned i = 1, e = Operands.size(); i != e; ++i) {
@@ -999,8 +999,8 @@ SCEVUse SCEVAddRecExpr::evaluateAtIteration(ArrayRef<SCEVUse> Operands,
return Coeff;
SCEVUse Mul = SE.getMulExpr(Operands[i].getPointer(), Coeff,
- {SCEV::FlagAnyWrap, UseFlags});
- Result = SE.getAddExpr(Result, Mul, {SCEV::FlagAnyWrap, UseFlags});
+ {SCEV::FlagNone, UseFlags});
+ Result = SE.getAddExpr(Result, Mul, {SCEV::FlagNone, UseFlags});
}
return Result;
}
@@ -1013,7 +1013,7 @@ SCEVUse SCEVAddRecExpr::getExitValue(ScalarEvolution &SE) const {
// is the value it had, and that did not wrap.
return evaluateAtIteration(operands(), BTC, SE,
isAffine() ? getNoWrapFlags(SCEV::FlagNUW)
- : SCEV::FlagAnyWrap);
+ : SCEV::FlagNone);
}
//===----------------------------------------------------------------------===//
@@ -1189,7 +1189,7 @@ const SCEV *ScalarEvolution::getTruncateExpr(SCEVUse Op, Type *Ty,
SmallVector<SCEVUse, 4> Operands;
for (const SCEV *Op : AddRec->operands())
Operands.push_back(getTruncateExpr(Op, Ty, Depth + 1));
- return getAddRecExpr(Operands, AddRec->getLoop(), SCEV::FlagAnyWrap);
+ return getAddRecExpr(Operands, AddRec->getLoop(), SCEV::FlagNone);
}
// Return zero if truncating to known zeros.
@@ -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;
@@ -1336,10 +1336,10 @@ static const SCEV *getPreStartForExtend(const SCEVAddRecExpr *AR,
// 1. NSW/NUW flags on the step increment.
auto PreStartFlags =
- ScalarEvolution::maskFlags(SA->getNoWrapFlags(), SCEV::FlagNUW);
+ ScalarEvolution::maskFlags(SA->getNoWrapFlags(), SCEV::FlagNUW);
const SCEV *PreStart = SE->getAddExpr(DiffOps, PreStartFlags);
const SCEVAddRecExpr *PreAR = dyn_cast<SCEVAddRecExpr>(
- SE->getAddRecExpr(PreStart, Step, L, SCEV::FlagAnyWrap));
+ SE->getAddRecExpr(PreStart, Step, L, SCEV::FlagNone));
// "{S,+,X} is <nsw>/<nuw>" and "the backedge is taken at least once" implies
// "S+X does not sign/unsign-overflow".
@@ -1639,9 +1639,9 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(SCEVUse Op, Type *Ty,
Type *WideTy = IntegerType::get(getContext(), BitWidth * 2);
// Check whether Start+Step*MaxBECount has no unsigned overflow.
const SCEV *ZMul =
- getMulExpr(CastedMaxBECount, Step, SCEV::FlagAnyWrap, Depth + 1);
+ getMulExpr(CastedMaxBECount, Step, SCEV::FlagNone, Depth + 1);
const SCEV *ZAdd = getZeroExtendExpr(
- getAddExpr(Start, ZMul, SCEV::FlagAnyWrap, Depth + 1), WideTy,
+ getAddExpr(Start, ZMul, SCEV::FlagNone, Depth + 1), WideTy,
Depth + 1);
const SCEV *WideStart = getZeroExtendExpr(Start, WideTy, Depth + 1);
const SCEV *WideMaxBECount =
@@ -1650,8 +1650,8 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(SCEVUse Op, Type *Ty,
getAddExpr(WideStart,
getMulExpr(WideMaxBECount,
getZeroExtendExpr(Step, WideTy, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1);
+ SCEV::FlagNone, Depth + 1),
+ SCEV::FlagNone, Depth + 1);
if (ZAdd == OperandExtendedAdd) {
// Cache knowledge of AR NUW, which is propagated to this AddRec.
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNUW);
@@ -1667,8 +1667,8 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(SCEVUse Op, Type *Ty,
getAddExpr(WideStart,
getMulExpr(WideMaxBECount,
getSignExtendExpr(Step, WideTy, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1);
+ SCEV::FlagNone, Depth + 1),
+ SCEV::FlagNone, Depth + 1);
if (ZAdd == OperandExtendedAdd) {
// Cache knowledge of AR NW, which is propagated to this AddRec.
// Negative step causes unsigned wrap, but it still can't self-wrap.
@@ -1801,7 +1801,7 @@ const SCEV *ScalarEvolution::getZeroExtendExprImpl(SCEVUse Op, Type *Ty,
if (D != 0) {
const SCEV *SZExtD = getZeroExtendExpr(getConstant(D), Ty, Depth);
const SCEV *SResidual =
- getAddExpr(getConstant(-D), SA, SCEV::FlagAnyWrap, Depth);
+ getAddExpr(getConstant(-D), SA, SCEV::FlagNone, Depth);
const SCEV *SZExtR = getZeroExtendExpr(SResidual, Ty, Depth + 1);
return getAddExpr(SZExtD, SZExtR, (SCEV::FlagNSW | SCEV::FlagNUW),
Depth + 1);
@@ -1990,7 +1990,7 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
if (D != 0) {
const SCEV *SSExtD = getSignExtendExpr(getConstant(D), Ty, Depth);
const SCEV *SResidual =
- getAddExpr(getConstant(-D), SA, SCEV::FlagAnyWrap, Depth);
+ getAddExpr(getConstant(-D), SA, SCEV::FlagNone, Depth);
const SCEV *SSExtR = getSignExtendExpr(SResidual, Ty, Depth + 1);
return getAddExpr(SSExtD, SSExtR, (SCEV::FlagNSW | SCEV::FlagNUW),
Depth + 1);
@@ -2030,9 +2030,9 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
Type *WideTy = IntegerType::get(getContext(), BitWidth * 2);
// Check whether Start+Step*MaxBECount has no signed overflow.
const SCEV *SMul =
- getMulExpr(CastedMaxBECount, Step, SCEV::FlagAnyWrap, Depth + 1);
+ getMulExpr(CastedMaxBECount, Step, SCEV::FlagNone, Depth + 1);
const SCEV *SAdd = getSignExtendExpr(
- getAddExpr(Start, SMul, SCEV::FlagAnyWrap, Depth + 1), WideTy,
+ getAddExpr(Start, SMul, SCEV::FlagNone, Depth + 1), WideTy,
Depth + 1);
const SCEV *WideStart = getSignExtendExpr(Start, WideTy, Depth + 1);
const SCEV *WideMaxBECount =
@@ -2041,8 +2041,8 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
getAddExpr(WideStart,
getMulExpr(WideMaxBECount,
getSignExtendExpr(Step, WideTy, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1);
+ SCEV::FlagNone, Depth + 1),
+ SCEV::FlagNone, Depth + 1);
if (SAdd == OperandExtendedAdd) {
// Cache knowledge of AR NSW, which is propagated to this AddRec.
setNoWrapFlags(const_cast<SCEVAddRecExpr *>(AR), SCEV::FlagNSW);
@@ -2058,8 +2058,8 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(SCEVUse Op, Type *Ty,
getAddExpr(WideStart,
getMulExpr(WideMaxBECount,
getZeroExtendExpr(Step, WideTy, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1);
+ SCEV::FlagNone, Depth + 1),
+ SCEV::FlagNone, Depth + 1);
if (SAdd == OperandExtendedAdd) {
// If AR wraps around then
//
@@ -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::FlagAnyWrap;
+ 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.
@@ -2515,10 +2512,10 @@ 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,
- SCEVFlags Flags, unsigned Depth) {
- SCEV::NoWrapFlags OrigFlags = Flags.ExprFlags;
- SCEV::NoWrapFlags UseFlags = Flags.UseFlags;
- assert(!(OrigFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
+ SCEVFlagInfo Flags, unsigned Depth) {
+ SCEVFlags ExprFlags, UseFlags;
+ std::tie(ExprFlags, UseFlags) = Flags;
+ assert(!(ExprFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
"only nuw or nsw allowed");
assert(!(UseFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
"only nuw or nsw allowed");
@@ -2551,8 +2548,8 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
unsigned Idx = isa<SCEVConstant>(Ops[0]) ? 1 : 0;
// Delay expensive flag strengthening until necessary.
- auto ComputeFlags = [this, OrigFlags](ArrayRef<SCEVUse> Ops) {
- return StrengthenNoWrapFlags(this, scAddExpr, Ops, OrigFlags);
+ auto ComputeFlags = [this, ExprFlags](ArrayRef<SCEVUse> Ops) {
+ return StrengthenNoWrapFlags(this, scAddExpr, Ops, ExprFlags);
};
// Limit recursion calls depth.
@@ -2562,7 +2559,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
if (SCEV *S = findExistingSCEVInCache(scAddExpr, Ops)) {
// Don't strengthen flags if we have no new information.
SCEVAddExpr *Add = static_cast<SCEVAddExpr *>(S);
- if (Add->getNoWrapFlags(OrigFlags) != OrigFlags)
+ if (Add->getNoWrapFlags(ExprFlags) != ExprFlags)
Add->setNoWrapFlags(ComputeFlags(Ops));
return {S, UseFlags};
}
@@ -2580,7 +2577,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
++Count;
// Merge the values into a multiply.
SCEVUse Scale = getConstant(Ty, Count);
- const SCEV *Mul = getMulExpr(Scale, Ops[i], SCEV::FlagAnyWrap, Depth + 1);
+ const SCEV *Mul = getMulExpr(Scale, Ops[i], SCEV::FlagNone, Depth + 1);
if (Ops.size() == Count)
return Mul;
Ops[i] = Mul;
@@ -2589,7 +2586,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
FoundMatch = true;
}
if (FoundMatch)
- return getAddExpr(Ops, OrigFlags, Depth + 1);
+ return getAddExpr(Ops, ExprFlags, Depth + 1);
// Check for truncates. If all the operands are truncated from the same
// type, see if factoring out the truncate would permit the result to be
@@ -2641,7 +2638,8 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
}
}
if (Ok)
- LargeOps.push_back(getMulExpr(LargeMulOps, SCEV::FlagAnyWrap, Depth + 1));
+ LargeOps.push_back(
+ getMulExpr(LargeMulOps, SCEV::FlagNone, Depth + 1));
} else {
Ok = false;
break;
@@ -2649,7 +2647,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
}
if (Ok) {
// Evaluate the expression in the larger type.
- const SCEV *Fold = getAddExpr(LargeOps, SCEV::FlagAnyWrap, Depth + 1);
+ const SCEV *Fold = getAddExpr(LargeOps, SCEV::FlagNone, Depth + 1);
// If it folds to something simple, use it. Otherwise, don't.
if (isa<SCEVConstant>(Fold) || isa<SCEVUnknown>(Fold))
return getTruncateExpr(Fold, Ty);
@@ -2667,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::FlagAnyWrap;
+ SCEVFlags PreservedFlags = SCEV::FlagNone;
APInt ConstAdd = C1 + C2;
auto AddFlags = AddExpr->getNoWrapFlags();
@@ -2687,7 +2685,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
ScalarEvolution::setFlags(PreservedFlags, SCEV::FlagNSW);
}
- if (PreservedFlags != SCEV::FlagAnyWrap) {
+ if (PreservedFlags != SCEV::FlagNone) {
SmallVector<SCEVUse, 4> NewOps(AddExpr->operands());
NewOps[0] = getConstant(ConstAdd);
return getAddExpr(NewOps, PreservedFlags);
@@ -2702,7 +2700,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
if (NarrowA == getNegativeSCEV(InnerAdd->getOperand(0)) &&
getZeroExtendExpr(NarrowA, B->getType()) == A &&
hasFlags(StrengthenNoWrapFlags(this, scAddExpr, {NarrowA, InnerAdd},
- SCEV::FlagAnyWrap),
+ SCEV::FlagNone),
SCEV::FlagNUW)) {
return getZeroExtendExpr(getAddExpr(NarrowA, InnerAdd), B->getType());
}
@@ -2727,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(OrigFlags, SCEV::FlagNUW);
+ SCEVFlags CommonFlags = maskFlags(ExprFlags, SCEV::FlagNUW);
while (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[Idx])) {
if (Ops.size() > AddOpsInlineThreshold ||
Add->getNumOperands() > AddOpsInlineThreshold)
@@ -2778,19 +2776,19 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
Ops.push_back(getConstant(AccumulatedConstant));
for (auto &MulOp : MulOpLists) {
if (MulOp.first == 1) {
- Ops.push_back(getAddExpr(MulOp.second, SCEV::FlagAnyWrap, Depth + 1));
+ Ops.push_back(getAddExpr(MulOp.second, SCEV::FlagNone, Depth + 1));
} else if (MulOp.first != 0) {
- Ops.push_back(getMulExpr(
- getConstant(MulOp.first),
- getAddExpr(MulOp.second, SCEV::FlagAnyWrap, Depth + 1),
- SCEV::FlagAnyWrap, Depth + 1));
+ Ops.push_back(
+ getMulExpr(getConstant(MulOp.first),
+ getAddExpr(MulOp.second, SCEV::FlagNone, Depth + 1),
+ SCEV::FlagNone, Depth + 1));
}
}
if (Ops.empty())
return getZero(Ty);
if (Ops.size() == 1)
return Ops[0];
- return getAddExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);
+ return getAddExpr(Ops, SCEV::FlagNone, Depth + 1);
}
}
@@ -2801,7 +2799,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
return M->getOperand(OpIdx == 0);
SmallVector<SCEVUse, 4> Remaining(M->operands().take_front(OpIdx));
append_range(Remaining, M->operands().drop_front(OpIdx + 1));
- return getMulExpr(Remaining, SCEV::FlagAnyWrap, Depth + 1);
+ return getMulExpr(Remaining, SCEV::FlagNone, Depth + 1);
};
// If we are adding something to a multiply expression, make sure the
@@ -2849,9 +2847,9 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
if (!Cofactors.empty()) {
Cofactors.push_back(StripFactor(Mul, MulOp));
- SCEVUse InnerSum = getAddExpr(Cofactors, SCEV::FlagAnyWrap, Depth + 1);
+ SCEVUse InnerSum = getAddExpr(Cofactors, SCEV::FlagNone, Depth + 1);
SCEVUse OuterMul =
- getMulExpr(MulOpSCEV, InnerSum, SCEV::FlagAnyWrap, Depth + 1);
+ getMulExpr(MulOpSCEV, InnerSum, SCEV::FlagNone, Depth + 1);
// DeadIndices does not include Idx (the anchor), hence +1.
if (Ops.size() == DeadIndices.size() + 1)
@@ -2866,7 +2864,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
Ops.erase(Ops.begin() + (Dead > Idx ? Dead - 1 : Dead));
Ops.push_back(OuterMul);
- return getAddExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);
+ return getAddExpr(Ops, SCEV::FlagNone, Depth + 1);
}
}
}
@@ -2897,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}
@@ -2915,12 +2913,12 @@ 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;
- if (AddFlags != SCEV::FlagAnyWrap) {
+ SCEVFlags AddFlags = Flags;
+ if (AddFlags != SCEV::FlagNone) {
auto *DefI = getDefiningScopeBound(LIOps);
auto *ReachI = &*AddRecLoop->getHeader()->begin();
if (!isGuaranteedToTransferExecutionTo(DefI, ReachI))
- AddFlags = SCEV::FlagAnyWrap;
+ AddFlags = SCEV::FlagNone;
}
AddRecOps[0] = getAddExpr(LIOps, AddFlags, Depth + 1);
@@ -2939,7 +2937,7 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
Ops[i] = NewRec;
break;
}
- return getAddExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);
+ return getAddExpr(Ops, SCEV::FlagNone, Depth + 1);
}
// Okay, if there weren't any loop invariants to be folded, check to see if
@@ -2969,14 +2967,14 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
}
AddRecOps[i] =
getAddExpr(AddRecOps[i], OtherAddRec->getOperand(i),
- SCEV::FlagAnyWrap, Depth + 1);
+ SCEV::FlagNone, Depth + 1);
}
Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
}
}
// Step size has changed, so we cannot guarantee no self-wraparound.
- Ops[Idx] = getAddRecExpr(AddRecOps, AddRecLoop, SCEV::FlagAnyWrap);
- return getAddExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);
+ Ops[Idx] = getAddRecExpr(AddRecOps, AddRecLoop, SCEV::FlagNone);
+ return getAddExpr(Ops, SCEV::FlagNone, Depth + 1);
}
}
@@ -2986,13 +2984,13 @@ SCEVUse ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
// Okay, it looks like we really DO need an add expr. Check to see if we
// already have one, otherwise create a new one.
- assert((UseFlags == SCEV::FlagAnyWrap || equal(OrigOps, Ops)) &&
+ assert((UseFlags == SCEV::FlagNone || equal(OrigOps, Ops)) &&
"Tried to add SCEVUse flags after operands changed");
return {getOrCreateAddExpr(Ops, ComputeFlags(Ops)), UseFlags};
}
const SCEV *ScalarEvolution::getOrCreateAddExpr(ArrayRef<SCEVUse> Ops,
- SCEV::NoWrapFlags Flags) {
+ SCEVFlags Flags) {
FoldingSetNodeID ID;
ID.AddInteger(scAddExpr);
for (SCEVUse Op : Ops)
@@ -3014,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)
@@ -3038,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)
@@ -3130,10 +3128,10 @@ static bool containsConstantInAddMulChain(const SCEV *StartExpr) {
/// Get a canonical multiply expression, or something simpler if possible.
SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
- SCEVFlags Flags, unsigned Depth) {
- SCEV::NoWrapFlags OrigFlags = Flags.ExprFlags;
- SCEV::NoWrapFlags UseFlags = Flags.UseFlags;
- assert(OrigFlags == maskFlags(OrigFlags, SCEV::FlagNUW | SCEV::FlagNSW) &&
+ SCEVFlagInfo Flags, unsigned Depth) {
+ SCEVFlags ExprFlags, UseFlags;
+ std::tie(ExprFlags, UseFlags) = Flags;
+ assert(ExprFlags == maskFlags(ExprFlags, SCEV::FlagNUW | SCEV::FlagNSW) &&
"only nuw or nsw allowed");
assert(UseFlags == maskFlags(UseFlags, SCEV::FlagNUW | SCEV::FlagNSW) &&
"only nuw or nsw allowed");
@@ -3162,8 +3160,8 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
#endif
// Delay expensive flag strengthening until necessary.
- auto ComputeFlags = [this, OrigFlags](const ArrayRef<SCEVUse> Ops) {
- return StrengthenNoWrapFlags(this, scMulExpr, Ops, OrigFlags);
+ auto ComputeFlags = [this, ExprFlags](const ArrayRef<SCEVUse> Ops) {
+ return StrengthenNoWrapFlags(this, scMulExpr, Ops, ExprFlags);
};
// Limit recursion calls depth.
@@ -3173,7 +3171,7 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
if (SCEV *S = findExistingSCEVInCache(scMulExpr, Ops)) {
// Don't strengthen flags if we have no new information.
SCEVMulExpr *Mul = static_cast<SCEVMulExpr *>(S);
- if (Mul->getNoWrapFlags(OrigFlags) != OrigFlags)
+ if (Mul->getNoWrapFlags(ExprFlags) != ExprFlags)
Mul->setNoWrapFlags(ComputeFlags(Ops));
return {S, UseFlags};
}
@@ -3190,9 +3188,9 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
const SCEV *Op0, *Op1;
if (match(Ops[1], m_scev_Add(m_SCEV(Op0), m_SCEV(Op1))) &&
containsConstantInAddMulChain(Ops[1])) {
- const SCEV *LHS = getMulExpr(LHSC, Op0, SCEV::FlagAnyWrap, Depth + 1);
- const SCEV *RHS = getMulExpr(LHSC, Op1, SCEV::FlagAnyWrap, Depth + 1);
- return getAddExpr(LHS, RHS, SCEV::FlagAnyWrap, Depth + 1);
+ const SCEV *LHS = getMulExpr(LHSC, Op0, SCEV::FlagNone, Depth + 1);
+ const SCEV *RHS = getMulExpr(LHSC, Op1, SCEV::FlagNone, Depth + 1);
+ return getAddExpr(LHS, RHS, SCEV::FlagNone, Depth + 1);
}
if (Ops[0]->isAllOnesValue()) {
@@ -3202,19 +3200,19 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
SmallVector<SCEVUse, 4> NewOps;
bool AnyFolded = false;
for (const SCEV *AddOp : Add->operands()) {
- const SCEV *Mul = getMulExpr(Ops[0], SCEVUse(AddOp),
- SCEV::FlagAnyWrap, Depth + 1);
+ const SCEV *Mul =
+ getMulExpr(Ops[0], SCEVUse(AddOp), SCEV::FlagNone, Depth + 1);
if (!isa<SCEVMulExpr>(Mul)) AnyFolded = true;
NewOps.push_back(Mul);
}
if (AnyFolded)
- return getAddExpr(NewOps, SCEV::FlagAnyWrap, Depth + 1);
+ return getAddExpr(NewOps, SCEV::FlagNone, Depth + 1);
} else if (const auto *AddRec = dyn_cast<SCEVAddRecExpr>(Ops[1])) {
// Negation preserves a recurrence's no self-wrap property.
SmallVector<SCEVUse, 4> Operands;
for (const SCEV *AddRecOp : AddRec->operands())
Operands.push_back(getMulExpr(Ops[0], SCEVUse(AddRecOp),
- SCEV::FlagAnyWrap, Depth + 1));
+ SCEV::FlagNone, Depth + 1));
// Let M be the minimum representable signed value. AddRec with nsw
// multiplied by -1 can have signed overflow if and only if it takes a
// value of M: M * (-1) would stay M and (M + 1) * (-1) would be the
@@ -3240,7 +3238,7 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
if (isa<SCEVConstant>(InnerAdd->getOperand(0)) &&
getZeroExtendExpr(NarrowC, Ops[1]->getType()) == LHSC &&
hasFlags(StrengthenNoWrapFlags(this, scMulExpr, {NarrowC, InnerAdd},
- SCEV::FlagAnyWrap),
+ SCEV::FlagNone),
SCEV::FlagNUW)) {
const SCEV *Res =
getMulExpr(NarrowC, InnerAdd, SCEV::FlagNUW, Depth + 1);
@@ -3297,7 +3295,7 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
// list, and they are not necessarily sorted. Recurse to resort and
// resimplify any operands we just acquired.
if (DeletedMul)
- return getMulExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);
+ return getMulExpr(Ops, SCEV::FlagNone, Depth + 1);
}
// If there are any add recurrences in the operands list, see if any other
@@ -3324,18 +3322,17 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
// NLI * LI * {Start,+,Step} --> NLI * {LI*Start,+,LI*Step}
SmallVector<SCEVUse, 4> NewOps;
NewOps.reserve(AddRec->getNumOperands());
- const SCEV *Scale = getMulExpr(LIOps, SCEV::FlagAnyWrap, Depth + 1);
+ const SCEV *Scale = getMulExpr(LIOps, SCEV::FlagNone, Depth + 1);
// If both the mul and addrec are nuw, we can preserve nuw.
// 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),
- SCEV::FlagAnyWrap, Depth + 1));
+ SCEV::FlagNone, Depth + 1));
if (hasFlags(Flags, SCEV::FlagNSW) && !hasFlags(Flags, SCEV::FlagNUW)) {
ConstantRange NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
@@ -3357,7 +3354,7 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
Ops[i] = NewRec;
break;
}
- return getMulExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);
+ return getMulExpr(Ops, SCEV::FlagNone, Depth + 1);
}
// Okay, if there weren't any loop invariants to be folded, check to see
@@ -3410,17 +3407,17 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
const SCEV *CoeffTerm = getConstant(Ty, Coeff);
const SCEV *Term1 = AddRec->getOperand(y-z);
const SCEV *Term2 = OtherAddRec->getOperand(z);
- SumOps.push_back(getMulExpr(CoeffTerm, Term1, Term2,
- SCEV::FlagAnyWrap, Depth + 1));
+ SumOps.push_back(
+ getMulExpr(CoeffTerm, Term1, Term2, SCEV::FlagNone, Depth + 1));
}
}
if (SumOps.empty())
SumOps.push_back(getZero(Ty));
- AddRecOps.push_back(getAddExpr(SumOps, SCEV::FlagAnyWrap, Depth + 1));
+ AddRecOps.push_back(getAddExpr(SumOps, SCEV::FlagNone, Depth + 1));
}
if (!Overflow) {
- const SCEV *NewAddRec = getAddRecExpr(AddRecOps, AddRec->getLoop(),
- SCEV::FlagAnyWrap);
+ const SCEV *NewAddRec =
+ getAddRecExpr(AddRecOps, AddRec->getLoop(), SCEV::FlagNone);
if (Ops.size() == 2) return NewAddRec;
Ops[Idx] = NewAddRec;
Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
@@ -3431,7 +3428,7 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
}
}
if (OpsModified)
- return getMulExpr(Ops, SCEV::FlagAnyWrap, Depth + 1);
+ return getMulExpr(Ops, SCEV::FlagNone, Depth + 1);
// Otherwise couldn't fold anything into this recurrence. Move onto the
// next one.
@@ -3439,7 +3436,7 @@ SCEVUse ScalarEvolution::getMulExpr(SmallVectorImpl<SCEVUse> &Ops,
// Okay, it looks like we really DO need an mul expr. Check to see if we
// already have one, otherwise create a new one.
- assert((UseFlags == SCEV::FlagAnyWrap || equal(OrigOps, Ops)) &&
+ assert((UseFlags == SCEV::FlagNone || equal(OrigOps, Ops)) &&
"Tried to add SCEVUse flags after operands changed");
return {getOrCreateMulExpr(Ops, ComputeFlags(Ops)), UseFlags};
}
@@ -3513,9 +3510,9 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
const APInt &DivInt = RHSC->getAPInt();
if (!StepInt.urem(DivInt) &&
getZeroExtendExpr(AR, ExtTy) ==
- getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
- getZeroExtendExpr(Step, ExtTy),
- AR->getLoop(), SCEV::FlagAnyWrap)) {
+ getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
+ getZeroExtendExpr(Step, ExtTy), AR->getLoop(),
+ SCEV::FlagNone)) {
SmallVector<SCEVUse, 4> Operands;
for (const SCEV *Op : AR->operands())
Operands.push_back(getUDivExpr(Op, RHS));
@@ -3530,7 +3527,7 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
getZeroExtendExpr(AR, ExtTy) ==
getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy),
getZeroExtendExpr(Step, ExtTy), AR->getLoop(),
- SCEV::FlagAnyWrap);
+ SCEV::FlagNone);
// With N <= C and both N, C as powers-of-2, the transformation
// {X,+,N}/C => {(X - X%N),+,N}/C preserves division results even
@@ -3546,7 +3543,7 @@ const SCEV *ScalarEvolution::getUDivExpr(SCEVUse LHS, SCEVUse RHS) {
!isa<SCEVAddExpr>(NewStart)) {
const SCEV *NewLHS =
getAddRecExpr(NewStart, Step, AR->getLoop(),
- NoWrap ? SCEV::FlagNW : SCEV::FlagAnyWrap);
+ NoWrap ? SCEV::FlagNW : SCEV::FlagNone);
if (LHS != NewLHS)
return getUDivExpr(NewLHS, RHS);
}
@@ -3682,7 +3679,7 @@ const SCEV *ScalarEvolution::getUDivExactExpr(SCEVUse LHS, SCEVUse RHS) {
/// Get an add recurrence expression for the specified loop. Simplify the
/// expression as much as possible.
SCEVUse ScalarEvolution::getAddRecExpr(SCEVUse Start, SCEVUse Step,
- const Loop *L, SCEVFlags Flags) {
+ const Loop *L, SCEVFlagInfo Flags) {
SmallVector<SCEVUse, 4> Operands;
Operands.push_back(Start);
if (const SCEVAddRecExpr *StepChrec = dyn_cast<SCEVAddRecExpr>(Step))
@@ -3690,8 +3687,7 @@ SCEVUse ScalarEvolution::getAddRecExpr(SCEVUse Start, SCEVUse Step,
append_range(Operands, StepChrec->operands());
// The use flags describe the two-operand recurrence, not the flattened
// one built here, so drop them just like the expression's NUW/NSW.
- return getAddRecExpr(Operands, L,
- maskFlags(Flags.ExprFlags, SCEV::FlagNW));
+ return getAddRecExpr(Operands, L, maskFlags(Flags.first, SCEV::FlagNW));
}
Operands.push_back(Step);
@@ -3701,9 +3697,8 @@ SCEVUse ScalarEvolution::getAddRecExpr(SCEVUse Start, SCEVUse Step,
/// Get an add recurrence expression for the specified loop. Simplify the
/// expression as much as possible.
SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
- const Loop *L, SCEVFlags NWFlags) {
- SCEV::NoWrapFlags Flags = NWFlags.ExprFlags;
- SCEV::NoWrapFlags UseFlags = NWFlags.UseFlags;
+ const Loop *L, SCEVFlagInfo Flags) {
+ auto [ExprFlags, UseFlags] = Flags;
assert(!(UseFlags & ~(SCEV::FlagNUW | SCEV::FlagNSW)) &&
"only nuw or nsw allowed");
if (Operands.size() == 1) return Operands[0];
@@ -3725,7 +3720,7 @@ SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
if (Operands.back()->isZero()) {
Operands.pop_back();
- return getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); // {X,+,0} --> X
+ return getAddRecExpr(Operands, L, SCEV::FlagNone); // {X,+,0} --> X
}
// It's tempting to want to call getConstantMaxBackedgeTakenCount count here and
@@ -3734,7 +3729,7 @@ SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
// meaningful BE count at this point (and if we don't, we'd be stuck
// with a SCEVCouldNotCompute as the cached BE count).
- Flags = StrengthenNoWrapFlags(this, scAddRecExpr, Operands, Flags);
+ ExprFlags = StrengthenNoWrapFlags(this, scAddRecExpr, Operands, ExprFlags);
// Canonicalize nested AddRecs in by nesting them in order of loop depth.
if (const SCEVAddRecExpr *NestedAR = dyn_cast<SCEVAddRecExpr>(Operands[0])) {
@@ -3756,8 +3751,8 @@ 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 =
- maskFlags(Flags, SCEV::FlagNW | NestedAR->getNoWrapFlags());
+ SCEVFlags OuterFlags =
+ maskFlags(ExprFlags, SCEV::FlagNW | NestedAR->getNoWrapFlags());
NestedOperands[0] = getAddRecExpr(Operands, L, OuterFlags);
AllInvariant = all_of(NestedOperands, [&](const SCEV *Op) {
@@ -3769,8 +3764,8 @@ 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 =
- maskFlags(NestedAR->getNoWrapFlags(), SCEV::FlagNW | Flags);
+ SCEVFlags InnerFlags =
+ maskFlags(NestedAR->getNoWrapFlags(), SCEV::FlagNW | ExprFlags);
return getAddRecExpr(NestedOperands, NestedLoop, InnerFlags);
}
}
@@ -3781,9 +3776,9 @@ SCEVUse ScalarEvolution::getAddRecExpr(SmallVectorImpl<SCEVUse> &Operands,
// Okay, it looks like we really DO need an addrec expr. Check to see if we
// already have one, otherwise create a new one.
- assert((UseFlags == SCEV::FlagAnyWrap || equal(OrigOperands, Operands)) &&
+ assert((UseFlags == SCEV::FlagNone || equal(OrigOperands, Operands)) &&
"Tried to add SCEVUse flags after operands changed");
- return {getOrCreateAddRecExpr(Operands, L, Flags), UseFlags};
+ return {getOrCreateAddRecExpr(Operands, L, ExprFlags), UseFlags};
}
const SCEV *ScalarEvolution::getGEPExpr(GEPOperator *GEP,
@@ -3809,7 +3804,7 @@ const SCEV *ScalarEvolution::getGEPExpr(GEPOperator *GEP,
const SCEV *ScalarEvolution::getGEPExpr(SCEVUse BaseExpr,
ArrayRef<SCEVUse> IndexExprs,
Type *SrcElementTy, GEPNoWrapFlags NW) {
- SCEV::NoWrapFlags OffsetWrap = SCEV::FlagAnyWrap;
+ SCEVFlags OffsetWrap = SCEV::FlagNone;
if (NW.hasNoUnsignedSignedWrap())
OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNSW);
if (NW.hasNoUnsignedWrap())
@@ -3862,7 +3857,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::FlagAnyWrap;
+ 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.");
@@ -3880,7 +3875,7 @@ SCEV *ScalarEvolution::findExistingSCEVInCache(SCEVTypes SCEVType,
}
const SCEV *ScalarEvolution::getAbsExpr(const SCEV *Op, bool IsNSW) {
- SCEV::NoWrapFlags Flags = IsNSW ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
+ SCEVFlags Flags = IsNSW ? SCEV::FlagNSW : SCEV::FlagNone;
return getSMaxExpr(Op, getNegativeSCEV(Op, Flags));
}
@@ -4117,7 +4112,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,
@@ -4578,8 +4573,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())));
@@ -4637,7 +4631,7 @@ const SCEV *ScalarEvolution::removePointerBase(const SCEV *P) {
Ops[0] = removePointerBase(Ops[0]);
// Don't try to transfer nowrap flags for now. We could in some cases
// (for example, if pointer operand of the AddRec is a SCEVUnknown).
- return getAddRecExpr(Ops, AddRec->getLoop(), SCEV::FlagAnyWrap);
+ return getAddRecExpr(Ops, AddRec->getLoop(), SCEV::FlagNone);
}
if (auto *Add = dyn_cast<SCEVAddExpr>(P)) {
// The base of an Add is the pointer operand.
@@ -4659,8 +4653,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());
@@ -4678,7 +4671,7 @@ const SCEV *ScalarEvolution::getMinusSCEV(SCEVUse LHS, SCEVUse RHS,
// We represent LHS - RHS as LHS + (-1)*RHS. This transformation
// makes it so that we cannot make much use of NUW.
- auto AddFlags = SCEV::FlagAnyWrap;
+ auto AddFlags = SCEV::FlagNone;
const bool RHSIsNotMinSigned =
!getSignedRangeMin(RHS).isMinSignedValue();
if (hasFlags(Flags, SCEV::FlagNSW)) {
@@ -4703,7 +4696,7 @@ const SCEV *ScalarEvolution::getMinusSCEV(SCEVUse LHS, SCEVUse RHS,
// relative to a loop that is to be found in a recurrence in LHS and
// not in RHS. Applying NSW to (-1)*M may then let the NSW have a
// larger scope than intended.
- auto NegFlags = RHSIsNotMinSigned ? SCEV::FlagNSW : SCEV::FlagAnyWrap;
+ auto NegFlags = RHSIsNotMinSigned ? SCEV::FlagNSW : SCEV::FlagNone;
return getAddExpr(LHS, getNegativeSCEV(RHS, NegFlags), AddFlags, Depth);
}
@@ -5084,9 +5077,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;
@@ -5137,9 +5130,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;
@@ -5553,7 +5546,7 @@ ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI
const SCEV *StartVal = getSCEV(StartValueV);
const SCEV *PHISCEV =
getAddRecExpr(getTruncateExpr(StartVal, TruncTy),
- getTruncateExpr(Accum, TruncTy), L, SCEV::FlagAnyWrap);
+ getTruncateExpr(Accum, TruncTy), L, SCEV::FlagNone);
// PHISCEV can be either a SCEVConstant or a SCEVAddRecExpr.
// ex: If truncated Accum is 0 and StartVal is a constant, then PHISCEV
@@ -5630,7 +5623,7 @@ ScalarEvolution::createAddRecFromPHIWithCastsImpl(const SCEVUnknown *SymbolicPHI
// which the casts had been folded away. The caller can rewrite SymbolicPHI
// into NewAR if it will also add the runtime overflow checks specified in
// Predicates.
- const SCEV *NewAR = getAddRecExpr(StartVal, Accum, L, SCEV::FlagAnyWrap);
+ const SCEV *NewAR = getAddRecExpr(StartVal, Accum, L, SCEV::FlagNone);
std::pair<const SCEV *, SmallVector<const SCEVPredicate *, 3>> PredRewrite =
std::make_pair(NewAR, Predicates);
@@ -5702,9 +5695,9 @@ bool PredicatedScalarEvolution::areAddRecsEqualWithPreds(
return true;
}
-static SCEV::NoWrapFlags
-getNoWrapFlagsForGEP(GEPOperator *GEP, const SCEV *Accum, ScalarEvolution &SE) {
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
+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.
@@ -5734,7 +5727,7 @@ const SCEV *ScalarEvolution::createSimpleAffineAddRec(PHINode *PN,
assert(BEValueV && StartValueV);
const SCEV *Accum = nullptr;
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
+ SCEVFlags Flags = SCEV::FlagNone;
if (auto BO = MatchBinaryOp(BEValueV, getDataLayout(), AC, DT, PN)) {
if (BO->Opcode != Instruction::Add)
return nullptr;
@@ -5861,7 +5854,7 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
if (isLoopInvariant(Accum, L) ||
(isa<SCEVAddRecExpr>(Accum) &&
cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) {
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
+ SCEVFlags Flags = SCEV::FlagNone;
if (auto BO = MatchBinaryOp(BEValueV, getDataLayout(), AC, DT, PN)) {
if (BO->Opcode == Instruction::Add && BO->LHS == PN) {
@@ -6448,8 +6441,7 @@ static std::optional<ConstantRange> GetRangeFromMetadata(Value *V) {
return std::nullopt;
}
-void ScalarEvolution::setNoWrapFlags(SCEVAddRecExpr *AddRec,
- SCEV::NoWrapFlags Flags) {
+void ScalarEvolution::setNoWrapFlags(SCEVAddRecExpr *AddRec, SCEVFlags Flags) {
if (AddRec->getNoWrapFlags(Flags) != Flags) {
AddRec->setNoWrapFlags(Flags);
UnsignedRanges.erase(AddRec);
@@ -7114,7 +7106,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 +7132,7 @@ ScalarEvolution::getRangeForAffineAR(const SCEV *Start, const SCEV *Step,
getUnsignedRangeMax(Step), getUnsignedRange(Start), MaxBECount,
/*Signed=*/false);
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
+ SCEVFlags Flags = SCEV::FlagNone;
if (NUW)
Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
if (NSW1 && NSW2)
@@ -7332,12 +7324,13 @@ ConstantRange ScalarEvolution::getRangeViaFactoring(const SCEV *Start,
return TrueRange.unionWith(FalseRange);
}
-SCEV::NoWrapFlags ScalarEvolution::getNoWrapFlagsFromUB(const Value *V) {
- if (isa<ConstantExpr>(V)) return SCEV::FlagAnyWrap;
+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::FlagAnyWrap;
+ SCEVFlags Flags = SCEV::FlagNone;
if (auto *PDI = dyn_cast<PossiblyDisjointInst>(BinOp);
PDI && PDI->isDisjoint()) {
Flags = ScalarEvolution::setFlags(SCEV::FlagNUW, SCEV::FlagNSW);
@@ -7347,10 +7340,10 @@ SCEV::NoWrapFlags ScalarEvolution::getNoWrapFlagsFromUB(const Value *V) {
if (BinOp->hasNoSignedWrap())
Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNSW);
}
- if (Flags == SCEV::FlagAnyWrap)
- return SCEV::FlagAnyWrap;
+ if (Flags == SCEV::FlagNone)
+ return SCEV::FlagNone;
- return isSCEVExprNeverPoison(BinOp) ? Flags : SCEV::FlagAnyWrap;
+ return isSCEVExprNeverPoison(BinOp) ? Flags : SCEV::FlagNone;
}
const Instruction *
@@ -7881,8 +7874,8 @@ 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);
- if (Flags != SCEV::FlagAnyWrap) {
+ SCEVFlags Flags = getNoWrapFlagsFromUB(BO->Op);
+ if (Flags != SCEV::FlagNone) {
const SCEV *LHS = getSCEV(BO->LHS);
if (BO->Opcode == Instruction::Sub)
AddOps.push_back(getMinusSCEV(LHS, RHS, Flags));
@@ -7919,8 +7912,8 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
break;
}
- SCEV::NoWrapFlags Flags = getNoWrapFlagsFromUB(BO->Op);
- if (Flags != SCEV::FlagAnyWrap) {
+ SCEVFlags Flags = getNoWrapFlagsFromUB(BO->Op);
+ if (Flags != SCEV::FlagNone) {
LHS = getSCEV(BO->LHS);
RHS = getSCEV(BO->RHS);
MulOps.push_back(getMulExpr(LHS, RHS, Flags));
@@ -7949,7 +7942,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
RHS = getSCEV(BO->RHS);
return getURemExpr(LHS, RHS);
case Instruction::Sub: {
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
+ SCEVFlags Flags = SCEV::FlagNone;
if (BO->Op)
Flags = getNoWrapFlagsFromUB(BO->Op);
@@ -8108,7 +8101,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
// turn a nuw nsw shl into a nuw nsw mul. However, nsw in isolation
// requires special handling. It can be preserved as long as we're not
// left shifting by bitwidth - 1.
- auto Flags = SCEV::FlagAnyWrap;
+ auto Flags = SCEV::FlagNone;
if (BO->Op) {
auto MulFlags = getNoWrapFlagsFromUB(BO->Op);
if (any(MulFlags & SCEV::FlagNSW) &&
@@ -11762,12 +11755,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());
@@ -11938,7 +11930,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,
@@ -12416,7 +12408,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;
@@ -12921,8 +12913,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;
@@ -13958,8 +13949,8 @@ const SCEV *SCEVAddRecExpr::getNumIterationsInRange(const ConstantRange &Range,
if (!SC->getValue()->isZero()) {
SmallVector<SCEVUse, 4> Operands(operands());
Operands[0] = SE.getZero(SC->getType());
- const SCEV *Shifted = SE.getAddRecExpr(Operands, getLoop(),
- getNoWrapFlags(FlagNW));
+ const SCEV *Shifted =
+ SE.getAddRecExpr(Operands, getLoop(), getNoWrapFlags(FlagNW));
if (const auto *ShiftedAddRec = dyn_cast<SCEVAddRecExpr>(Shifted))
return ShiftedAddRec->getNumIterationsInRange(
Range.subtract(SC->getAPInt()), SE);
@@ -14040,8 +14031,7 @@ SCEVAddRecExpr::getPostIncExpr(ScalarEvolution &SE) const {
const SCEV *Last = getOperand(getNumOperands() - 1);
assert(!Last->isZero() && "Recurrency with zero step?");
Ops.push_back(Last);
- return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, getLoop(),
- SCEV::FlagAnyWrap));
+ return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, getLoop(), SCEV::FlagNone));
}
// Return true when S contains at least an undef value.
@@ -15503,7 +15493,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)
@@ -16302,7 +16292,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::FlagAnyWrap;
+ SCEVFlags FlagMask = SCEV::FlagNone;
public:
SCEVLoopGuardRewriter(ScalarEvolution &SE,
diff --git a/llvm/lib/Analysis/ScalarEvolutionDivision.cpp b/llvm/lib/Analysis/ScalarEvolutionDivision.cpp
index bd12be7929959..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::FlagAnyWrap);
+ SCEVFlags::FlagNone);
Remainder = SE.getAddRecExpr(StartR, StepR, Numerator->getLoop(),
- SCEV::NoWrapFlags::FlagAnyWrap);
+ SCEVFlags::FlagNone);
}
void SCEVDivision::visitAddExpr(const SCEVAddExpr *Numerator) {
diff --git a/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp b/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
index bfc2d6aafdbfc..3666b2ead1521 100644
--- a/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
+++ b/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
@@ -52,7 +52,7 @@ NormalizeDenormalizeRewriter::visitAddRecExpr(const SCEVAddRecExpr *AR) {
[&](SCEVUse Op) { return visit(Op.getPointer()); });
if (!Pred(AR))
- return SE.getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagAnyWrap);
+ return SE.getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagNone);
// Normalization and denormalization are fancy names for decrementing and
// incrementing a SCEV expression with respect to a set of loops. Since
@@ -91,7 +91,7 @@ NormalizeDenormalizeRewriter::visitAddRecExpr(const SCEVAddRecExpr *AR) {
Operands[i] = SE.getMinusSCEV(Operands[i], Operands[i + 1]);
}
- return SE.getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagAnyWrap);
+ return SE.getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagNone);
}
const SCEV *llvm::normalizeForPostIncUse(const SCEV *S,
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 08a4a2f95033e..95117d9758958 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -565,7 +565,7 @@ static void DoInitialMatch(const SCEV *S, Loop *L,
DoInitialMatch(Start, L, Good, Bad, SE);
DoInitialMatch(SE.getAddRecExpr(SE.getConstant(S->getType(), 0), Step,
// FIXME: AR->getNoWrapFlags()
- ARLoop, SCEV::FlagAnyWrap),
+ ARLoop, SCEV::FlagNone),
L, Good, Bad, SE);
return;
}
@@ -868,7 +868,7 @@ static const SCEV *getExactSDiv(const SCEV *LHS, const SCEV *RHS,
// FlagNW is independent of the start value, step direction, and is
// preserved with smaller magnitude steps.
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
- return SE.getAddRecExpr(Start, Step, AR->getLoop(), SCEV::FlagAnyWrap);
+ return SE.getAddRecExpr(Start, Step, AR->getLoop(), SCEV::FlagNone);
}
return nullptr;
}
@@ -988,7 +988,7 @@ static Immediate ExtractImmediate(SCEVUse &S, ScalarEvolution &SE,
if (Result.isNonZero())
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
- SCEV::FlagAnyWrap);
+ SCEV::FlagNone);
return Result;
}
return ExtractImmediateOperand({S}, SE, PreferScalable);
@@ -1014,7 +1014,7 @@ static GlobalValue *ExtractSymbol(SCEVUse &S, ScalarEvolution &SE) {
if (Result)
S = SE.getAddRecExpr(NewOps, AR->getLoop(),
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
- SCEV::FlagAnyWrap);
+ SCEV::FlagNone);
return Result;
}
return nullptr;
@@ -3942,7 +3942,7 @@ static const SCEV *CollectSubexprs(const SCEV *S, const SCEVConstant *C,
return SE.getAddRecExpr(Remainder, Step,
cast<SCEVAddRecExpr>(S)->getLoop(),
// FIXME: AR->getNoWrapFlags(SCEV::FlagNW)
- SCEV::FlagAnyWrap);
+ SCEV::FlagNone);
}
} else if (match(S, m_scev_Mul(m_SCEVConstant(Op0), m_SCEV(Op1)))) {
// Break (C * (a + b + c)) into C*a + C*b + C*c.
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 3f698822449ed..d3377ab503a2e 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))
@@ -379,7 +379,7 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
/// can be folded using target addressing modes.
///
Value *SCEVExpander::expandAddToGEP(SCEVUse Offset, Value *V,
- SCEV::NoWrapFlags Flags) {
+ SCEVFlags Flags) {
assert(!isa<Instruction>(V) ||
SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint()));
@@ -532,7 +532,7 @@ Value *SCEVExpander::visitAddExpr(SCEVUseT<const SCEVAddExpr *> S) {
if (match(S, m_scev_URem(m_SCEV(URemLHS), m_SCEV(URemRHS), SE))) {
Value *LHS = expand(URemLHS);
Value *RHS = expand(URemRHS);
- return InsertBinop(Instruction::URem, LHS, RHS, SCEV::FlagAnyWrap,
+ return InsertBinop(Instruction::URem, LHS, RHS, SCEV::FlagNone,
/*IsSafeToHoist*/ false);
}
@@ -591,7 +591,7 @@ Value *SCEVExpander::visitAddExpr(SCEVUseT<const SCEVAddExpr *> S) {
} else if (Op->isNonConstantNegative()) {
// Instead of doing a negate and add, just do a subtract.
Value *W = expand(SE.getNegativeSCEV(Op));
- Sum = InsertBinop(Instruction::Sub, Sum, W, SCEV::FlagAnyWrap,
+ Sum = InsertBinop(Instruction::Sub, Sum, W, SCEV::FlagNone,
/*IsSafeToHoist*/ true);
++I;
} else {
@@ -624,7 +624,7 @@ Value *SCEVExpander::visitMulExpr(SCEVUseT<const SCEVMulExpr *> S) {
unsigned BitWidth = Ty->getScalarSizeInBits();
APInt Mask(APInt::getBitsSetFrom(BitWidth, ShAmtC));
Value *Res = InsertBinop(Instruction::And, LHS, ConstantInt::get(Ty, Mask),
- SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true);
+ SCEV::FlagNone, /*IsSafeToHoist*/ true);
return Res;
}
@@ -668,13 +668,13 @@ Value *SCEVExpander::visitMulExpr(SCEVUseT<const SCEVMulExpr *> S) {
if (Exponent & 1)
Result = P;
for (uint64_t BinExp = 2; BinExp <= Exponent; BinExp <<= 1) {
- P = InsertBinop(Instruction::Mul, P, P, SCEV::FlagAnyWrap,
+ P = InsertBinop(Instruction::Mul, P, P, SCEV::FlagNone,
/*IsSafeToHoist*/ true);
if (Exponent & BinExp)
- Result = Result ? InsertBinop(Instruction::Mul, Result, P,
- SCEV::FlagAnyWrap,
- /*IsSafeToHoist*/ true)
- : P;
+ Result = Result
+ ? InsertBinop(Instruction::Mul, Result, P, SCEV::FlagNone,
+ /*IsSafeToHoist*/ true)
+ : P;
}
I = E;
@@ -689,7 +689,7 @@ Value *SCEVExpander::visitMulExpr(SCEVUseT<const SCEVMulExpr *> S) {
} else if (I->second->isAllOnesValue()) {
// Instead of doing a multiply by negative one, just do a negate.
Prod = InsertBinop(Instruction::Sub, Constant::getNullValue(Ty), Prod,
- SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true);
+ SCEV::FlagNone, /*IsSafeToHoist*/ true);
++I;
} else {
// A simple mul.
@@ -724,7 +724,7 @@ Value *SCEVExpander::visitUDivExpr(SCEVUseT<const SCEVUDivExpr *> S) {
if (RHS.isPowerOf2())
return InsertBinop(Instruction::LShr, LHS,
ConstantInt::get(SC->getType(), RHS.logBase2()),
- SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true);
+ SCEV::FlagNone, /*IsSafeToHoist*/ true);
}
const SCEV *RHSExpr = S->getRHS();
@@ -742,7 +742,7 @@ Value *SCEVExpander::visitUDivExpr(SCEVUseT<const SCEVUDivExpr *> S) {
RHS = Builder.CreateIntrinsic(RHS->getType(), Intrinsic::umax,
{RHS, ConstantInt::get(RHS->getType(), 1)});
}
- return InsertBinop(Instruction::UDiv, LHS, RHS, SCEV::FlagAnyWrap,
+ return InsertBinop(Instruction::UDiv, LHS, RHS, SCEV::FlagNone,
/*IsSafeToHoist*/ SE.isKnownNonZero(S->getRHS()));
}
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 0c080d9434ea8..953b1a41e9ee2 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -523,7 +523,7 @@ class SCEVAddRecForUniformityRewriter
const SCEV *ScaledOffset = SE.getMulExpr(Step, SE.getConstant(Ty, Offset));
const SCEV *NewStart =
SE.getAddExpr(Expr->getStart(), SCEVUse(ScaledOffset));
- return SE.getAddRecExpr(NewStart, NewStep, TheLoop, SCEV::FlagAnyWrap);
+ return SE.getAddRecExpr(NewStart, NewStep, TheLoop, SCEV::FlagNone);
}
const SCEV *visit(const SCEV *S) {
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 6b2233f606f91..9a07697f66762 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -140,7 +140,7 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
if (!L)
return SE.getCouldNotCompute();
return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
- L, SCEV::FlagAnyWrap);
+ L, SCEV::FlagNone);
}
if (isa<VPIRValue, VPSymbolicValue>(V)) {
@@ -167,16 +167,16 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
VPValue *LHSVal, *RHSVal;
if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
- return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
+ return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
});
if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
- return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
+ return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
});
if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
- return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
+ return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagNone, 0);
});
if (match(V, m_Not(m_VPValue(LHSVal)))) {
// not X = xor X, -1 = -1 - X
@@ -186,7 +186,7 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
}
if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
- return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
+ return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
});
// Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
// amount >= the bit width produces poison; do not rewrite it, as
@@ -321,7 +321,7 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
const SCEV *Start =
getSCEVExprForVPValue(R->getStartValue(), PSE, L);
const SCEV *AddRec =
- SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
+ SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
if (R->getTruncInst())
return SE.getTruncateExpr(AddRec, R->getScalarType());
return AddRec;
@@ -335,7 +335,7 @@ const SCEV *vputils::getSCEVExprForVPValue(const VPValue *V,
const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
if (isa<SCEVCouldNotCompute>(Step))
return SE.getCouldNotCompute();
- return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
+ return SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
})
.Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) -> const SCEV * {
const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
diff --git a/llvm/unittests/Analysis/IVDescriptorsTest.cpp b/llvm/unittests/Analysis/IVDescriptorsTest.cpp
index 793b909116018..e9d71f0630a81 100644
--- a/llvm/unittests/Analysis/IVDescriptorsTest.cpp
+++ b/llvm/unittests/Analysis/IVDescriptorsTest.cpp
@@ -678,6 +678,6 @@ for.end:
EXPECT_EQ(Desc.getStepSCEV(), StepSCEV);
// Check we don't add `nuw` when we have a negative GEP step.
- EXPECT_EQ(Desc.getSCEVNoWrapFlags(), SCEV::FlagAnyWrap);
+ EXPECT_EQ(Desc.getSCEVNoWrapFlags(), SCEV::FlagNone);
});
}
diff --git a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index d362403626387..cf96ff83c219c 100644
--- a/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -430,18 +430,18 @@ TEST_F(ScalarEvolutionsTest, SCEVAddExpr) {
EXPECT_EQ(AddWithNUW->getNoWrapFlags(), SCEV::FlagNUW);
const SCEV *AddWithAnyWrap =
- SE.getAddExpr(SE.getSCEV(A3), SE.getSCEV(A4), SCEV::FlagAnyWrap);
+ SE.getAddExpr(SE.getSCEV(A3), SE.getSCEV(A4), SCEV::FlagNone);
auto *AddWithAnyWrapNUW = cast<SCEVAddExpr>(
SE.getAddExpr(AddWithAnyWrap, SE.getSCEV(A5), SCEV::FlagNUW));
EXPECT_EQ(AddWithAnyWrapNUW->getNumOperands(), 3u);
- EXPECT_EQ(AddWithAnyWrapNUW->getNoWrapFlags(), SCEV::FlagAnyWrap);
+ EXPECT_EQ(AddWithAnyWrapNUW->getNoWrapFlags(), SCEV::FlagNone);
const SCEV *AddWithNSW = SE.getAddExpr(
SE.getSCEV(A2), SE.getConstant(APInt(32, 99)), SCEV::FlagNSW);
auto *AddWithNSW_NUW = cast<SCEVAddExpr>(
SE.getAddExpr(AddWithNSW, SE.getSCEV(A5), SCEV::FlagNUW));
EXPECT_EQ(AddWithNSW_NUW->getNumOperands(), 3u);
- EXPECT_EQ(AddWithNSW_NUW->getNoWrapFlags(), SCEV::FlagAnyWrap);
+ EXPECT_EQ(AddWithNSW_NUW->getNoWrapFlags(), SCEV::FlagNone);
const SCEV *AddWithNSWNUW =
SE.getAddExpr(SE.getSCEV(A2), SE.getSCEV(A4),
@@ -455,7 +455,7 @@ TEST_F(ScalarEvolutionsTest, SCEVAddExpr) {
SE.getAddExpr(AddWithNSW, SE.getSCEV(A6),
ScalarEvolution::setFlags(SCEV::FlagNUW, SCEV::FlagNSW)));
EXPECT_EQ(AddWithNSW_NSWNUW->getNumOperands(), 3u);
- EXPECT_EQ(AddWithNSW_NSWNUW->getNoWrapFlags(), SCEV::FlagAnyWrap);
+ EXPECT_EQ(AddWithNSW_NSWNUW->getNoWrapFlags(), SCEV::FlagNone);
}
static Instruction &GetInstByName(Function &F, StringRef Name) {
@@ -546,12 +546,12 @@ TEST_F(ScalarEvolutionsTest, SCEVNormalization) {
auto GetAddRec = [&SE](const Loop *L,
std::initializer_list<const SCEV *> Ops) {
SmallVector<SCEVUse, 4> OpsCopy(Ops.begin(), Ops.end());
- return SE.getAddRecExpr(OpsCopy, L, SCEV::FlagAnyWrap);
+ return SE.getAddRecExpr(OpsCopy, L, SCEV::FlagNone);
};
auto GetAdd = [&SE](std::initializer_list<const SCEV *> Ops) {
SmallVector<SCEVUse, 4> OpsCopy(Ops.begin(), Ops.end());
- return SE.getAddExpr(OpsCopy, SCEV::FlagAnyWrap);
+ return SE.getAddExpr(OpsCopy, SCEV::FlagNone);
};
// We first populate the AddRecs vector with a few "interesting" SCEV
@@ -781,7 +781,7 @@ TEST_F(ScalarEvolutionsTest, SCEVExitLimitForgetLoop) {
// that is relevant to this test.
const SCEV *Five = SE.getConstant(APInt(/*numBits=*/64, 5));
const SCEV *AR =
- SE.getAddRecExpr(Five, SE.getOne(T_int64), Loop, SCEV::FlagAnyWrap);
+ SE.getAddRecExpr(Five, SE.getOne(T_int64), Loop, SCEV::FlagNone);
const SCEV *ARAtLoopExit = SE.getSCEVAtScope(AR, nullptr);
EXPECT_FALSE(isa<SCEVCouldNotCompute>(ARAtLoopExit));
EXPECT_TRUE(isa<SCEVConstant>(ARAtLoopExit));
@@ -1330,7 +1330,7 @@ TEST_F(ScalarEvolutionsTest, SCEVUseDropsRedundantFlags) {
// flags either, while FlagAnyWrap remains fine for them.
const SCEV *ZExt =
SE.getZeroExtendExpr(X, Type::getInt64Ty(F.getContext()));
- EXPECT_FALSE(SCEVUse(ZExt, SCEV::FlagAnyWrap).hasUseFlags());
+ EXPECT_FALSE(SCEVUse(ZExt, SCEV::FlagNone).hasUseFlags());
#ifndef NDEBUG
EXPECT_DEATH((void)SCEVUse(ZExt, SCEV::FlagNUW),
"use flags require an expression that can carry no-wrap");
@@ -2204,7 +2204,7 @@ TEST_F(ScalarEvolutionsTest, PrintUseFlagsOfOperands) {
SCEVUse UDiv = SE.getUDivExpr(NUWAdd, NSWAdd4);
EXPECT_EQ(Rendered(UDiv), "((%a + %b)<u nuw> /u (4 + %a)<u nsw>)");
- SCEVUse AR = SE.getAddRecExpr(NUWAdd, NSWAdd4, L, SCEV::FlagAnyWrap);
+ SCEVUse AR = SE.getAddRecExpr(NUWAdd, NSWAdd4, L, SCEV::FlagNone);
EXPECT_EQ(Rendered(AR), "{(%a + %b)<u nuw>,+,(4 + %a)<u nsw>}<%loop>");
// Casts print their operand as a use as well.
@@ -2261,8 +2261,8 @@ TEST_F(ScalarEvolutionsTest, OperandUseFlagsArePartOfIdentity) {
EXPECT_NE(SE.getMulExpr(MulNSW, Z), SE.getMulExpr(Add, Z));
EXPECT_NE(SE.getUDivExpr(MulNSW, Z), SE.getUDivExpr(Add, Z));
EXPECT_NE(SE.getUMaxExpr(MulNSW, Z), SE.getUMaxExpr(Add, Z));
- EXPECT_NE(SE.getAddRecExpr(MulNSW, Z, L, SCEV::FlagAnyWrap),
- SE.getAddRecExpr(Add, Z, L, SCEV::FlagAnyWrap));
+ EXPECT_NE(SE.getAddRecExpr(MulNSW, Z, L, SCEV::FlagNone),
+ SE.getAddRecExpr(Add, Z, L, SCEV::FlagNone));
SmallVector<SCEVUse, 2> FlaggedSeqOps = {MulNSW, Z};
SmallVector<SCEVUse, 2> BareSeqOps = {Add, Z};
EXPECT_NE(SE.getUMinExpr(FlaggedSeqOps, /*Sequential=*/true),
@@ -2398,7 +2398,7 @@ TEST_F(ScalarEvolutionsTest, AddExprUseFlags) {
Type *I32 = A->getType();
// The sum is built as-is, so the use carries the requested flags.
- SCEVUse Sum = SE.getAddExpr(A, B, {SCEV::FlagAnyWrap, SCEV::FlagNUW});
+ SCEVUse Sum = SE.getAddExpr(A, B, {SCEV::FlagNone, SCEV::FlagNUW});
EXPECT_TRUE(Sum.hasUseFlags());
EXPECT_EQ(Sum.getUseNoWrapFlags(), SCEV::FlagNUW | SCEV::FlagNW);
@@ -2406,16 +2406,16 @@ TEST_F(ScalarEvolutionsTest, AddExprUseFlags) {
const SCEV *BareSum = SE.getAddExpr(A, B);
EXPECT_EQ(Sum.getPointer(), BareSum);
EXPECT_EQ(cast<SCEVAddExpr>(BareSum)->getNoWrapFlags(SCEV::FlagNUW),
- SCEV::FlagAnyWrap);
+ SCEV::FlagNone);
EXPECT_EQ(Sum.getCanonical(), BareSum);
EXPECT_FALSE(SCEVUse(BareSum).hasUseFlags());
// Operands get sorted by complexity, so their order does not matter.
- EXPECT_EQ(SE.getAddExpr(B, A, {SCEV::FlagAnyWrap, SCEV::FlagNUW}), Sum);
+ EXPECT_EQ(SE.getAddExpr(B, A, {SCEV::FlagNone, SCEV::FlagNUW}), Sum);
// The same holds for sums of more than two operands.
SmallVector<SCEVUse, 3> Ops = {Cc, B, A};
- SCEVUse Sum3 = SE.getAddExpr(Ops, {SCEV::FlagAnyWrap, SCEV::FlagNSW});
+ SCEVUse Sum3 = SE.getAddExpr(Ops, {SCEV::FlagNone, SCEV::FlagNSW});
EXPECT_EQ(Sum3.getUseNoWrapFlags(), SCEV::FlagNSW | SCEV::FlagNW);
EXPECT_EQ(Sum3.getCanonical(), SE.getAddExpr(A, B, Cc));
@@ -2429,16 +2429,16 @@ TEST_F(ScalarEvolutionsTest, AddExprUseFlags) {
// the requested sum, so none of them may carry its flags.
auto CheckNoUseFlags = [](SCEVUse U) {
EXPECT_FALSE(U.hasUseFlags());
- EXPECT_EQ(U.getUseNoWrapFlags(), SCEV::FlagAnyWrap);
+ EXPECT_EQ(U.getUseNoWrapFlags(), SCEV::FlagNone);
};
CheckNoUseFlags(SE.getAddExpr(SE.getConstant(APInt(32, 1)),
SE.getConstant(APInt(32, 2)),
- {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ {SCEV::FlagNone, SCEV::FlagNUW}));
CheckNoUseFlags(
- SE.getAddExpr(A, SE.getZero(I32), {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ SE.getAddExpr(A, SE.getZero(I32), {SCEV::FlagNone, SCEV::FlagNUW}));
CheckNoUseFlags(SE.getAddExpr(A, SE.getAddExpr(B, Cc),
- {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
- CheckNoUseFlags(SE.getAddExpr(A, A, {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ {SCEV::FlagNone, SCEV::FlagNUW}));
+ CheckNoUseFlags(SE.getAddExpr(A, A, {SCEV::FlagNone, SCEV::FlagNUW}));
// SCEV flags are valid for all subsets and orders of the operands, so
// use-specific flags can be preserved when folding constants. the requested
@@ -2446,14 +2446,14 @@ TEST_F(ScalarEvolutionsTest, AddExprUseFlags) {
SmallVector<SCEVUse, 3> FoldedOps = {SE.getConstant(APInt(32, 1)),
SE.getConstant(APInt(32, 2)), A};
SCEVUse FoldedSum = SE.getAddExpr(
- FoldedOps, {SCEV::FlagAnyWrap, SCEV::FlagNUW | SCEV::FlagNSW});
+ FoldedOps, {SCEV::FlagNone, SCEV::FlagNUW | SCEV::FlagNSW});
EXPECT_EQ(FoldedSum.getCanonical(),
SE.getAddExpr(SE.getConstant(I32, 3), A));
EXPECT_EQ(FoldedSum.getUseNoWrapFlags(),
SCEV::FlagNUW | SCEV::FlagNSW | SCEV::FlagNW);
#ifndef NDEBUG
- EXPECT_DEATH((void)SE.getAddExpr(A, B, {SCEV::FlagAnyWrap, SCEV::FlagNW}),
+ EXPECT_DEATH((void)SE.getAddExpr(A, B, {SCEV::FlagNone, SCEV::FlagNW}),
"only nuw or nsw allowed");
#endif
});
@@ -2495,7 +2495,7 @@ TEST_F(ScalarEvolutionsTest, MulExprUseFlags) {
const SCEV *Three = SE.getConstant(I32, 3);
// The product is built as-is, use carries the requested flags.
- SCEVUse Prod = SE.getMulExpr(A, B, {SCEV::FlagAnyWrap, SCEV::FlagNUW});
+ SCEVUse Prod = SE.getMulExpr(A, B, {SCEV::FlagNone, SCEV::FlagNUW});
EXPECT_TRUE(Prod.hasUseFlags());
EXPECT_EQ(Prod.getUseNoWrapFlags(), SCEV::FlagNUW | SCEV::FlagNW);
@@ -2503,16 +2503,16 @@ TEST_F(ScalarEvolutionsTest, MulExprUseFlags) {
const SCEV *BareProd = SE.getMulExpr(A, B);
EXPECT_EQ(Prod.getPointer(), BareProd);
EXPECT_EQ(cast<SCEVMulExpr>(BareProd)->getNoWrapFlags(SCEV::FlagNUW),
- SCEV::FlagAnyWrap);
+ SCEV::FlagNone);
EXPECT_EQ(Prod.getCanonical(), BareProd);
EXPECT_FALSE(SCEVUse(BareProd).hasUseFlags());
// Operands get sorted by complexity, so their order does not matter.
- EXPECT_EQ(SE.getMulExpr(B, A, {SCEV::FlagAnyWrap, SCEV::FlagNUW}), Prod);
+ EXPECT_EQ(SE.getMulExpr(B, A, {SCEV::FlagNone, SCEV::FlagNUW}), Prod);
// The same holds for products of more than two operands.
SmallVector<SCEVUse, 3> Ops = {Cc, B, A};
- SCEVUse Prod3 = SE.getMulExpr(Ops, {SCEV::FlagAnyWrap, SCEV::FlagNSW});
+ SCEVUse Prod3 = SE.getMulExpr(Ops, {SCEV::FlagNone, SCEV::FlagNSW});
EXPECT_EQ(Prod3.getUseNoWrapFlags(), SCEV::FlagNSW | SCEV::FlagNW);
EXPECT_EQ(Prod3.getCanonical(), SE.getMulExpr(A, B, Cc));
@@ -2527,32 +2527,31 @@ TEST_F(ScalarEvolutionsTest, MulExprUseFlags) {
// carry its flags.
auto CheckNoUseFlags = [](SCEVUse U) {
EXPECT_FALSE(U.hasUseFlags());
- EXPECT_EQ(U.getUseNoWrapFlags(), SCEV::FlagAnyWrap);
+ EXPECT_EQ(U.getUseNoWrapFlags(), SCEV::FlagNone);
};
+ CheckNoUseFlags(SE.getMulExpr(Two, Three, {SCEV::FlagNone, SCEV::FlagNUW}));
CheckNoUseFlags(
- SE.getMulExpr(Two, Three, {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ SE.getMulExpr(A, SE.getOne(I32), {SCEV::FlagNone, SCEV::FlagNUW}));
CheckNoUseFlags(
- SE.getMulExpr(A, SE.getOne(I32), {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
- CheckNoUseFlags(
- SE.getMulExpr(A, SE.getZero(I32), {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ SE.getMulExpr(A, SE.getZero(I32), {SCEV::FlagNone, SCEV::FlagNUW}));
CheckNoUseFlags(SE.getMulExpr(A, SE.getMulExpr(B, Cc),
- {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ {SCEV::FlagNone, SCEV::FlagNUW}));
CheckNoUseFlags(SE.getMulExpr(Two, SE.getAddExpr(SE.getOne(I32), A),
- {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
- CheckNoUseFlags(SE.getMulExpr(Two, IV, {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ {SCEV::FlagNone, SCEV::FlagNUW}));
+ CheckNoUseFlags(SE.getMulExpr(Two, IV, {SCEV::FlagNone, SCEV::FlagNUW}));
// SCEV flags are valid for all subsets and orders of the operands, so
// use-specific flags can be preserved when folding constants.
SmallVector<SCEVUse, 3> FoldedOps = {Two, Three, A};
SCEVUse FoldedProd = SE.getMulExpr(
- FoldedOps, {SCEV::FlagAnyWrap, SCEV::FlagNUW | SCEV::FlagNSW});
+ FoldedOps, {SCEV::FlagNone, SCEV::FlagNUW | SCEV::FlagNSW});
EXPECT_EQ(FoldedProd.getCanonical(),
SE.getMulExpr(SE.getConstant(I32, 6), A));
EXPECT_EQ(FoldedProd.getUseNoWrapFlags(),
SCEV::FlagNUW | SCEV::FlagNSW | SCEV::FlagNW);
#ifndef NDEBUG
- EXPECT_DEATH((void)SE.getMulExpr(A, B, {SCEV::FlagAnyWrap, SCEV::FlagNW}),
+ EXPECT_DEATH((void)SE.getMulExpr(A, B, {SCEV::FlagNone, SCEV::FlagNW}),
"only nuw or nsw allowed");
#endif
});
@@ -2600,31 +2599,30 @@ TEST_F(ScalarEvolutionsTest, AddRecExprUseFlags) {
LI.getLoopFor(getInstructionByName(F, "iv.2")->getParent());
// The recurrence is built as-is, so the use carries the requested flags.
- SCEVUse AR = SE.getAddRecExpr(A, B, L1, {SCEV::FlagAnyWrap, SCEV::FlagNUW});
+ SCEVUse AR = SE.getAddRecExpr(A, B, L1, {SCEV::FlagNone, SCEV::FlagNUW});
EXPECT_TRUE(AR.hasUseFlags());
EXPECT_EQ(AR.getUseNoWrapFlags(), SCEV::FlagNUW | SCEV::FlagNW);
// Same as AR, but without NUW use flags.
- const SCEV *BareAR = SE.getAddRecExpr(A, B, L1, SCEV::FlagAnyWrap);
+ const SCEV *BareAR = SE.getAddRecExpr(A, B, L1, SCEV::FlagNone);
EXPECT_EQ(AR.getPointer(), BareAR);
- EXPECT_EQ(cast<SCEVAddRecExpr>(BareAR)->getNoWrapFlags(),
- SCEV::FlagAnyWrap);
+ EXPECT_EQ(cast<SCEVAddRecExpr>(BareAR)->getNoWrapFlags(), SCEV::FlagNone);
EXPECT_EQ(AR.getCanonical(), BareAR);
// Recurrence are not commutative, different operand orders must not re-use
// UseFlags.
SCEVUse Swapped =
- SE.getAddRecExpr(B, A, L1, {SCEV::FlagAnyWrap, SCEV::FlagNSW});
+ SE.getAddRecExpr(B, A, L1, {SCEV::FlagNone, SCEV::FlagNSW});
EXPECT_NE(Swapped.getPointer(), AR.getPointer());
EXPECT_EQ(Swapped.getUseNoWrapFlags(), SCEV::FlagNSW | SCEV::FlagNW);
// The same holds for recurrences with more than two operands.
SmallVector<SCEVUse, 3> Ops = {A, B, Cc};
- SCEVUse AR3 = SE.getAddRecExpr(Ops, L1, {SCEV::FlagAnyWrap, SCEV::FlagNSW});
+ SCEVUse AR3 = SE.getAddRecExpr(Ops, L1, {SCEV::FlagNone, SCEV::FlagNSW});
EXPECT_EQ(AR3.getUseNoWrapFlags(), SCEV::FlagNSW | SCEV::FlagNW);
SmallVector<SCEVUse, 3> BareOps = {A, B, Cc};
EXPECT_EQ(AR3.getCanonical(),
- SE.getAddRecExpr(BareOps, L1, SCEV::FlagAnyWrap));
+ SE.getAddRecExpr(BareOps, L1, SCEV::FlagNone));
// Flags the expression already carries add nothing to the use.
SCEVUse NUWAR = SE.getAddRecExpr(A, Cc, L1, {SCEV::FlagNUW, SCEV::FlagNUW});
@@ -2636,25 +2634,25 @@ TEST_F(ScalarEvolutionsTest, AddRecExprUseFlags) {
// different AddRec, so none of them may carry the provided use flags.
auto CheckNoUseFlags = [](SCEVUse U) {
EXPECT_FALSE(U.hasUseFlags());
- EXPECT_EQ(U.getUseNoWrapFlags(), SCEV::FlagAnyWrap);
+ EXPECT_EQ(U.getUseNoWrapFlags(), SCEV::FlagNone);
};
CheckNoUseFlags(SE.getAddRecExpr(A, SE.getZero(I32), L1,
- {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ {SCEV::FlagNone, SCEV::FlagNUW}));
SmallVector<SCEVUse, 3> OpsWithZeroStep = {A, B, SE.getZero(I32)};
- CheckNoUseFlags(SE.getAddRecExpr(OpsWithZeroStep, L1,
- {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
- const SCEV *StepAR = SE.getAddRecExpr(B, Cc, L1, SCEV::FlagAnyWrap);
CheckNoUseFlags(
- SE.getAddRecExpr(A, StepAR, L1, {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ SE.getAddRecExpr(OpsWithZeroStep, L1, {SCEV::FlagNone, SCEV::FlagNUW}));
+ const SCEV *StepAR = SE.getAddRecExpr(B, Cc, L1, SCEV::FlagNone);
+ CheckNoUseFlags(
+ SE.getAddRecExpr(A, StepAR, L1, {SCEV::FlagNone, SCEV::FlagNUW}));
// A zero step folds the recurrence away, use flags must not be applied to
// the result.
CheckNoUseFlags(SE.getAddRecExpr(BareAR, SE.getZero(I32), L2,
- {SCEV::FlagAnyWrap, SCEV::FlagNUW}));
+ {SCEV::FlagNone, SCEV::FlagNUW}));
#ifndef NDEBUG
EXPECT_DEATH(
- (void)SE.getAddRecExpr(A, B, L1, {SCEV::FlagAnyWrap, SCEV::FlagNW}),
+ (void)SE.getAddRecExpr(A, B, L1, {SCEV::FlagNone, SCEV::FlagNW}),
"only nuw or nsw allowed");
#endif
});
diff --git a/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp b/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp
index f2c0ad7d26a3c..76207f7260b9e 100644
--- a/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp
+++ b/llvm/unittests/Transforms/Utils/ScalarEvolutionExpanderTest.cpp
@@ -669,7 +669,7 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVExpandInsertCanonicalIV) {
// Expand {5,+,1}
auto GetAR2 = [&](ScalarEvolution &SE, Loop *L) -> const SCEV * {
return SE.getAddRecExpr(SE.getConstant(APInt(ARBitWidth, 5)),
- SE.getOne(ARType), L, SCEV::FlagAnyWrap);
+ SE.getOne(ARType), L, SCEV::FlagNone);
};
TestNoCanonicalIV(GetAR2);
TestNarrowCanonicalIV(GetAR2);
@@ -874,7 +874,7 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVExpandNonAffineAddRec) {
auto GetAR3 = [&](ScalarEvolution &SE, Loop *L) -> const SCEVAddRecExpr * {
SmallVector<SCEVUse, 3> Ops = {SE.getConstant(APInt(ARBitWidth, 5)),
SE.getOne(ARType), SE.getOne(ARType)};
- return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, L, SCEV::FlagAnyWrap));
+ return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, L, SCEV::FlagNone));
};
TestNoCanonicalIV(GetAR3);
TestNarrowCanonicalIV(GetAR3);
@@ -885,7 +885,7 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVExpandNonAffineAddRec) {
SmallVector<SCEVUse, 4> Ops = {SE.getConstant(APInt(ARBitWidth, 5)),
SE.getOne(ARType), SE.getOne(ARType),
SE.getOne(ARType)};
- return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, L, SCEV::FlagAnyWrap));
+ return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, L, SCEV::FlagNone));
};
TestNoCanonicalIV(GetAR4);
TestNarrowCanonicalIV(GetAR4);
@@ -896,7 +896,7 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVExpandNonAffineAddRec) {
SmallVector<SCEVUse, 5> Ops = {SE.getConstant(APInt(ARBitWidth, 5)),
SE.getOne(ARType), SE.getOne(ARType),
SE.getOne(ARType), SE.getOne(ARType)};
- return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, L, SCEV::FlagAnyWrap));
+ return cast<SCEVAddRecExpr>(SE.getAddRecExpr(Ops, L, SCEV::FlagNone));
};
TestNoCanonicalIV(GetAR5);
TestNarrowCanonicalIV(GetAR5);
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 38943f2557cf2..f0bb8ef35e5e0 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -1384,7 +1384,7 @@ class SCEVSensitiveParameterRewriter final
const SCEV *Start = visit(E->getStart());
const SCEV *AddRec = SE.getAddRecExpr(SE.getConstant(E->getType(), 0),
visit(E->getStepRecurrence(SE)),
- E->getLoop(), SCEV::FlagAnyWrap);
+ E->getLoop(), SCEV::FlagNone);
return SE.getAddExpr(Start, AddRec);
}
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index 50027f898b174..126cb756a4144 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -978,9 +978,9 @@ void IslNodeBuilder::generateCopyStmt(
Value *IslNodeBuilder::materializeNonScopLoopInductionVariable(const Loop *L) {
assert(!OutsideLoopIterations.contains(L) &&
"trying to materialize loop induction variable twice");
- const SCEV *OuterLIV = SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
- SE.getUnknown(Builder.getInt64(1)), L,
- SCEV::FlagAnyWrap);
+ const SCEV *OuterLIV =
+ SE.getAddRecExpr(SE.getUnknown(Builder.getInt64(0)),
+ SE.getUnknown(Builder.getInt64(1)), L, SCEV::FlagNone);
Value *V = generateSCEV(OuterLIV);
OutsideLoopIterations[L] = SE.getUnknown(V);
return V;
diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp
index 07155486bd1e1..73a7260934da1 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::NoWrapMask;
+ return SCEV::FlagsMask;
}
static PWACtx combine(PWACtx PWAC0, PWACtx PWAC1,
More information about the llvm-commits
mailing list