[llvm] [VPlan] Generalize folding IV increment into phi start value (NFC). (PR #223260)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 10:55:53 PDT 2026
https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/223260
simplifyRecipe folds
X = phi(0, IVInc)
IVInc = X + Step
Def = IVInc + Y
into a phi starting at Y, but only if Y is a live-in. Also allow values defined in the block the phi's start value is coming from, which is where the value conservatively has to be available.
NFC today, but preparation for modeling the full epilogue skeleton in VPlan.
>From 665c61f4052d8de54a6eba309445c8308abb5068 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Sun, 23 Aug 2026 14:41:20 +0100
Subject: [PATCH] [VPlan] Generalize folding IV increment into phi start value
(NFC).
simplifyRecipe folds
X = phi(0, IVInc)
IVInc = X + Step
Def = IVInc + Y
into a phi starting at Y, but only if Y is a live-in. Also allow values
defined in the block the phi's start value is coming from, which is where the
value conservatively has to be available.
NFC today, but preparation for modeling the full epilogue skeleton in
VPlan.
---
.../Transforms/Vectorize/VPlanTransforms.cpp | 33 +++++++++++--------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 831eb957c8caf..dd29d99a58e16 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1371,6 +1371,13 @@ static VPValue *simplifyRecipe(VPlan &Plan, VPSingleDefRecipe *Def) {
return nullptr;
}
+/// Returns true if \p V is available at the end of \p VPBB, i.e. it either is a
+/// live-in from the original IR or defined in \p VPBB.
+static bool isAvailableAtEndOf(VPValue *V, const VPBasicBlock *VPBB) {
+ VPRecipeBase *DefR = V->getDefiningRecipe();
+ return DefR ? DefR->getParent() == VPBB : isa<VPIRValue>(V);
+}
+
/// Combine \p Def into a simpler recipe. May modify or create new recipes.
static VPSingleDefRecipe *combineRecipe(VPlan &Plan, VPSingleDefRecipe *Def) {
if (auto *V = simplifyRecipe(Plan, Def)) {
@@ -1669,20 +1676,20 @@ static VPSingleDefRecipe *combineRecipe(VPlan &Plan, VPSingleDefRecipe *Def) {
VPValue *IVInc;
if (match(Def, m_Add(m_VPValue(IVInc, m_Add(m_VPValue(X), m_VPValue())),
m_VPValue(Y))) &&
- isa<VPIRValue>(Y) && match(X, m_VPPhi(m_ZeroInt(), m_Specific(IVInc)))) {
+ match(X, m_VPPhi(m_ZeroInt(), m_Specific(IVInc))) &&
+ IVInc->getNumUsers() == 2) {
auto *Phi = cast<VPPhi>(X);
- if (IVInc->getNumUsers() == 2) {
- // If Phi has a second user (besides IVInc's defining recipe), it must
- // be Inc = Phi + Y for the fold to apply.
- auto *Inc = dyn_cast_or_null<VPSingleDefRecipe>(
- findUserOf(Phi, m_Add(m_Specific(Phi), m_Specific(Y))));
- if (Phi->getNumUsers() == 1 || (Phi->getNumUsers() == 2 && Inc)) {
- Def->replaceAllUsesWith(IVInc);
- if (Inc)
- Inc->replaceAllUsesWith(Phi);
- Phi->setOperand(0, Y);
- return Def;
- }
+ // If Phi has a second user (besides IVInc's defining recipe), it must be
+ // Inc = Phi + Y for the fold to apply.
+ auto *Inc = dyn_cast_if_present<VPSingleDefRecipe>(
+ findUserOf(Phi, m_Add(m_Specific(Phi), m_Specific(Y))));
+ if ((Phi->getNumUsers() == 1 || (Phi->getNumUsers() == 2 && Inc)) &&
+ isAvailableAtEndOf(Y, Phi->getIncomingBlock(0))) {
+ Def->replaceAllUsesWith(IVInc);
+ if (Inc)
+ Inc->replaceAllUsesWith(Phi);
+ Phi->setOperand(0, Y);
+ return Def;
}
}
More information about the llvm-commits
mailing list