[llvm] [IVDescriptors] Implement MonotonicDescriptor (PR #214490)
Gaƫtan Bossu via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 21 08:48:11 PDT 2026
================
@@ -1696,3 +1696,164 @@ bool InductionDescriptor::isInductionPHI(
/*InductionBinOp=*/nullptr, /*Casts=*/nullptr, Preds);
return true;
}
+
+// Recognize monotonic phi variable by matching the following pattern:
+// loop_header:
+// %monotonic_phi = phi [ %start, %preheader ], [ %chain_phi0, %latch ]
+// br i1 %do_step, label %step_bb, label %latch
+//
+// step_bb:
+// %step = add/gep %monotonic_phi, %step_val
+// br label %latch
+//
+// latch:
+// %chain_phi0 = phi [ %monotonic_phi, %loop_header ], [ %step, %step_bb ]
+// br label %loop_header
+//
+// For this pattern, monotonic phi is described by {%start, +, %step}
+// recurrence and predicate is CFG edge %step_bb -> %latch.
+std::optional<MonotonicDescriptor::MonotonicPHI>
+MonotonicDescriptor::matchMonotonicPHI(PHINode *PN, const Loop *L,
+ ScalarEvolution &SE) {
+ if (!PN->getType()->isIntOrPtrTy() || PN->getParent() != L->getHeader())
+ return std::nullopt;
+ auto *BackedgeInst =
+ dyn_cast<PHINode>(PN->getIncomingValueForBlock(L->getLoopLatch()));
+ if (!BackedgeInst)
+ return std::nullopt;
+
+ // Ensure the only user of the backedge are out of the loop or the PN.
+ for (User *U : BackedgeInst->users()) {
+ auto *UI = dyn_cast<Instruction>(U);
+ if (UI == PN || (UI && !L->contains(UI)))
+ continue;
+ return std::nullopt;
+ }
+
+ // Find the StepOp (that increments PN). TODO: Support chains of phis.
+ Value *StepOp = nullptr;
+ for (auto [Block, Incoming] :
+ zip_equal(BackedgeInst->blocks(), BackedgeInst->incoming_values())) {
----------------
gbossu wrote:
I didn't know about `find_singleton`, that's great!
https://github.com/llvm/llvm-project/pull/214490
More information about the llvm-commits
mailing list