Skip to content

Commit aadf35c

Browse files
committed
[VPlan] Verify number preds and operands matches for VPIRPhis. (NFC)
Extend the verifier to ensure the number of predecessors and operands match for VPIRPhis.
1 parent 541ad3f commit aadf35c

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,18 @@ bool VPlanVerifier::verifyPhiRecipes(const VPBasicBlock *VPBB) {
9797
return false;
9898
}
9999

100+
// Check if the recipe operands match the number of predecessors.
101+
// TODO Extend to other phi-like recipes.
102+
if (auto *PhiIRI = dyn_cast<VPIRPhi>(&*RecipeI)) {
103+
if (PhiIRI->getNumOperands() != VPBB->getNumPredecessors()) {
104+
errs() << "Phi-like recipe with different number of operands and "
105+
"predecessors.\n";
106+
// TODO: Print broken recipe. At the moment printing an ill-formed
107+
// phi-like recipe may crash.
108+
return false;
109+
}
110+
}
111+
100112
RecipeI++;
101113
}
102114

llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,44 @@ TEST_F(VPVerifierTest, BlockOutsideRegionWithParent) {
223223
#endif
224224
}
225225

226+
class VPIRVerifierTest : public VPlanTestIRBase {};
227+
228+
TEST_F(VPIRVerifierTest, testVerifyIRPhi) {
229+
const char *ModuleString =
230+
"define void @f(ptr %A, i64 %N) {\n"
231+
"entry:\n"
232+
" br label %loop\n"
233+
"loop:\n"
234+
" %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]\n"
235+
" %arr.idx = getelementptr inbounds i32, ptr %A, i64 %iv\n"
236+
" %l1 = load i32, ptr %arr.idx, align 4\n"
237+
" %res = add i32 %l1, 10\n"
238+
" store i32 %res, ptr %arr.idx, align 4\n"
239+
" %iv.next = add i64 %iv, 1\n"
240+
" %exitcond = icmp ne i64 %iv.next, %N\n"
241+
" br i1 %exitcond, label %loop, label %for.end\n"
242+
"for.end:\n"
243+
" %p = phi i32 [ %l1, %loop ]\n"
244+
" ret void\n"
245+
"}\n";
246+
247+
Module &M = parseModule(ModuleString);
248+
249+
Function *F = M.getFunction("f");
250+
BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor();
251+
auto Plan = buildVPlan(LoopHeader);
252+
253+
Plan->getExitBlocks()[0]->front().addOperand(
254+
Plan->getOrAddLiveIn(ConstantInt::get(Type::getInt32Ty(*Ctx), 0)));
255+
256+
#if GTEST_HAS_STREAM_REDIRECTION
257+
::testing::internal::CaptureStderr();
258+
#endif
259+
EXPECT_FALSE(verifyVPlanIsValid(*Plan));
260+
#if GTEST_HAS_STREAM_REDIRECTION
261+
EXPECT_STREQ(
262+
"Phi-like recipe with different number of operands and predecessors.\n",
263+
::testing::internal::GetCapturedStderr().c_str());
264+
#endif
265+
}
226266
} // namespace

0 commit comments

Comments
 (0)