xref: /llvm-project/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp (revision ca8b0b4af42499669573fdfe6e3bb87feb2f6b69)
1 //===- llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "../lib/Transforms/Vectorize/VPlanVerifier.h"
10 #include "../lib/Transforms/Vectorize/VPlan.h"
11 #include "llvm/IR/Instruction.h"
12 #include "llvm/IR/Instructions.h"
13 #include "gtest/gtest.h"
14 
15 using namespace llvm;
16 
17 namespace {
18 TEST(VPVerifierTest, VPInstructionUseBeforeDefSameBB) {
19   VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
20   VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI});
21 
22   VPBasicBlock *VPBB1 = new VPBasicBlock();
23   VPBB1->appendRecipe(UseI);
24   VPBB1->appendRecipe(DefI);
25 
26   VPlan Plan;
27   Plan.setEntry(VPBB1);
28 
29 #if GTEST_HAS_STREAM_REDIRECTION
30   ::testing::internal::CaptureStderr();
31 #endif
32   EXPECT_FALSE(VPlanVerifier::verifyPlanIsValid(Plan));
33 #if GTEST_HAS_STREAM_REDIRECTION
34   EXPECT_STREQ("Use before def!\n",
35                ::testing::internal::GetCapturedStderr().c_str());
36 #endif
37 }
38 
39 TEST(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) {
40   VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
41   VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI});
42   auto *CanIV = new VPCanonicalIVPHIRecipe(UseI, {});
43   VPInstruction *BranchOnCond =
44       new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
45 
46   VPBasicBlock *VPBB1 = new VPBasicBlock();
47   VPBasicBlock *VPBB2 = new VPBasicBlock();
48 
49   VPBB1->appendRecipe(UseI);
50   VPBB2->appendRecipe(CanIV);
51   VPBB2->appendRecipe(DefI);
52   VPBB2->appendRecipe(BranchOnCond);
53 
54   VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB2, "R1");
55   VPBlockUtils::connectBlocks(VPBB1, R1);
56 
57   VPlan Plan;
58   Plan.setEntry(VPBB1);
59 
60   // TODO: UseI uses DefI but DefI does not dominate UseI. Currently missed by
61   // the verifier.
62 #if GTEST_HAS_STREAM_REDIRECTION
63   ::testing::internal::CaptureStderr();
64 #endif
65   EXPECT_TRUE(VPlanVerifier::verifyPlanIsValid(Plan));
66 #if GTEST_HAS_STREAM_REDIRECTION
67   EXPECT_STREQ("", ::testing::internal::GetCapturedStderr().c_str());
68 #endif
69 }
70 
71 TEST(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) {
72   LLVMContext C;
73   IntegerType *Int32 = IntegerType::get(C, 32);
74   auto *Phi = PHINode::Create(Int32, 1);
75 
76   VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
77   VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
78   auto *CanIV = new VPCanonicalIVPHIRecipe(I1, {});
79   VPInstruction *BranchOnCond =
80       new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
81   auto *Blend = new VPBlendRecipe(Phi, {DefI});
82 
83   VPBasicBlock *VPBB1 = new VPBasicBlock();
84   VPBasicBlock *VPBB2 = new VPBasicBlock();
85   VPBasicBlock *VPBB3 = new VPBasicBlock();
86   VPBasicBlock *VPBB4 = new VPBasicBlock();
87 
88   VPBB1->appendRecipe(I1);
89   VPBB2->appendRecipe(CanIV);
90   VPBB3->appendRecipe(Blend);
91   VPBB4->appendRecipe(DefI);
92   VPBB4->appendRecipe(BranchOnCond);
93 
94   VPBlockUtils::connectBlocks(VPBB2, VPBB3);
95   VPBlockUtils::connectBlocks(VPBB3, VPBB4);
96   VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB4, "R1");
97   VPBlockUtils::connectBlocks(VPBB1, R1);
98 
99   VPlan Plan;
100   Plan.setEntry(VPBB1);
101 
102   // TODO: Blend uses Def but Def does not dominate Blend. Currently missed by
103   // the verifier.
104 #if GTEST_HAS_STREAM_REDIRECTION
105   ::testing::internal::CaptureStderr();
106 #endif
107   EXPECT_TRUE(VPlanVerifier::verifyPlanIsValid(Plan));
108 #if GTEST_HAS_STREAM_REDIRECTION
109   EXPECT_STREQ("", ::testing::internal::GetCapturedStderr().c_str());
110 #endif
111 
112   delete Phi;
113 }
114 } // namespace
115