[llvm] [LV] Recognize UF*vscale as a valid canonical-IV increment step (PR #196722)

Hassnaa Hamdi via llvm-commits llvm-commits at lists.llvm.org
Tue May 12 04:55:31 PDT 2026


https://github.com/hassnaaHamdi updated https://github.com/llvm/llvm-project/pull/196722

>From c5b62e98055e0f4e8772b78e53c5fb98ce079cb8 Mon Sep 17 00:00:00 2001
From: Hassnaa Hamdi <hassnaa.hamdi at arm.com>
Date: Sat, 9 May 2026 13:12:33 +0000
Subject: [PATCH 1/4] [LV] Add a unittest to a failing scenario that should
 succeed

---
 .../Transforms/Vectorize/VPlanTest.cpp        | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index a1ddda7eda969..cfeeebaa3764f 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -1804,5 +1804,39 @@ TEST_F(VPInstructionTest, VPSymbolicValueAddUserAfterMaterialization) {
 }
 #endif
 
+TEST_F(VPRecipeTest, UFAddUsersBeforeMaterialization) {
+  VPlan &Plan = getPlan();
+  VPBasicBlock *Header = Plan.createVPBasicBlock("vector.header");
+  VPBasicBlock *Latch = Plan.createVPBasicBlock("vector.latch");
+  VPRegionBlock *LoopRegion = Plan.createLoopRegion(
+      Type::getInt32Ty(C), DebugLoc(), "vector.loop", Header, Latch);
+  VPBlockUtils::connectBlocks(Header, Latch);
+  VPBlockUtils::connectBlocks(Plan.getEntry(), LoopRegion);
+  VPBlockUtils::connectBlocks(LoopRegion, Plan.getScalarHeader());
+
+  auto *VScale = new VPInstruction(VPInstruction::VScale, {});
+  Plan.getVectorPreheader()->appendRecipe(VScale);
+
+  VPValue *UF = &Plan.getUF();
+  auto *Step =
+      new VPInstruction(Instruction::Mul, {VScale, UF},
+                        VPIRFlags(VPIRFlags::WrapFlagsTy(false, false)));
+  Plan.getVectorPreheader()->appendRecipe(Step);
+
+  auto *Increment = new VPInstruction(
+      Instruction::Add, {LoopRegion->getCanonicalIV(), Step},
+      VPIRFlags(VPIRFlags::WrapFlagsTy(LoopRegion->hasCanonicalIVNUW(), false)),
+      {}, DebugLoc(), "index.next");
+  Latch->appendRecipe(Increment);
+
+  auto *Br = new VPInstruction(VPInstruction::BranchOnCount,
+                               {Increment, &Plan.getVectorTripCount()});
+  Latch->appendRecipe(Br);
+
+  Plan.getVFxUF().markMaterialized();
+  Plan.dump();
+  EXPECT_EQ(Increment, LoopRegion->getOrCreateCanonicalIVIncrement());
+}
+
 } // namespace
 } // namespace llvm

>From 74c5313ed9a89a1ffc1a18dc595550fa47e8488f Mon Sep 17 00:00:00 2001
From: Hassnaa Hamdi <hassnaa.hamdi at arm.com>
Date: Sat, 9 May 2026 13:17:08 +0000
Subject: [PATCH 2/4] [LV] Add UF*Vscale as increment step to canonicalIV

---
 llvm/lib/Transforms/Vectorize/VPlanUtils.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 3327c4b188bb3..fad8acb64afe1 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -724,7 +724,9 @@ VPInstruction *vputils::findCanonicalIVIncrement(VPlan &Plan) {
 
     VPSymbolicValue &UF = Plan.getUF();
     if (!UF.isMaterialized())
-      return Step == &UF;
+      return Step == &UF ||
+             match(Step, m_c_Mul(m_Specific(&Plan.getUF()),
+                                 m_VPInstruction<VPInstruction::VScale>()));
 
     unsigned ConcreteUF = Plan.getConcreteUF();
     // Fixed VF: step is just the concrete UF.

>From 1ec34feecf0ed6e469c30a0f226ccb27e4f3a7f0 Mon Sep 17 00:00:00 2001
From: Hassnaa Hamdi <hassnaa.hamdi at arm.com>
Date: Mon, 11 May 2026 11:44:18 +0000
Subject: [PATCH 3/4] remove dump()

Change-Id: Ib42ee9c9ee293190d41003fe162b0b1fbe11a567
---
 llvm/unittests/Transforms/Vectorize/VPlanTest.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index cfeeebaa3764f..3b77b454bd012 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -1834,7 +1834,6 @@ TEST_F(VPRecipeTest, UFAddUsersBeforeMaterialization) {
   Latch->appendRecipe(Br);
 
   Plan.getVFxUF().markMaterialized();
-  Plan.dump();
   EXPECT_EQ(Increment, LoopRegion->getOrCreateCanonicalIVIncrement());
 }
 

>From 59a699117a3cdb53a88c3a938afe48985ce5a696 Mon Sep 17 00:00:00 2001
From: Hassnaa Hamdi <hassnaa.hamdi at arm.com>
Date: Tue, 12 May 2026 11:54:29 +0000
Subject: [PATCH 4/4] resolve review comments

---
 llvm/unittests/Transforms/Vectorize/VPlanTest.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index 3b77b454bd012..5a72b89d24f35 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -1808,8 +1808,9 @@ TEST_F(VPRecipeTest, UFAddUsersBeforeMaterialization) {
   VPlan &Plan = getPlan();
   VPBasicBlock *Header = Plan.createVPBasicBlock("vector.header");
   VPBasicBlock *Latch = Plan.createVPBasicBlock("vector.latch");
-  VPRegionBlock *LoopRegion = Plan.createLoopRegion(
-      Type::getInt32Ty(C), DebugLoc(), "vector.loop", Header, Latch);
+  VPRegionBlock *LoopRegion =
+      Plan.createLoopRegion(Type::getInt32Ty(C), DebugLoc::getUnknown(),
+                            "vector.loop", Header, Latch);
   VPBlockUtils::connectBlocks(Header, Latch);
   VPBlockUtils::connectBlocks(Plan.getEntry(), LoopRegion);
   VPBlockUtils::connectBlocks(LoopRegion, Plan.getScalarHeader());
@@ -1818,15 +1819,14 @@ TEST_F(VPRecipeTest, UFAddUsersBeforeMaterialization) {
   Plan.getVectorPreheader()->appendRecipe(VScale);
 
   VPValue *UF = &Plan.getUF();
-  auto *Step =
-      new VPInstruction(Instruction::Mul, {VScale, UF},
-                        VPIRFlags(VPIRFlags::WrapFlagsTy(false, false)));
+  auto *Step = new VPInstruction(Instruction::Mul, {VScale, UF},
+                                 VPIRFlags::getDefaultFlags(Instruction::Mul));
   Plan.getVectorPreheader()->appendRecipe(Step);
 
   auto *Increment = new VPInstruction(
       Instruction::Add, {LoopRegion->getCanonicalIV(), Step},
-      VPIRFlags(VPIRFlags::WrapFlagsTy(LoopRegion->hasCanonicalIVNUW(), false)),
-      {}, DebugLoc(), "index.next");
+      VPIRFlags::WrapFlagsTy(LoopRegion->hasCanonicalIVNUW(), false), {},
+      DebugLoc::getUnknown(), "index.next");
   Latch->appendRecipe(Increment);
 
   auto *Br = new VPInstruction(VPInstruction::BranchOnCount,



More information about the llvm-commits mailing list