diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index f5a3af4e983f6..4022755c7c4dc 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..2291d53aa9a61 --- /dev/null +++ b/llvm/unittests/Transforms/Vectorize/VPlanTransformsTest.cpp @@ -0,0 +1,84 @@ +//===- 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, %Mask +// REPLICATE %Rep2 = add, %Mask +// REPLICATE %Rep3 = add, %Mask +// No successors +// +// -> +// +// 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 +// REPLICATE %Rep3 = add %Rep0 +// Successor(s): pred.add.continue +// +// pred.add.continue: +// No successors +// } +TEST_F(VPlanTransformsTest, createAndOptimizeReplicateRegions) { + VPlan &Plan = getPlan(); + Plan.addVF(ElementCount::getFixed(4)); + + 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.createLoopRegion("R1", VPBB1, VPBB1); + VPBlockUtils::connectBlocks(VPBB0, R1); + auto *Mask = new VPInstruction(0, {}); + // Not masked, but should still be sunk into Rep3's region. + auto *Rep0 = new VPReplicateRecipe(AI, {}, false); + // Masked, should each create a replicate region and get merged. + auto *Rep1 = new VPReplicateRecipe(AI, {}, false, Mask); + auto *Rep2 = new VPReplicateRecipe(AI, {}, false, Mask); + auto *Rep3 = new VPReplicateRecipe(AI, {Rep0}, false, Mask); + VPBB1->appendRecipe(Rep0); + VPBB1->appendRecipe(Rep1); + VPBB1->appendRecipe(Rep2); + VPBB1->appendRecipe(Rep3); + + VPlanTransforms::createAndOptimizeReplicateRegions(Plan); + + auto *Replicator = cast(R1->getEntry()->getSingleSuccessor()); + EXPECT_TRUE(Replicator->isReplicator()); + auto *ReplicatorEntry = cast(Replicator->getEntry()); + EXPECT_EQ(ReplicatorEntry->size(), 1u); + EXPECT_TRUE(isa(ReplicatorEntry->front())); + auto *ReplicatorIf = cast(ReplicatorEntry->getSuccessors()[0]); + EXPECT_EQ(ReplicatorIf->size(), 4u); + EXPECT_EQ(ReplicatorEntry->getSuccessors()[1], + ReplicatorIf->getSingleSuccessor()); + EXPECT_EQ(ReplicatorIf->getSingleSuccessor(), Replicator->getExiting()); +} + +} // namespace +} // namespace llvm