@@ -28,6 +28,7 @@ namespace {
28
28
class VPlanVerifier {
29
29
const VPDominatorTree &VPDT;
30
30
VPTypeAnalysis &TypeInfo;
31
+ bool VerifyLate;
31
32
32
33
SmallPtrSet<BasicBlock *, 8 > WrappedIRBBs;
33
34
@@ -60,8 +61,9 @@ class VPlanVerifier {
60
61
bool verifyRegionRec (const VPRegionBlock *Region);
61
62
62
63
public:
63
- VPlanVerifier (VPDominatorTree &VPDT, VPTypeAnalysis &TypeInfo)
64
- : VPDT(VPDT), TypeInfo(TypeInfo) {}
64
+ VPlanVerifier (VPDominatorTree &VPDT, VPTypeAnalysis &TypeInfo,
65
+ bool VerifyLate)
66
+ : VPDT(VPDT), TypeInfo(TypeInfo), VerifyLate(VerifyLate) {}
65
67
66
68
bool verify (const VPlan &Plan);
67
69
};
@@ -113,7 +115,7 @@ bool VPlanVerifier::verifyPhiRecipes(const VPBasicBlock *VPBB) {
113
115
RecipeI++;
114
116
}
115
117
116
- if (NumActiveLaneMaskPhiRecipes > 1 ) {
118
+ if (!VerifyLate && NumActiveLaneMaskPhiRecipes > 1 ) {
117
119
errs () << " There should be no more than one VPActiveLaneMaskPHIRecipe" ;
118
120
return false ;
119
121
}
@@ -151,7 +153,7 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
151
153
}
152
154
return true ;
153
155
};
154
- return all_of (EVL.users (), [&VerifyEVLUse](VPUser *U) {
156
+ return all_of (EVL.users (), [this , &VerifyEVLUse](VPUser *U) {
155
157
return TypeSwitch<const VPUser *, bool >(U)
156
158
.Case <VPWidenIntrinsicRecipe>([&](const VPWidenIntrinsicRecipe *S) {
157
159
return VerifyEVLUse (*S, S->getNumOperands () - 1 );
@@ -174,7 +176,7 @@ bool VPlanVerifier::verifyEVLRecipe(const VPInstruction &EVL) const {
174
176
" users\n " ;
175
177
return false ;
176
178
}
177
- if (!isa<VPEVLBasedIVPHIRecipe>(*I->users ().begin ())) {
179
+ if (!VerifyLate && ! isa<VPEVLBasedIVPHIRecipe>(*I->users ().begin ())) {
178
180
errs () << " Result of VPInstruction::Add with EVL operand is "
179
181
" not used by VPEVLBasedIVPHIRecipe\n " ;
180
182
return false ;
@@ -243,7 +245,9 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) {
243
245
continue ;
244
246
}
245
247
// TODO: Also verify VPPredInstPHIRecipe.
246
- if (isa<VPPredInstPHIRecipe>(UI))
248
+ if (isa<VPPredInstPHIRecipe>(UI) ||
249
+ (isa<VPInstruction>(UI) && (cast<VPInstruction>(UI)->getOpcode () ==
250
+ VPInstruction::ResumePhi)))
247
251
continue ;
248
252
249
253
// If the user is in the same block, check it comes after R in the
@@ -302,18 +306,20 @@ static bool hasDuplicates(const SmallVectorImpl<VPBlockBase *> &VPBlockVec) {
302
306
bool VPlanVerifier::verifyBlock (const VPBlockBase *VPB) {
303
307
auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
304
308
// Check block's condition bit.
305
- if (VPB->getNumSuccessors () > 1 ||
306
- (VPBB && VPBB->getParent () && VPBB->isExiting () &&
307
- !VPBB->getParent ()->isReplicator ())) {
308
- if (!VPBB || !VPBB->getTerminator ()) {
309
- errs () << " Block has multiple successors but doesn't "
310
- " have a proper branch recipe!\n " ;
311
- return false ;
312
- }
313
- } else {
314
- if (VPBB && VPBB->getTerminator ()) {
315
- errs () << " Unexpected branch recipe!\n " ;
316
- return false ;
309
+ if (!isa<VPIRBasicBlock>(VPB)) {
310
+ if (VPB->getNumSuccessors () > 1 ||
311
+ (VPBB && VPBB->getParent () && VPBB->isExiting () &&
312
+ !VPBB->getParent ()->isReplicator ())) {
313
+ if (!VPBB || !VPBB->getTerminator ()) {
314
+ errs () << " Block has multiple successors but doesn't "
315
+ " have a proper branch recipe!\n " ;
316
+ return false ;
317
+ }
318
+ } else {
319
+ if (VPBB && VPBB->getTerminator ()) {
320
+ errs () << " Unexpected branch recipe!\n " ;
321
+ return false ;
322
+ }
317
323
}
318
324
}
319
325
@@ -409,6 +415,10 @@ bool VPlanVerifier::verify(const VPlan &Plan) {
409
415
return false ;
410
416
411
417
const VPRegionBlock *TopRegion = Plan.getVectorLoopRegion ();
418
+ // TODO: Verify all blocks using vp_depth_first_deep iterators.
419
+ if (!TopRegion)
420
+ return true ;
421
+
412
422
if (!verifyRegionRec (TopRegion))
413
423
return false ;
414
424
@@ -423,7 +433,8 @@ bool VPlanVerifier::verify(const VPlan &Plan) {
423
433
return false ;
424
434
}
425
435
426
- if (!isa<VPCanonicalIVPHIRecipe>(&*Entry->begin ())) {
436
+ // TODO: Remove once loop regions are dissolved before execution.
437
+ if (!VerifyLate && !isa<VPCanonicalIVPHIRecipe>(&*Entry->begin ())) {
427
438
errs () << " VPlan vector loop header does not start with a "
428
439
" VPCanonicalIVPHIRecipe\n " ;
429
440
return false ;
@@ -452,10 +463,10 @@ bool VPlanVerifier::verify(const VPlan &Plan) {
452
463
return true ;
453
464
}
454
465
455
- bool llvm::verifyVPlanIsValid (const VPlan &Plan) {
466
+ bool llvm::verifyVPlanIsValid (const VPlan &Plan, bool VerifyLate ) {
456
467
VPDominatorTree VPDT;
457
468
VPDT.recalculate (const_cast <VPlan &>(Plan));
458
469
VPTypeAnalysis TypeInfo (Plan);
459
- VPlanVerifier Verifier (VPDT, TypeInfo);
470
+ VPlanVerifier Verifier (VPDT, TypeInfo, VerifyLate );
460
471
return Verifier.verify (Plan);
461
472
}
0 commit comments