[llvm] [VPlan] Allow same predecessor multiple times in the verifier. (NFC) (PR #192809)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 18 12:48:24 PDT 2026


https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/192809

IR instructions like switch lead to initial VPlans with blocks that have the same predecessor multiple times. Allow it in the verifier.

>From 4d96c60eb5f590b62dd8f97ef005793b94ee4bc4 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Sat, 18 Apr 2026 16:15:01 +0100
Subject: [PATCH] [VPlan] Allow same predecessor multiple times in the
 verifier.

IR instructions like switch lead to initial VPlans with blocks that have
the same predecessor multiple times. Allow it in the verifier.
---
 .../Transforms/Vectorize/VPlanVerifier.cpp    | 25 -------------------
 .../Vectorize/VPlanVerifierTest.cpp           | 20 +++------------
 2 files changed, 4 insertions(+), 41 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
index 1dff1831c305c..ee1c7e3f16b2e 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
@@ -314,17 +314,6 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
   return true;
 }
 
-/// Utility function that checks whether \p VPBlockVec has duplicate
-/// VPBlockBases.
-static bool hasDuplicates(const SmallVectorImpl<VPBlockBase *> &VPBlockVec) {
-  SmallDenseSet<const VPBlockBase *, 8> VPBlockSet;
-  for (const auto *Block : VPBlockVec) {
-    if (!VPBlockSet.insert(Block).second)
-      return true;
-  }
-  return false;
-}
-
 bool VPlanVerifier::verifyBlock(const VPBlockBase *VPB) {
   auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
   // Check block's condition bit.
@@ -345,13 +334,6 @@ bool VPlanVerifier::verifyBlock(const VPBlockBase *VPB) {
 
   // Check block's successors.
   const auto &Successors = VPB->getSuccessors();
-  // There must be only one instance of a successor in block's successor list.
-  // TODO: This won't work for switch statements.
-  if (hasDuplicates(Successors)) {
-    errs() << "Multiple instances of the same successor.\n";
-    return false;
-  }
-
   for (const VPBlockBase *Succ : Successors) {
     // There must be a bi-directional link between block and successor.
     const auto &SuccPreds = Succ->getPredecessors();
@@ -363,13 +345,6 @@ bool VPlanVerifier::verifyBlock(const VPBlockBase *VPB) {
 
   // Check block's predecessors.
   const auto &Predecessors = VPB->getPredecessors();
-  // There must be only one instance of a predecessor in block's predecessor
-  // list.
-  // TODO: This won't work for switch statements.
-  if (hasDuplicates(Predecessors)) {
-    errs() << "Multiple instances of the same predecessor.\n";
-    return false;
-  }
 
   for (const VPBlockBase *Pred : Predecessors) {
     // Block and predecessor must be inside the same region.
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
index 2472e18b654e2..1bf3248da48b7 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp
@@ -224,14 +224,8 @@ TEST_F(VPVerifierTest, DuplicateSuccessorsOutsideRegion) {
 
   VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());
 
-#if GTEST_HAS_STREAM_REDIRECTION
-  ::testing::internal::CaptureStderr();
-#endif
-  EXPECT_FALSE(verifyVPlanIsValid(Plan));
-#if GTEST_HAS_STREAM_REDIRECTION
-  EXPECT_STREQ("Multiple instances of the same successor.\n",
-               ::testing::internal::GetCapturedStderr().c_str());
-#endif
+  // Duplicate successors are allowed for blocks with conditional terminators.
+  EXPECT_TRUE(verifyVPlanIsValid(Plan));
 }
 
 TEST_F(VPVerifierTest, DuplicateSuccessorsInsideRegion) {
@@ -263,14 +257,8 @@ TEST_F(VPVerifierTest, DuplicateSuccessorsInsideRegion) {
 
   VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());
 
-#if GTEST_HAS_STREAM_REDIRECTION
-  ::testing::internal::CaptureStderr();
-#endif
-  EXPECT_FALSE(verifyVPlanIsValid(Plan));
-#if GTEST_HAS_STREAM_REDIRECTION
-  EXPECT_STREQ("Multiple instances of the same successor.\n",
-               ::testing::internal::GetCapturedStderr().c_str());
-#endif
+  // Duplicate successors are allowed for blocks with conditional terminators.
+  EXPECT_TRUE(verifyVPlanIsValid(Plan));
 }
 
 TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) {



More information about the llvm-commits mailing list