[llvm] [VPlan] Strip VPDT-assert forbidding replicate regions (PR #189342)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 8 04:53:47 PDT 2026


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/189342

>From 9465a319da40644e8b923b4e2a884eb44c065452 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 30 Mar 2026 09:56:03 +0100
Subject: [PATCH 1/6] [VPlan] Strip VPDT-assert forbidding replicate regions
 (NFC)

VPDominatorTree::properlyDominates currently unnecessarily forbids
replicate regions, as there is no such limitation either in the parent
DominatorTree, or in VPlanCFG. Strip the assert entirely.
---
 .../lib/Transforms/Vectorize/VPlanAnalysis.cpp | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
index 9667227a329ac..2f6377614a9bf 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
@@ -391,24 +391,6 @@ bool VPDominatorTree::properlyDominates(const VPRecipeBase *A,
   if (ParentA == ParentB)
     return LocalComesBefore(A, B);
 
-#ifndef NDEBUG
-  auto GetReplicateRegion = [](VPRecipeBase *R) -> VPRegionBlock * {
-    VPRegionBlock *Region = R->getRegion();
-    if (Region && Region->isReplicator()) {
-      assert(Region->getNumSuccessors() == 1 &&
-             Region->getNumPredecessors() == 1 && "Expected SESE region!");
-      assert(R->getParent()->size() == 1 &&
-             "A recipe in an original replicator region must be the only "
-             "recipe in its block");
-      return Region;
-    }
-    return nullptr;
-  };
-  assert(!GetReplicateRegion(const_cast<VPRecipeBase *>(A)) &&
-         "No replicate regions expected at this point");
-  assert(!GetReplicateRegion(const_cast<VPRecipeBase *>(B)) &&
-         "No replicate regions expected at this point");
-#endif
   return Base::properlyDominates(ParentA, ParentB);
 }
 

>From 1186dc032d15175f18d5353b4843fb1a2f0867ae Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Tue, 31 Mar 2026 22:13:23 +0100
Subject: [PATCH 2/6] [VPlan] Add VPDomTreeTest

---
 .../Transforms/Vectorize/VPDomTreeTest.cpp    | 65 ++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
index e108c4d77c5a9..0c964bdd0b902 100644
--- a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
@@ -175,7 +175,7 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
 
     VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
     VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("R2BB2");
-    VPBasicBlock *R2BB3 = Plan.createVPBasicBlock("R2BB#");
+    VPBasicBlock *R2BB3 = Plan.createVPBasicBlock("R2BB3");
     VPRegionBlock *R2 = Plan.createLoopRegion("R2", R2BB1, R2BB3);
     R2BB2->setParent(R2);
     VPBlockUtils::connectBlocks(R2BB1, R2BB2);
@@ -208,6 +208,69 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     checkDomChildren(VPDT, R1BB3, {VPBB2});
     checkDomChildren(VPDT, VPBB2, {Plan.getScalarHeader()});
   }
+
+  {
+    // 2 nested replicate regions.
+    //  VPBB1
+    //    |
+    //  R1 {
+    //         R1BB1
+    //       /        \
+    //   R2 {          |
+    //     \           |
+    //     R2BB1       |
+    //       |   \    R1BB2
+    //     R2BB2-/     |
+    //        \        |
+    //         R2BB3   |
+    //   }            /
+    //      \        /
+    //        R1BB3
+    //  }
+    //   |
+    //  VPBB2
+    //
+    VPlan &Plan = getPlan();
+    VPBasicBlock *R1BB1 = Plan.createVPBasicBlock("R1BB1");
+    VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("R1BB2");
+    VPBasicBlock *R1BB3 = Plan.createVPBasicBlock("R1BB3");
+    VPRegionBlock *R1 = Plan.createReplicateRegion(R1BB1, R1BB3, "R1");
+
+    VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
+    VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("R2BB2");
+    VPBasicBlock *R2BB3 = Plan.createVPBasicBlock("R2BB3");
+    VPRegionBlock *R2 = Plan.createReplicateRegion(R2BB1, R2BB3, "R2");
+    R2BB2->setParent(R2);
+    VPBlockUtils::connectBlocks(R2BB1, R2BB2);
+    VPBlockUtils::connectBlocks(R2BB2, R2BB1);
+    VPBlockUtils::connectBlocks(R2BB2, R2BB3);
+
+    R2->setParent(R1);
+    VPBlockUtils::connectBlocks(R1BB1, R2);
+    R1BB2->setParent(R1);
+    VPBlockUtils::connectBlocks(R1BB1, R1BB2);
+    VPBlockUtils::connectBlocks(R1BB2, R1BB3);
+    VPBlockUtils::connectBlocks(R2, R1BB3);
+
+    VPBasicBlock *VPBB1 = Plan.getEntry();
+    VPBlockUtils::connectBlocks(VPBB1, R1);
+    VPBasicBlock *VPBB2 = Plan.createVPBasicBlock("VPBB2");
+    VPBlockUtils::connectBlocks(R1, VPBB2);
+
+    VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
+    VPDominatorTree VPDT(Plan);
+
+    checkDomChildren(VPDT, VPBB1, {R1});
+    checkDomChildren(VPDT, R1, {R1BB1});
+    checkDomChildren(VPDT, R1BB1, {R2, R1BB3, R1BB2});
+    checkDomChildren(VPDT, R1BB2, {});
+    checkDomChildren(VPDT, R2, {R2BB1});
+    checkDomChildren(VPDT, R2BB1, {R2BB2});
+    checkDomChildren(VPDT, R2BB2, {R2BB3});
+    checkDomChildren(VPDT, R2BB3, {});
+    checkDomChildren(VPDT, R1BB3, {VPBB2});
+    checkDomChildren(VPDT, VPBB2, {Plan.getScalarHeader()});
+  }
 }
 
 } // namespace

>From 636e7f3b73c6d443fc888f5ed27b211f086e0417 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 2 Apr 2026 10:59:18 +0100
Subject: [PATCH 3/6] [VPDomTreeTest] Improve ascii diagram in comments

---
 .../Transforms/Vectorize/VPDomTreeTest.cpp       | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
index 0c964bdd0b902..41bdccbf3ebed 100644
--- a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
@@ -151,12 +151,12 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     //  VPBB1
     //    |
     //  R1 {
-    //         R1BB1
-    //       /        \
+    //         R1BB1 <-+
+    //       /         |
     //   R2 {          |
     //     \           |
-    //     R2BB1       |
-    //       |   \    R1BB2
+    //     R2BB1<-+    |
+    //       |    |   R1BB2
     //     R2BB2-/     |
     //        \        |
     //         R2BB3   |
@@ -214,12 +214,12 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     //  VPBB1
     //    |
     //  R1 {
-    //         R1BB1
-    //       /        \
+    //         R1BB1 <-+
+    //       /         |
     //   R2 {          |
     //     \           |
-    //     R2BB1       |
-    //       |   \    R1BB2
+    //     R2BB1<-+    |
+    //       |    |   R1BB2
     //     R2BB2-/     |
     //        \        |
     //         R2BB3   |

>From 625a89415f51203a392ee0b773328bbb9ae72190 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Thu, 2 Apr 2026 15:51:42 +0100
Subject: [PATCH 4/6] [VPlan] Add missing tests, thanks Florian!

---
 .../unittests/Transforms/Vectorize/VPDomTreeTest.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
index 41bdccbf3ebed..fe9012682f4bf 100644
--- a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
@@ -270,6 +270,18 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     checkDomChildren(VPDT, R2BB3, {});
     checkDomChildren(VPDT, R1BB3, {VPBB2});
     checkDomChildren(VPDT, VPBB2, {Plan.getScalarHeader()});
+
+    EXPECT_FALSE(VPDT.properlyDominates(R1BB1, R1BB1));
+    EXPECT_FALSE(VPDT.properlyDominates(R2, R1BB3));
+    EXPECT_FALSE(VPDT.properlyDominates(R2, R1BB2));
+    EXPECT_TRUE(VPDT.properlyDominates(R1BB1, R2));
+    EXPECT_TRUE(VPDT.properlyDominates(R1BB1, R1BB2));
+    EXPECT_TRUE(VPDT.properlyDominates(R1BB1, R1BB3));
+    EXPECT_TRUE(VPDT.properlyDominates(R2, R2BB1));
+    EXPECT_TRUE(VPDT.properlyDominates(R2, R2BB2));
+    EXPECT_TRUE(VPDT.properlyDominates(R2, R2BB3));
+    EXPECT_TRUE(VPDT.properlyDominates(R2BB1, R2BB2));
+    EXPECT_TRUE(VPDT.properlyDominates(R2BB1, R2BB3));
   }
 }
 

>From 0cc09dbd0a5fed72107455254133e4c17dcb706f Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Tue, 7 Apr 2026 11:34:07 +0100
Subject: [PATCH 5/6] [VPlan] Fix embarassing confusion; really exercise code

---
 .../Transforms/Vectorize/VPDomTreeTest.cpp    | 32 ++++++-------------
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
index fe9012682f4bf..a6b209caf141a 100644
--- a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
@@ -237,8 +237,14 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     VPRegionBlock *R1 = Plan.createReplicateRegion(R1BB1, R1BB3, "R1");
 
     VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
+    VPInstruction *R2BB1I = new VPInstruction(VPInstruction::VScale, {});
+    R1BB1->appendRecipe(R2BB1I);
     VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("R2BB2");
+    VPInstruction *R2BB2I = new VPInstruction(VPInstruction::VScale, {});
+    R2BB2->appendRecipe(R2BB2I);
     VPBasicBlock *R2BB3 = Plan.createVPBasicBlock("R2BB3");
+    VPInstruction *R2BB3I = new VPInstruction(VPInstruction::VScale, {});
+    R2BB3->appendRecipe(R2BB3I);
     VPRegionBlock *R2 = Plan.createReplicateRegion(R2BB1, R2BB3, "R2");
     R2BB2->setParent(R2);
     VPBlockUtils::connectBlocks(R2BB1, R2BB2);
@@ -260,28 +266,10 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
     VPDominatorTree VPDT(Plan);
 
-    checkDomChildren(VPDT, VPBB1, {R1});
-    checkDomChildren(VPDT, R1, {R1BB1});
-    checkDomChildren(VPDT, R1BB1, {R2, R1BB3, R1BB2});
-    checkDomChildren(VPDT, R1BB2, {});
-    checkDomChildren(VPDT, R2, {R2BB1});
-    checkDomChildren(VPDT, R2BB1, {R2BB2});
-    checkDomChildren(VPDT, R2BB2, {R2BB3});
-    checkDomChildren(VPDT, R2BB3, {});
-    checkDomChildren(VPDT, R1BB3, {VPBB2});
-    checkDomChildren(VPDT, VPBB2, {Plan.getScalarHeader()});
-
-    EXPECT_FALSE(VPDT.properlyDominates(R1BB1, R1BB1));
-    EXPECT_FALSE(VPDT.properlyDominates(R2, R1BB3));
-    EXPECT_FALSE(VPDT.properlyDominates(R2, R1BB2));
-    EXPECT_TRUE(VPDT.properlyDominates(R1BB1, R2));
-    EXPECT_TRUE(VPDT.properlyDominates(R1BB1, R1BB2));
-    EXPECT_TRUE(VPDT.properlyDominates(R1BB1, R1BB3));
-    EXPECT_TRUE(VPDT.properlyDominates(R2, R2BB1));
-    EXPECT_TRUE(VPDT.properlyDominates(R2, R2BB2));
-    EXPECT_TRUE(VPDT.properlyDominates(R2, R2BB3));
-    EXPECT_TRUE(VPDT.properlyDominates(R2BB1, R2BB2));
-    EXPECT_TRUE(VPDT.properlyDominates(R2BB1, R2BB3));
+    EXPECT_TRUE(VPDT.properlyDominates(R2BB1I, R2BB2I));
+    EXPECT_TRUE(VPDT.properlyDominates(R2BB1I, R2BB3I));
+    EXPECT_FALSE(VPDT.properlyDominates(R2BB3I, R2BB2I));
+    EXPECT_FALSE(VPDT.properlyDominates(R2BB1I, R2BB1I));
   }
 }
 

>From 50279f8ea8f9caf8af0271afbb64becbc6e2cba4 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 8 Apr 2026 12:34:43 +0100
Subject: [PATCH 6/6] [VPlan] More extensive testing

---
 .../Transforms/Vectorize/VPDomTreeTest.cpp         | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
index a6b209caf141a..958fb307b9743 100644
--- a/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPDomTreeTest.cpp
@@ -232,13 +232,19 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     //
     VPlan &Plan = getPlan();
     VPBasicBlock *R1BB1 = Plan.createVPBasicBlock("R1BB1");
+    VPInstruction *R1BB1I = new VPInstruction(VPInstruction::VScale, {});
+    R1BB1->appendRecipe(R1BB1I);
     VPBasicBlock *R1BB2 = Plan.createVPBasicBlock("R1BB2");
+    VPInstruction *R1BB2I = new VPInstruction(VPInstruction::VScale, {});
+    R1BB2->appendRecipe(R1BB2I);
     VPBasicBlock *R1BB3 = Plan.createVPBasicBlock("R1BB3");
+    VPInstruction *R1BB3I = new VPInstruction(VPInstruction::VScale, {});
+    R1BB3->appendRecipe(R1BB3I);
     VPRegionBlock *R1 = Plan.createReplicateRegion(R1BB1, R1BB3, "R1");
 
     VPBasicBlock *R2BB1 = Plan.createVPBasicBlock("R2BB1");
     VPInstruction *R2BB1I = new VPInstruction(VPInstruction::VScale, {});
-    R1BB1->appendRecipe(R2BB1I);
+    R2BB1->appendRecipe(R2BB1I);
     VPBasicBlock *R2BB2 = Plan.createVPBasicBlock("R2BB2");
     VPInstruction *R2BB2I = new VPInstruction(VPInstruction::VScale, {});
     R2BB2->appendRecipe(R2BB2I);
@@ -266,8 +272,14 @@ TEST_F(VPDominatorTreeTest, DominanceRegionsTest) {
     VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
     VPDominatorTree VPDT(Plan);
 
+    EXPECT_TRUE(VPDT.properlyDominates(R1BB1I, R2BB1I));
+    EXPECT_TRUE(VPDT.properlyDominates(R1BB1I, R2BB2I));
+    EXPECT_TRUE(VPDT.properlyDominates(R1BB1I, R2BB3I));
+    EXPECT_TRUE(VPDT.properlyDominates(R1BB1I, R1BB3I));
+    EXPECT_FALSE(VPDT.properlyDominates(R1BB2I, R1BB3I));
     EXPECT_TRUE(VPDT.properlyDominates(R2BB1I, R2BB2I));
     EXPECT_TRUE(VPDT.properlyDominates(R2BB1I, R2BB3I));
+    EXPECT_FALSE(VPDT.properlyDominates(R2BB1I, R1BB3I));
     EXPECT_FALSE(VPDT.properlyDominates(R2BB3I, R2BB2I));
     EXPECT_FALSE(VPDT.properlyDominates(R2BB1I, R2BB1I));
   }



More information about the llvm-commits mailing list