Skip to content

Commit

Permalink
[VPlan] Initial def-use verification.
Browse files Browse the repository at this point in the history
This patch introduces some initial def-use verification. This catches
cases like the one fixed by D129436.

Reviewed By: Ayal

Differential Revision: https://reviews.llvm.org/D129717
  • Loading branch information
fhahn committed Jul 20, 2022
1 parent 9fc347a commit 5124b21
Showing 1 changed file with 62 additions and 4 deletions.
66 changes: 62 additions & 4 deletions llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
Expand Up @@ -133,7 +133,9 @@ void VPlanVerifier::verifyHierarchicalCFG(
verifyRegionRec(TopRegion);
}

static bool verifyVPBasicBlock(const VPBasicBlock *VPBB) {
static bool
verifyVPBasicBlock(const VPBasicBlock *VPBB,
DenseMap<const VPBlockBase *, unsigned> &BlockNumbering) {
// Verify that phi-like recipes are at the beginning of the block, with no
// other recipes in between.
auto RecipeI = VPBB->begin();
Expand Down Expand Up @@ -165,15 +167,71 @@ static bool verifyVPBasicBlock(const VPBasicBlock *VPBB) {
RecipeI++;
}

// Verify that defs in VPBB dominate all their uses. The current
// implementation is still incomplete.
DenseMap<const VPRecipeBase *, unsigned> RecipeNumbering;
unsigned Cnt = 0;
for (const VPRecipeBase &R : *VPBB)
RecipeNumbering[&R] = Cnt++;

for (const VPRecipeBase &R : *VPBB) {
for (const VPValue *V : R.definedValues()) {
for (const VPUser *U : V->users()) {
auto *UI = dyn_cast<VPRecipeBase>(U);
if (!UI || isa<VPHeaderPHIRecipe>(UI))
continue;

// If the user is in the same block, check it comes after R in the
// block.
if (UI->getParent() == VPBB) {
if (RecipeNumbering[UI] < RecipeNumbering[&R]) {
errs() << "Use before def!\n";
return false;
}
continue;
}

// Skip blocks outside any region for now and blocks outside
// replicate-regions.
auto *ParentR = VPBB->getParent();
if (!ParentR || !ParentR->isReplicator())
continue;

// For replicators, verify that VPPRedInstPHIRecipe defs are only used
// in subsequent blocks.
if (isa<VPPredInstPHIRecipe>(&R)) {
auto I = BlockNumbering.find(UI->getParent());
unsigned BlockNumber = I == BlockNumbering.end() ? std::numeric_limits<unsigned>::max() : I->second;
if (BlockNumber < BlockNumbering[ParentR]) {
errs() << "Use before def!\n";
return false;
}
continue;
}

// All non-VPPredInstPHIRecipe recipes in the block must be used in
// the replicate region only.
if (UI->getParent()->getParent() != ParentR) {
errs() << "Use before def!\n";
return false;
}
}
}
}
return true;
}

bool VPlanVerifier::verifyPlanIsValid(const VPlan &Plan) {
DenseMap<const VPBlockBase *, unsigned> BlockNumbering;
unsigned Cnt = 0;
auto Iter = depth_first(
VPBlockRecursiveTraversalWrapper<const VPBlockBase *>(Plan.getEntry()));
for (const VPBasicBlock *VPBB :
VPBlockUtils::blocksOnly<const VPBasicBlock>(Iter)) {
if (!verifyVPBasicBlock(VPBB))
for (const VPBlockBase *VPB : Iter) {
BlockNumbering[VPB] = Cnt++;
auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
if (!VPBB)
continue;
if (!verifyVPBasicBlock(VPBB, BlockNumbering))
return false;
}

Expand Down

0 comments on commit 5124b21

Please sign in to comment.