[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