[llvm] [polly] [SCEV] Rename SCEVNoWrapFlags to SCEVFlags (NFC) (PR #225179)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 01:17:03 PDT 2026


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/225179

>From ee88feadba83a30e1861b139e98d0fa6d30370ca Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 21 Sep 2026 20:20:32 +0100
Subject: [PATCH] [SCEV] Rename SCEVNoWrapFlags to SCEVFlags (NFC)

In preparation to extend the flags that ScalarEvolution can represent,
rename SCEVNoWrapFlags to the more general SCEVFlags. In particular, we
preserve the (get|set)NoWrapFlags interface, which simply masks the
no-wrap flags from the newly-introduced (get|set)Flags.

See also: #225065
---
 llvm/include/llvm/Analysis/IVDescriptors.h    |   9 +-
 llvm/include/llvm/Analysis/ScalarEvolution.h  | 107 +++++++-------
 .../Analysis/ScalarEvolutionExpressions.h     |  41 ++++--
 .../Analysis/ScalarEvolutionPatternMatch.h    |   4 +-
 .../Utils/ScalarEvolutionExpander.h           |   4 +-
 llvm/lib/Analysis/IVDescriptors.cpp           |   2 +-
 llvm/lib/Analysis/LoopAccessAnalysis.cpp      |   2 +-
 llvm/lib/Analysis/LoopCacheAnalysis.cpp       |   6 +-
 llvm/lib/Analysis/ScalarEvolution.cpp         | 130 ++++++++----------
 llvm/lib/Analysis/ScalarEvolutionDivision.cpp |   4 +-
 .../Utils/ScalarEvolutionExpander.cpp         |   9 +-
 polly/lib/Support/SCEVAffinator.cpp           |   4 +-
 12 files changed, 160 insertions(+), 162 deletions(-)

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



More information about the llvm-commits mailing list