[llvm] 43cb5e4 - [IVDescriptors] Rename MonotonicDescriptor ConditionalInductionDescriptor (NFC) (#223707)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 02:13:08 PDT 2026


Author: Benjamin Maxwell
Date: 2026-09-16T10:13:03+01:00
New Revision: 43cb5e4766869fc13a104498f63906a64e37cf79

URL: https://github.com/llvm/llvm-project/commit/43cb5e4766869fc13a104498f63906a64e37cf79
DIFF: https://github.com/llvm/llvm-project/commit/43cb5e4766869fc13a104498f63906a64e37cf79.diff

LOG: [IVDescriptors] Rename MonotonicDescriptor ConditionalInductionDescriptor (NFC) (#223707)

Rename `MonotonicDescriptor` to `ConditionalInductionDescriptor` to
acknowledge that the phi may wrap, so is not strictly monotonic.

Assisted-by: Codex

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/IVDescriptors.h
    llvm/lib/Analysis/IVDescriptors.cpp
    llvm/unittests/Analysis/IVDescriptorsTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/IVDescriptors.h b/llvm/include/llvm/Analysis/IVDescriptors.h
index 837abbaf3ee22..7548ea1c871fe 100644
--- a/llvm/include/llvm/Analysis/IVDescriptors.h
+++ b/llvm/include/llvm/Analysis/IVDescriptors.h
@@ -483,20 +483,19 @@ 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. The step of the monotonic variable must be loop-invariant.
-class MonotonicDescriptor {
+/// Describes a conditional induction variable: an induction variable that is
+/// updated only on loop iterations for which a certain predicate is satisfied.
+/// Its step must be loop-invariant.
+class ConditionalInductionDescriptor {
 public:
-  MonotonicDescriptor() = default;
+  ConditionalInductionDescriptor() = default;
 
-  /// Returns true if \p PN is a monotonic variable in the loop \p L. If \p PN
-  /// is monotonic, the monotonic descriptor \p Desc will contain the data
-  /// describing the PHI.
-  LLVM_ABI static bool isMonotonicPHI(PHINode *PN, const Loop *L,
-                                      MonotonicDescriptor &Desc,
-                                      ScalarEvolution &SE);
+  /// Returns true if \p PN is a conditional induction variable in the loop
+  /// \p L. If it is, \p Desc will contain the data describing the PHI.
+  LLVM_ABI static bool
+  isConditionalInductionPHI(PHINode *PN, const Loop *L,
+                            ConditionalInductionDescriptor &Desc,
+                            ScalarEvolution &SE);
 
   /// Returns the header PHI described by this descriptor.
   PHINode *getHeaderPHI() const { return HeaderPHI; }
@@ -504,24 +503,25 @@ class MonotonicDescriptor {
   /// Returns the backedge PHI that selects between StepInst and the HeaderPHI.
   PHINode *getBackedgePHI() const { return BackedgePHI; }
 
-  /// Returns the instruction that updates the value of the monotonic PHI.
+  /// Returns the instruction that updates the conditional induction PHI.
   Instruction *getStepInst() const { return StepInst; }
 
-  /// Returns a SCEV expression for the initial value of the monotonic PHI.
+  /// Returns a SCEV expression for the initial value of the conditional
+  /// induction PHI.
   const SCEV *getStartSCEV() const { return StartSCEV; }
 
-  /// Returns a SCEV expression for the step of the monotonic PHI. This is
-  /// the value the monotonic PHI increments by on loop iterations where the
-  /// predicate is satisfied.
+  /// Returns a SCEV expression for the step of the conditional induction PHI.
+  /// This is the value it increments by when the predicate is satisfied.
   const SCEV *getStepSCEV() const { return StepSCEV; }
 
   /// Returns the SCEV no-wrap flags that apply to StepInst.
   SCEVNoWrapFlags getSCEVNoWrapFlags() const { return NoWrapFlags; }
 
 private:
-  MonotonicDescriptor(PHINode *HeaderPHI, PHINode *BackedgePHI,
-                      Instruction *StepInst, const SCEV *StartSCEV,
-                      const SCEV *StepSCEV, SCEVNoWrapFlags NoWrapFlags)
+  ConditionalInductionDescriptor(PHINode *HeaderPHI, PHINode *BackedgePHI,
+                                 Instruction *StepInst, const SCEV *StartSCEV,
+                                 const SCEV *StepSCEV,
+                                 SCEVNoWrapFlags NoWrapFlags)
       : HeaderPHI(HeaderPHI), BackedgePHI(BackedgePHI), StepInst(StepInst),
         StartSCEV(StartSCEV), StepSCEV(StepSCEV), NoWrapFlags(NoWrapFlags) {}
 
@@ -531,13 +531,15 @@ class MonotonicDescriptor {
   /// The backedge PHI that selects between StepInst and the HeaderPHI.
   PHINode *BackedgePHI = nullptr;
 
-  /// The instruction that updates the value of the monotonic PHI.
+  /// The instruction that updates the conditional induction PHI.
   Instruction *StepInst = nullptr;
 
-  /// SCEV expression representing the start value for the monotonic PHI.
+  /// SCEV expression representing the start value for the conditional
+  /// induction PHI.
   const SCEV *StartSCEV = nullptr;
 
-  /// SCEV expression representing the step value for the monotonic PHI.
+  /// SCEV expression representing the step value for the conditional induction
+  /// PHI.
   const SCEV *StepSCEV = nullptr;
 
   /// The SCEV no-wrap flags that apply to StepInst.

diff  --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index d9e9fabcebb77..d79624e071f3e 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -1697,21 +1697,21 @@ bool InductionDescriptor::isInductionPHI(
   return true;
 }
 
-// Recognize a monotonic PHI variable by matching the following pattern:
+// Recognize a conditional induction PHI by matching the following pattern:
 // loop_header:
-//   %monotonic_phi = phi [ %start, %preheader ], [ %latch_phi, %latch ]
+//   %conditional_iv = phi [ %start, %preheader ], [ %latch_phi, %latch ]
 //   br i1 %do_step, label %step_bb, label %latch
 //
 // step_bb:
-//   %step = add/gep %monotonic_phi, %step_val
+//   %step = add/gep %conditional_iv, %step_val
 //   br label %latch
 //
 // latch:
-//   %latch_phi = phi [ %monotonic_phi, %loop_header ], [ %step, %step_bb ]
+//   %latch_phi = phi [ %conditional_iv, %loop_header ], [ %step, %step_bb ]
 //   br label %loop_header
-bool MonotonicDescriptor::isMonotonicPHI(PHINode *PN, const Loop *L,
-                                         MonotonicDescriptor &Desc,
-                                         ScalarEvolution &SE) {
+bool ConditionalInductionDescriptor::isConditionalInductionPHI(
+    PHINode *PN, const Loop *L, ConditionalInductionDescriptor &Desc,
+    ScalarEvolution &SE) {
   BasicBlock *Preheader = L->getLoopPreheader();
   if (!Preheader)
     return false;
@@ -1733,7 +1733,7 @@ bool MonotonicDescriptor::isMonotonicPHI(PHINode *PN, const Loop *L,
       return false;
   }
 
-  // Find the step operation used to increment the value of the monotonic PHI.
+  // Find the step operation used to increment the conditional induction PHI.
   // TODO: Support chains of PHIs.
   Value *StepOp =
       find_singleton<Value>(BackedgePHI->incoming_values(),
@@ -1779,10 +1779,10 @@ bool MonotonicDescriptor::isMonotonicPHI(PHINode *PN, const Loop *L,
       NoWrapFlags = ScalarEvolution::setFlags(NoWrapFlags, SCEV::FlagNSW);
   }
 
-  LLVM_DEBUG(dbgs() << "LV: Found a monotonic phi: HeaderPHI: " << *PN
-                    << ", StepInst: " << *StepInst << "\n");
+  LLVM_DEBUG(dbgs() << "LV: Found a conditional induction phi: HeaderPHI: "
+                    << *PN << ", StepInst: " << *StepInst << "\n");
 
-  Desc = MonotonicDescriptor(PN, BackedgePHI, StepInst, StartSCEV, StepSCEV,
-                             NoWrapFlags);
+  Desc = ConditionalInductionDescriptor(PN, BackedgePHI, StepInst, StartSCEV,
+                                        StepSCEV, NoWrapFlags);
   return true;
 }

diff  --git a/llvm/unittests/Analysis/IVDescriptorsTest.cpp b/llvm/unittests/Analysis/IVDescriptorsTest.cpp
index 6b09354df8ced..793b909116018 100644
--- a/llvm/unittests/Analysis/IVDescriptorsTest.cpp
+++ b/llvm/unittests/Analysis/IVDescriptorsTest.cpp
@@ -440,7 +440,7 @@ static Instruction *getInstructionByName(Function &F, StringRef Name) {
   llvm_unreachable("Expected to find instruction!");
 }
 
-TEST(IVDescriptorsTest, MonotonicIntVar) {
+TEST(IVDescriptorsTest, ConditionalInductionIntVar) {
   // Parse the module.
   LLVMContext Context;
 
@@ -452,17 +452,17 @@ TEST(IVDescriptorsTest, MonotonicIntVar) {
 
 for.body:
   %i = phi i32 [ 0, %entry ], [ %i.next, %for.inc ]
-  %monotonic = phi i32 [ 0, %entry ], [ %monotonic.next, %for.inc ]
+  %conditional = phi i32 [ 0, %entry ], [ %conditional.next, %for.inc ]
   br i1 %cond, label %if.then, label %for.inc
 
 if.then:
-  %inc = add nsw i32 %monotonic, 1
-  %arrayidx = getelementptr inbounds i32, ptr %dst, i32 %monotonic
+  %inc = add nsw i32 %conditional, 1
+  %arrayidx = getelementptr inbounds i32, ptr %dst, i32 %conditional
   store i32 10, ptr %arrayidx, align 4
   br label %for.inc
 
 for.inc:
-  %monotonic.next = phi i32 [ %inc, %if.then ], [ %monotonic, %for.body ]
+  %conditional.next = phi i32 [ %inc, %if.then ], [ %conditional, %for.body ]
   %i.next = add i32 %i, 1
   %exitcond.not = icmp eq i32 %i.next, %n
   br i1 %exitcond.not, label %for.end, label %for.body
@@ -481,32 +481,34 @@ for.end:
         EXPECT_NE(L, nullptr);
 
         Instruction *Induction = getInstructionByName(F, "i");
-        Instruction *Phi = getInstructionByName(F, "monotonic");
-        Instruction *BackedgePhi = getInstructionByName(F, "monotonic.next");
+        Instruction *Phi = getInstructionByName(F, "conditional");
+        Instruction *BackedgePhi = getInstructionByName(F, "conditional.next");
         Instruction *StepInst = getInstructionByName(F, "inc");
 
-        // Check %monotonic descriptor.
-        MonotonicDescriptor Desc;
-        bool IsMonotonicPhi = MonotonicDescriptor::isMonotonicPHI(
-            cast<PHINode>(Phi), L, Desc, SE);
-        EXPECT_TRUE(IsMonotonicPhi);
+        // Check the conditional induction descriptor.
+        ConditionalInductionDescriptor Desc;
+        bool IsConditionalInductionPhi =
+            ConditionalInductionDescriptor::isConditionalInductionPHI(
+                cast<PHINode>(Phi), L, Desc, SE);
+        EXPECT_TRUE(IsConditionalInductionPhi);
         EXPECT_EQ(Desc.getHeaderPHI(), Phi);
         EXPECT_EQ(Desc.getBackedgePHI(), BackedgePhi);
         EXPECT_EQ(Desc.getStepInst(), StepInst);
 
         // Check the wrap flags for %i (the normal induction) don't include NSW.
-        // Note: `Induction` has the same start/step as the monotonic induction.
+        // Note: `Induction` has the same start/step as the conditional
+        // induction.
         const SCEV *OrigInSCEV = SE.getSCEV(Induction);
         auto *AR = cast<SCEVAddRecExpr>(OrigInSCEV);
         EXPECT_EQ(AR->getNoWrapFlags(), SCEV::FlagNUW | SCEV::FlagNW);
-        // Check the expressions and wrap flags for the monotonic induction.
+        // Check the expressions and wrap flags for the conditional induction.
         EXPECT_EQ(Desc.getSCEVNoWrapFlags(), SCEV::FlagNSW);
         EXPECT_EQ(Desc.getStartSCEV(), AR->getStart());
         EXPECT_EQ(Desc.getStepSCEV(), AR->getStepRecurrence(SE));
       });
 }
 
-TEST(IVDescriptorsTest, MonotonicPtrVar) {
+TEST(IVDescriptorsTest, ConditionalInductionPtrVar) {
   // Parse the module.
   LLVMContext Context;
 
@@ -518,15 +520,15 @@ TEST(IVDescriptorsTest, MonotonicPtrVar) {
 
 for.body:
   %i = phi i64 [ 0, %entry ], [ %i.next, %for.inc ]
-  %monotonic = phi ptr [ %start, %entry ], [ %monotonic.next, %for.inc ]
+  %conditional = phi ptr [ %start, %entry ], [ %conditional.next, %for.inc ]
   br i1 %cond, label %if.then, label %for.inc
 
 if.then:
-  %inc = getelementptr inbounds i8, ptr %monotonic, i32 4
+  %inc = getelementptr inbounds i8, ptr %conditional, i32 4
   br label %for.inc
 
 for.inc:
-  %monotonic.next = phi ptr [ %inc, %if.then ], [ %monotonic, %for.body ]
+  %conditional.next = phi ptr [ %inc, %if.then ], [ %conditional, %for.body ]
   %i.next = add nuw nsw i64 %i, 1
   %exitcond.not = icmp eq i64 %i.next, %n
   br i1 %exitcond.not, label %for.end, label %for.body
@@ -544,14 +546,15 @@ for.end:
         Loop *L = LI.getLoopFor(Header);
         EXPECT_NE(L, nullptr);
 
-        Instruction *Phi = getInstructionByName(F, "monotonic");
-        Instruction *BackedgePhi = getInstructionByName(F, "monotonic.next");
+        Instruction *Phi = getInstructionByName(F, "conditional");
+        Instruction *BackedgePhi = getInstructionByName(F, "conditional.next");
         Instruction *StepInst = getInstructionByName(F, "inc");
 
-        MonotonicDescriptor Desc;
-        bool IsMonotonicPhi = MonotonicDescriptor::isMonotonicPHI(
-            cast<PHINode>(Phi), L, Desc, SE);
-        EXPECT_TRUE(IsMonotonicPhi);
+        ConditionalInductionDescriptor Desc;
+        bool IsConditionalInductionPhi =
+            ConditionalInductionDescriptor::isConditionalInductionPHI(
+                cast<PHINode>(Phi), L, Desc, SE);
+        EXPECT_TRUE(IsConditionalInductionPhi);
 
         EXPECT_EQ(Desc.getHeaderPHI(), Phi);
         EXPECT_EQ(Desc.getBackedgePHI(), BackedgePhi);
@@ -564,7 +567,7 @@ for.end:
       });
 }
 
-TEST(IVDescriptorsTest, InvalidMonotonicExtraStep) {
+TEST(IVDescriptorsTest, InvalidConditionalInductionExtraStep) {
   // Parse the module.
   LLVMContext Context;
 
@@ -576,20 +579,20 @@ TEST(IVDescriptorsTest, InvalidMonotonicExtraStep) {
 
 for.body:
   %i = phi i64 [ 0, %entry ], [ %i.next, %for.inc ]
-  %monotonic = phi i32 [ 0, %entry ], [ %monotonic.next, %for.inc ]
+  %conditional = phi i32 [ 0, %entry ], [ %conditional.next, %for.inc ]
   br i1 %cond, label %if.then, label %for.inc
 
 if.then:
-  %inc = add nsw i32 %monotonic, 1
-  %monotonic.prom = sext i32 %monotonic to i64
-  %arrayidx = getelementptr inbounds i32, ptr %dst, i64 %monotonic.prom
+  %inc = add nsw i32 %conditional, 1
+  %conditional.prom = sext i32 %conditional to i64
+  %arrayidx = getelementptr inbounds i32, ptr %dst, i64 %conditional.prom
   store i32 10, ptr %arrayidx, align 4
   br i1 %cond2, label %if.then1, label %for.inc
 if.then1:
-  %inc2 = add nsw i32 %monotonic, 2
+  %inc2 = add nsw i32 %conditional, 2
   br label %for.inc
 for.inc:
-  %monotonic.next = phi i32 [ %inc, %if.then ], [ %inc2, %if.then1 ], [ %monotonic, %for.body ]
+  %conditional.next = phi i32 [ %inc, %if.then ], [ %inc2, %if.then1 ], [ %conditional, %for.body ]
   %i.next = add nuw nsw i64 %i, 1
   %exitcond.not = icmp eq i64 %i.next, %n
   br i1 %exitcond.not, label %for.end, label %for.body
@@ -607,17 +610,18 @@ for.end:
         Loop *L = LI.getLoopFor(Header);
         EXPECT_NE(L, nullptr);
 
-        Instruction *Phi = getInstructionByName(F, "monotonic");
+        Instruction *Phi = getInstructionByName(F, "conditional");
 
-        // Check %monotonic descriptor.
-        MonotonicDescriptor Desc;
-        bool IsMonotonicPhi = MonotonicDescriptor::isMonotonicPHI(
-            cast<PHINode>(Phi), L, Desc, SE);
-        EXPECT_FALSE(IsMonotonicPhi);
+        // Check the conditional induction descriptor.
+        ConditionalInductionDescriptor Desc;
+        bool IsConditionalInductionPhi =
+            ConditionalInductionDescriptor::isConditionalInductionPHI(
+                cast<PHINode>(Phi), L, Desc, SE);
+        EXPECT_FALSE(IsConditionalInductionPhi);
       });
 }
 
-TEST(IVDescriptorsTest, MonotonicPhiNegativeStepPtrVar) {
+TEST(IVDescriptorsTest, ConditionalInductionPhiNegativeStepPtrVar) {
   // Parse the module.
   LLVMContext Context;
 
@@ -629,15 +633,15 @@ TEST(IVDescriptorsTest, MonotonicPhiNegativeStepPtrVar) {
 
 for.body:
   %i = phi i64 [ 0, %entry ], [ %i.next, %for.inc ]
-  %monotonic = phi ptr [ %start, %entry ], [ %monotonic.next, %for.inc ]
+  %conditional = phi ptr [ %start, %entry ], [ %conditional.next, %for.inc ]
   br i1 %cond, label %if.then, label %for.inc
 
 if.then:
-  %dec = getelementptr nusw i8, ptr %monotonic, i32 -4
+  %dec = getelementptr nusw i8, ptr %conditional, i32 -4
   br label %for.inc
 
 for.inc:
-  %monotonic.next = phi ptr [ %dec, %if.then ], [ %monotonic, %for.body ]
+  %conditional.next = phi ptr [ %dec, %if.then ], [ %conditional, %for.body ]
   %i.next = add nuw nsw i64 %i, 1
   %exitcond.not = icmp eq i64 %i.next, %n
   br i1 %exitcond.not, label %for.end, label %for.body
@@ -655,14 +659,15 @@ for.end:
         Loop *L = LI.getLoopFor(Header);
         EXPECT_NE(L, nullptr);
 
-        Instruction *Phi = getInstructionByName(F, "monotonic");
-        Instruction *BackedgePhi = getInstructionByName(F, "monotonic.next");
+        Instruction *Phi = getInstructionByName(F, "conditional");
+        Instruction *BackedgePhi = getInstructionByName(F, "conditional.next");
         Instruction *StepInst = getInstructionByName(F, "dec");
 
-        MonotonicDescriptor Desc;
-        bool IsMonotonicPhi = MonotonicDescriptor::isMonotonicPHI(
-            cast<PHINode>(Phi), L, Desc, SE);
-        EXPECT_TRUE(IsMonotonicPhi);
+        ConditionalInductionDescriptor Desc;
+        bool IsConditionalInductionPhi =
+            ConditionalInductionDescriptor::isConditionalInductionPHI(
+                cast<PHINode>(Phi), L, Desc, SE);
+        EXPECT_TRUE(IsConditionalInductionPhi);
 
         EXPECT_EQ(Desc.getHeaderPHI(), Phi);
         EXPECT_EQ(Desc.getBackedgePHI(), BackedgePhi);


        


More information about the llvm-commits mailing list