[llvm] [VPlan] Add unit test for createAndOptimizeReplicateRegions. NFC (PR #164652)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 22 09:06:10 PDT 2025


https://github.com/lukel97 created https://github.com/llvm/llvm-project/pull/164652

In #160449 some of the tests end up merging less blocks so we end up losing test coverage.
This adds a unit test to try and cover it elsewhere in a more predictable way, so it won't be influenced by e.g. whether or not the cost model decides to scalarize an instruction.

Two parts in createReplicateRegion/addReplicateRegions had to be relaxed to allow using a fake Instruction with no BasicBlock parent. I wasn't able to create a fake BasicBlock in the test without hitting iterator assertions.


>From 8e02164ba179038eb8022db307cc0bafe763496b Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Thu, 23 Oct 2025 00:00:27 +0800
Subject: [PATCH] [VPlan] Add unit test for createAndOptimizeReplicateRegions.
 NFC

In #160449 some of the tests end up merging less blocks so we end up losing test coverage.
This adds a unit test to try and cover it elsewhere in a more predictable way, so it won't be influenced by e.g. whether or not the cost model decides to scalarize an instruction.

Two parts in createReplicateRegion/addReplicateRegions had to be relaxed to allow using a fake Instruction with no BasicBlock parent. I wasn't able to create a fake BasicBlock in the test without hitting iterator assertions.
---
 .../Transforms/Vectorize/VPlanTransforms.cpp  |  6 +-
 .../Transforms/Vectorize/CMakeLists.txt       |  1 +
 .../Vectorize/VPlanTransformsTest.cpp         | 77 +++++++++++++++++++
 3 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100644 llvm/unittests/Transforms/Vectorize/VPlanTransformsTest.cpp

diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 7bf8d83d2550c..90d8cfc791097 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -345,7 +345,6 @@ static VPRegionBlock *createReplicateRegion(VPReplicateRecipe *PredRecipe,
   Instruction *Instr = PredRecipe->getUnderlyingInstr();
   // Build the triangular if-then region.
   std::string RegionName = (Twine("pred.") + Instr->getOpcodeName()).str();
-  assert(Instr->getParent() && "Predicated instruction not in any basic block");
   auto *BlockInMask = PredRecipe->getMask();
   auto *MaskDef = BlockInMask->getDefiningRecipe();
   auto *BOMRecipe = new VPBranchOnMaskRecipe(
@@ -399,8 +398,9 @@ static void addReplicateRegions(VPlan &Plan) {
     VPBasicBlock *SplitBlock = CurrentBlock->splitAt(RepR->getIterator());
 
     BasicBlock *OrigBB = RepR->getUnderlyingInstr()->getParent();
-    SplitBlock->setName(
-        OrigBB->hasName() ? OrigBB->getName() + "." + Twine(BBNum++) : "");
+    SplitBlock->setName((OrigBB && OrigBB->hasName())
+                            ? OrigBB->getName() + "." + Twine(BBNum++)
+                            : "");
     // Record predicated instructions for above packing optimizations.
     VPRegionBlock *Region = createReplicateRegion(RepR, Plan);
     Region->setParent(CurrentBlock->getParent());
diff --git a/llvm/unittests/Transforms/Vectorize/CMakeLists.txt b/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
index af111a29b90e5..3564bd140c971 100644
--- a/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
+++ b/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
@@ -14,6 +14,7 @@ add_llvm_unittest(VectorizeTests
   VPlanHCFGTest.cpp
   VPlanPatternMatchTest.cpp
   VPlanSlpTest.cpp
+  VPlanTransformsTest.cpp
   VPlanUncountableExitTest.cpp
   VPlanVerifierTest.cpp
   )
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTransformsTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTransformsTest.cpp
new file mode 100644
index 0000000000000..ab94337d61e39
--- /dev/null
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTransformsTest.cpp
@@ -0,0 +1,77 @@
+//===- llvm/unittests/Transforms/Vectorize/VPlanTransformsTest.cpp --------===//
+//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../lib/Transforms/Vectorize/VPlanTransforms.h"
+#include "../lib/Transforms/Vectorize/VPlan.h"
+#include "VPlanTestBase.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+namespace {
+using VPlanTransformsTest = VPlanTestBase;
+
+// Test we create and merge replicate regions:
+// VPBB1:
+//   REPLICATE %Rep0 = add
+//   REPLICATE %Rep1 = add
+//   REPLICATE %Rep2 = add
+// No successors
+//
+// ->
+//
+// <xVFxUF> pred.add: {
+//   pred.add.entry:
+//     BRANCH-ON-MASK %Mask
+//   Successor(s): pred.add.if, pred.add.continue
+//
+//   pred.add.if:
+//     REPLICATE %Rep0 = add
+//     REPLICATE %Rep1 = add
+//     REPLICATE %Rep2 = add
+//   Successor(s): pred.add.continue
+//
+//   pred.add.continue:
+//   No successors
+// }
+TEST_F(VPlanTransformsTest, createAndOptimizeReplicateRegions) {
+  VPlan &Plan = getPlan();
+
+  IntegerType *Int32 = IntegerType::get(C, 32);
+  auto *AI = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
+                                       PoisonValue::get(Int32));
+
+  auto *VPBB0 = Plan.getEntry();
+  auto *VPBB1 = Plan.createVPBasicBlock("VPBB1");
+  VPRegionBlock *R1 = Plan.createVPRegionBlock(VPBB1, VPBB1, "R1");
+  VPBlockUtils::connectBlocks(VPBB0, R1);
+  auto *Mask = new VPInstruction(0, {});
+  auto *Rep0 = new VPReplicateRecipe(AI, {}, false, Mask);
+  auto *Rep1 = new VPReplicateRecipe(AI, {}, false, Mask);
+  auto *Rep2 = new VPReplicateRecipe(AI, {}, false, Mask);
+  VPBB1->appendRecipe(Rep0);
+  VPBB1->appendRecipe(Rep1);
+  VPBB1->appendRecipe(Rep2);
+
+  VPlanTransforms::createAndOptimizeReplicateRegions(Plan);
+
+  auto *Replicator = cast<VPRegionBlock>(R1->getEntry()->getSingleSuccessor());
+  EXPECT_TRUE(Replicator->isReplicator());
+  auto *ReplicatorEntry = cast<VPBasicBlock>(Replicator->getEntry());
+  EXPECT_EQ(ReplicatorEntry->size(), 1u);
+  EXPECT_TRUE(isa<VPBranchOnMaskRecipe>(ReplicatorEntry->front()));
+  auto *ReplicatorIf = cast<VPBasicBlock>(ReplicatorEntry->getSuccessors()[0]);
+  EXPECT_EQ(ReplicatorIf->size(), 3u);
+  EXPECT_EQ(ReplicatorEntry->getSuccessors()[1],
+            ReplicatorIf->getSingleSuccessor());
+  EXPECT_EQ(ReplicatorIf->getSingleSuccessor(), Replicator->getExiting());
+}
+
+} // namespace
+} // namespace llvm



More information about the llvm-commits mailing list