[llvm] [IVDescriptors] Implement MonotonicDescriptor (PR #214490)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 10 02:21:10 PDT 2026


================
@@ -482,6 +483,67 @@ class InductionDescriptor {
   SmallVector<const SCEVPredicate *, 2> NoWrapPredicates;
 };
 
+/// A struct for saving information about monotonic variables.
+/// Monotonic variable can be considered as a "conditional" induction variable:
+/// its update happens only on loop iterations for which a certain predicate is
+/// satisfied. In this implementation the predicate is represented as an edge in
+/// loop CFG: variable is updated if this edge is executed on current loop
+/// iteration.
+class MonotonicDescriptor {
+public:
+  using Edge = std::pair<BasicBlock *, BasicBlock *>;
+
+  MonotonicDescriptor() = default;
+
+  /// Returns the PHIs that feed into the backedge of the monotonic PHI.
+  const SmallPtrSetImpl<PHINode *> &getChain() const { return Chain; }
+
+  /// Returns the instruction that updates the value of the monotonic PHI.
+  Instruction *getStepInst() const { return StepInst; }
+
+  /// Returns the edge where the monotonic value/PHI is updated when taken.
+  Edge getPredicateEdge() const { return PredEdge; }
+
+  /// Returns the expression that represents the monotonic PHI (match with
+  /// isMonotonicPHI) or monotonic value (match with isMonotonicVal). Note: The
+  /// conditional update is represented with a plain SCEVAddRec within the
+  /// expression, this only holds along the predicated edge.
+  const SCEVAddRecExpr *getExpr() const { return Expr; }
+
+  /// Returns true if \p PN is a monotonic variable in the loop \p L. If \p PN
+  /// is monotonic, the monotonic descriptor \p D will contain the data
+  /// describing this variable.
+  static bool isMonotonicPHI(PHINode *PN, const Loop *L,
+                             MonotonicDescriptor &Desc, ScalarEvolution &SE);
+
+  /// Returns true if \p Val is a monotonic variable in the loop \p L (in this
+  /// case, the value should transitively contain monotonic PHI as part of its
+  /// calculation).
+  static bool isMonotonicVal(Value *Val, const Loop *L,
+                             MonotonicDescriptor &Desc, ScalarEvolution &SE);
+
+private:
+  /// The PHIs that feed into the backedge update of the monotonic PHI.
+  SmallPtrSet<PHINode *, 1> Chain;
+
+  /// The instruction that updates the value of the monotonic PHI.
+  Instruction *StepInst = nullptr;
+
+  /// The predicated edge where the monotonic value/PHI is updated.
+  /// The common case is {StepInstBlock, StepInstBlock->getSingleSuccessor()}.
+  /// Note: StepInstBlock = StepInst->getParent().
+  Edge PredEdge = {};
+
+  /// Expression that represents the monotonic PHI (isMonotonicPHI) or monotonic
+  /// (isMonotonicVal). Within the expression, the conditional update is
+  /// represented as an (unconditional) SCEVAddRec.
+  const SCEVAddRecExpr *Expr = nullptr;
+
+  /// Set the SCEV expression for this descriptor. \p NewExpr must be an affine
+  /// SCEVAddRec.
+  bool setSCEV(const SCEV *NewExpr);
----------------
MacDue wrote:

In this case, this is just a private helper function. It's not an assert as this is used as part of the checks the descriptor has matched. 

https://github.com/llvm/llvm-project/pull/214490


More information about the llvm-commits mailing list