Skip to content

Commit 29aa9b0

Browse files
committed
[VPlan] Verify dominance for incoming values of phi-like recipes.
Update the verifier to verify dominance for incoming values for phi-like recipes. The defining recipe must dominate the incoming block for the incoming value. There are 4 different cases to consider when retrieving the incoming block: * VPIRInstructions wrapping phis: the incoming block from the blocks predecessors has the same index as the incoming value operand. * VPHeaderPhiRecipes, VPWidenPhi used in header: there's no predecessors; if the incoming value is the start value use the predecessor of the containing region, otherwise the exiting block of the region * 1 predecessor: Must be a VPWidenPHI used as LCSSA phi; use the predecessor * 2 predecessors: must be a VPPredInstPhiRecipe, use the second predecessor.
1 parent 6338bde commit 29aa9b0

File tree

1 file changed

+53
-5
lines changed

1 file changed

+53
-5
lines changed

llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
175175
});
176176
}
177177

178+
/// Return true if \p R is a VPIRInstruction wrapping a phi.
179+
static bool isVPIRInstructionPhi(const VPRecipeBase &R) {
180+
auto *VPIRI = dyn_cast<VPIRInstruction>(&R);
181+
return VPIRI && isa<PHINode>(VPIRI->getInstruction());
182+
}
178183
bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
179184
if (!verifyPhiRecipes(VPBB))
180185
return false;
@@ -207,22 +212,65 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
207212

208213
for (const VPUser *U : V->users()) {
209214
auto *UI = cast<VPRecipeBase>(U);
210-
// TODO: check dominance of incoming values for phis properly.
211-
if (!UI ||
212-
isa<VPHeaderPHIRecipe, VPWidenPHIRecipe, VPPredInstPHIRecipe>(UI))
215+
const VPBlockBase *UserVPBB = UI->getParent();
216+
217+
// Verify incoming values of VPIRInstructions wrapping phis. V most
218+
// dominate the end of the incoming block. The operand index of the
219+
// incoming value matches the predecessor block index of the
220+
// corresponding incoming block.
221+
if (isVPIRInstructionPhi(*UI)) {
222+
for (const auto &[Idx, Op] : enumerate(UI->operands())) {
223+
if (V != Op)
224+
continue;
225+
const VPBlockBase *Incoming = UserVPBB->getPredecessors()[Idx];
226+
if (Incoming != VPBB && !VPDT.dominates(VPBB, Incoming)) {
227+
errs() << "Use before def!\n";
228+
return false;
229+
}
230+
}
213231
continue;
232+
}
233+
// Verify incoming value of various phi-like recipes.
234+
if (isa<VPWidenPHIRecipe, VPHeaderPHIRecipe, VPPredInstPHIRecipe>(UI)) {
235+
const VPBlockBase *Incoming = nullptr;
236+
// Get the incoming block based on the number of predecessors.
237+
if (UserVPBB->getNumPredecessors() == 0) {
238+
assert((isa<VPWidenPHIRecipe>(UI) || isa<VPHeaderPHIRecipe>(UI)) &&
239+
"Unexpected recipe with 0 predecessors");
240+
const VPRegionBlock *UserRegion = UserVPBB->getParent();
241+
Incoming = V == UI->getOperand(0)
242+
? UserRegion->getSinglePredecessor()
243+
: UserRegion->getExiting();
244+
} else if (UserVPBB->getNumPredecessors() == 1) {
245+
assert(isa<VPWidenPHIRecipe>(UI) &&
246+
"Unexpected recipe with 1 predecessors");
247+
Incoming = UserVPBB->getSinglePredecessor();
248+
} else {
249+
assert(UserVPBB->getNumPredecessors() == 2 &&
250+
isa<VPPredInstPHIRecipe>(UI) &&
251+
"Unexpected recipe with 2 or more predecessors");
252+
Incoming = UserVPBB->getPredecessors()[1];
253+
}
254+
if (auto *R = dyn_cast<VPRegionBlock>(Incoming))
255+
Incoming = R->getExiting();
256+
if (Incoming != VPBB && !VPDT.dominates(VPBB, Incoming)) {
257+
errs() << "Use before def!\n";
258+
return false;
259+
}
260+
continue;
261+
}
214262

215263
// If the user is in the same block, check it comes after R in the
216264
// block.
217-
if (UI->getParent() == VPBB) {
265+
if (UserVPBB == VPBB) {
218266
if (RecipeNumbering[UI] < RecipeNumbering[&R]) {
219267
errs() << "Use before def!\n";
220268
return false;
221269
}
222270
continue;
223271
}
224272

225-
if (!VPDT.dominates(VPBB, UI->getParent())) {
273+
if (!VPDT.dominates(VPBB, UserVPBB)) {
226274
errs() << "Use before def!\n";
227275
return false;
228276
}

0 commit comments

Comments
 (0)