aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-03 14:10:23 +0000
commit145449b1e420787bb99721a429341fa6be3adfb6 (patch)
tree1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
parentecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff)
Diffstat (limited to 'llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp')
-rw-r--r--llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp55
1 files changed, 33 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
index d36f250995e1..f917883145c0 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
@@ -43,17 +43,20 @@ static bool hasDuplicates(const SmallVectorImpl<VPBlockBase *> &VPBlockVec) {
/// \p Region. Checks in this function are generic for VPBlockBases. They are
/// not specific for VPBasicBlocks or VPRegionBlocks.
static void verifyBlocksInRegion(const VPRegionBlock *Region) {
- for (const VPBlockBase *VPB :
- make_range(df_iterator<const VPBlockBase *>::begin(Region->getEntry()),
- df_iterator<const VPBlockBase *>::end(Region->getExit()))) {
+ for (const VPBlockBase *VPB : make_range(
+ df_iterator<const VPBlockBase *>::begin(Region->getEntry()),
+ df_iterator<const VPBlockBase *>::end(Region->getExiting()))) {
// Check block's parent.
assert(VPB->getParent() == Region && "VPBlockBase has wrong parent");
+ auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
// Check block's condition bit.
- if (VPB->getNumSuccessors() > 1)
- assert(VPB->getCondBit() && "Missing condition bit!");
+ if (VPB->getNumSuccessors() > 1 || (VPBB && VPBB->isExiting()))
+ assert(VPBB && VPBB->getTerminator() &&
+ "Block has multiple successors but doesn't "
+ "have a proper branch recipe!");
else
- assert(!VPB->getCondBit() && "Unexpected condition bit!");
+ assert((!VPBB || !VPBB->getTerminator()) && "Unexpected branch recipe!");
// Check block's successors.
const auto &Successors = VPB->getSuccessors();
@@ -94,13 +97,14 @@ static void verifyBlocksInRegion(const VPRegionBlock *Region) {
/// VPBlockBases. Do not recurse inside nested VPRegionBlocks.
static void verifyRegion(const VPRegionBlock *Region) {
const VPBlockBase *Entry = Region->getEntry();
- const VPBlockBase *Exit = Region->getExit();
+ const VPBlockBase *Exiting = Region->getExiting();
- // Entry and Exit shouldn't have any predecessor/successor, respectively.
+ // Entry and Exiting shouldn't have any predecessor/successor, respectively.
assert(!Entry->getNumPredecessors() && "Region entry has predecessors.");
- assert(!Exit->getNumSuccessors() && "Region exit has successors.");
+ assert(!Exiting->getNumSuccessors() &&
+ "Region exiting block has successors.");
(void)Entry;
- (void)Exit;
+ (void)Exiting;
verifyBlocksInRegion(Region);
}
@@ -111,9 +115,9 @@ static void verifyRegionRec(const VPRegionBlock *Region) {
verifyRegion(Region);
// Recurse inside nested regions.
- for (const VPBlockBase *VPB :
- make_range(df_iterator<const VPBlockBase *>::begin(Region->getEntry()),
- df_iterator<const VPBlockBase *>::end(Region->getExit()))) {
+ for (const VPBlockBase *VPB : make_range(
+ df_iterator<const VPBlockBase *>::begin(Region->getEntry()),
+ df_iterator<const VPBlockBase *>::end(Region->getExiting()))) {
if (const auto *SubRegion = dyn_cast<VPRegionBlock>(VPB))
verifyRegionRec(SubRegion);
}
@@ -157,7 +161,7 @@ bool VPlanVerifier::verifyPlanIsValid(const VPlan &Plan) {
}
}
- const VPRegionBlock *TopRegion = cast<VPRegionBlock>(Plan.getEntry());
+ const VPRegionBlock *TopRegion = Plan.getVectorLoopRegion();
const VPBasicBlock *Entry = dyn_cast<VPBasicBlock>(TopRegion->getEntry());
if (!Entry) {
errs() << "VPlan entry block is not a VPBasicBlock\n";
@@ -170,19 +174,19 @@ bool VPlanVerifier::verifyPlanIsValid(const VPlan &Plan) {
return false;
}
- const VPBasicBlock *Exit = dyn_cast<VPBasicBlock>(TopRegion->getExit());
- if (!Exit) {
- errs() << "VPlan exit block is not a VPBasicBlock\n";
+ const VPBasicBlock *Exiting = dyn_cast<VPBasicBlock>(TopRegion->getExiting());
+ if (!Exiting) {
+ errs() << "VPlan exiting block is not a VPBasicBlock\n";
return false;
}
- if (Exit->empty()) {
- errs() << "VPlan vector loop exit must end with BranchOnCount "
+ if (Exiting->empty()) {
+ errs() << "VPlan vector loop exiting block must end with BranchOnCount "
"VPInstruction but is empty\n";
return false;
}
- auto *LastInst = dyn_cast<VPInstruction>(std::prev(Exit->end()));
+ auto *LastInst = dyn_cast<VPInstruction>(std::prev(Exiting->end()));
if (!LastInst || LastInst->getOpcode() != VPInstruction::BranchOnCount) {
errs() << "VPlan vector loop exit must end with BranchOnCount "
"VPInstruction\n";
@@ -197,10 +201,17 @@ bool VPlanVerifier::verifyPlanIsValid(const VPlan &Plan) {
errs() << "region entry block has predecessors\n";
return false;
}
- if (Region->getExit()->getNumSuccessors() != 0) {
- errs() << "region exit block has successors\n";
+ if (Region->getExiting()->getNumSuccessors() != 0) {
+ errs() << "region exiting block has successors\n";
return false;
}
}
+
+ for (auto &KV : Plan.getLiveOuts())
+ if (KV.second->getNumOperands() != 1) {
+ errs() << "live outs must have a single operand\n";
+ return false;
+ }
+
return true;
}