@@ -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