Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / Transforms / Vectorize / VPlanVerifierTest.cpp
blob9958d6ea124f81211f778440b62641739b8911c8
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 //===----------------------------------------------------------------------===//
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"
15 using namespace llvm;
17 namespace {
18 TEST(VPVerifierTest, VPInstructionUseBeforeDefSameBB) {
19 VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
20 VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI});
22 VPBasicBlock *VPPH = new VPBasicBlock("ph");
23 VPBasicBlock *VPBB1 = new VPBasicBlock();
24 VPBB1->appendRecipe(UseI);
25 VPBB1->appendRecipe(DefI);
27 auto TC = std::make_unique<VPValue>();
28 VPBasicBlock *VPBB2 = new VPBasicBlock();
29 VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB2, "R1");
30 VPBlockUtils::connectBlocks(VPBB1, R1);
31 VPlan Plan(VPPH, &*TC, VPBB1);
33 #if GTEST_HAS_STREAM_REDIRECTION
34 ::testing::internal::CaptureStderr();
35 #endif
36 EXPECT_FALSE(verifyVPlanIsValid(Plan));
37 #if GTEST_HAS_STREAM_REDIRECTION
38 EXPECT_STREQ("Use before def!\n",
39 ::testing::internal::GetCapturedStderr().c_str());
40 #endif
43 TEST(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) {
44 VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
45 VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI});
46 auto *CanIV = new VPCanonicalIVPHIRecipe(UseI, {});
47 VPInstruction *BranchOnCond =
48 new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
50 VPBasicBlock *VPPH = new VPBasicBlock("ph");
51 VPBasicBlock *VPBB1 = new VPBasicBlock();
52 VPBasicBlock *VPBB2 = new VPBasicBlock();
54 VPBB1->appendRecipe(UseI);
55 VPBB2->appendRecipe(CanIV);
56 VPBB2->appendRecipe(DefI);
57 VPBB2->appendRecipe(BranchOnCond);
59 VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB2, "R1");
60 VPBlockUtils::connectBlocks(VPBB1, R1);
62 auto TC = std::make_unique<VPValue>();
63 VPlan Plan(VPPH, &*TC, VPBB1);
65 #if GTEST_HAS_STREAM_REDIRECTION
66 ::testing::internal::CaptureStderr();
67 #endif
68 EXPECT_FALSE(verifyVPlanIsValid(Plan));
69 #if GTEST_HAS_STREAM_REDIRECTION
70 EXPECT_STREQ("Use before def!\n",
71 ::testing::internal::GetCapturedStderr().c_str());
72 #endif
75 TEST(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) {
76 LLVMContext C;
77 IntegerType *Int32 = IntegerType::get(C, 32);
78 auto *Phi = PHINode::Create(Int32, 1);
80 VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
81 VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
82 auto *CanIV = new VPCanonicalIVPHIRecipe(I1, {});
83 VPInstruction *BranchOnCond =
84 new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
85 auto *Blend = new VPBlendRecipe(Phi, {DefI});
87 VPBasicBlock *VPPH = new VPBasicBlock("ph");
88 VPBasicBlock *VPBB1 = new VPBasicBlock();
89 VPBasicBlock *VPBB2 = new VPBasicBlock();
90 VPBasicBlock *VPBB3 = new VPBasicBlock();
91 VPBasicBlock *VPBB4 = new VPBasicBlock();
93 VPBB1->appendRecipe(I1);
94 VPBB2->appendRecipe(CanIV);
95 VPBB3->appendRecipe(Blend);
96 VPBB4->appendRecipe(DefI);
97 VPBB4->appendRecipe(BranchOnCond);
99 VPBlockUtils::connectBlocks(VPBB2, VPBB3);
100 VPBlockUtils::connectBlocks(VPBB3, VPBB4);
101 VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB4, "R1");
102 VPBlockUtils::connectBlocks(VPBB1, R1);
103 VPBB3->setParent(R1);
105 auto TC = std::make_unique<VPValue>();
106 VPlan Plan(VPPH, &*TC, VPBB1);
108 #if GTEST_HAS_STREAM_REDIRECTION
109 ::testing::internal::CaptureStderr();
110 #endif
111 EXPECT_FALSE(verifyVPlanIsValid(Plan));
112 #if GTEST_HAS_STREAM_REDIRECTION
113 EXPECT_STREQ("Use before def!\n",
114 ::testing::internal::GetCapturedStderr().c_str());
115 #endif
117 delete Phi;
120 TEST(VPVerifierTest, DuplicateSuccessorsOutsideRegion) {
121 VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
122 auto *CanIV = new VPCanonicalIVPHIRecipe(I1, {});
123 VPInstruction *BranchOnCond =
124 new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
125 VPInstruction *BranchOnCond2 =
126 new VPInstruction(VPInstruction::BranchOnCond, {I1});
128 VPBasicBlock *VPPH = new VPBasicBlock("ph");
129 VPBasicBlock *VPBB1 = new VPBasicBlock();
130 VPBasicBlock *VPBB2 = new VPBasicBlock();
132 VPBB1->appendRecipe(I1);
133 VPBB1->appendRecipe(BranchOnCond2);
134 VPBB2->appendRecipe(CanIV);
135 VPBB2->appendRecipe(BranchOnCond);
137 VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB2, "R1");
138 VPBlockUtils::connectBlocks(VPBB1, R1);
139 VPBlockUtils::connectBlocks(VPBB1, R1);
141 auto TC = std::make_unique<VPValue>();
142 VPlan Plan(VPPH, &*TC, VPBB1);
144 #if GTEST_HAS_STREAM_REDIRECTION
145 ::testing::internal::CaptureStderr();
146 #endif
147 EXPECT_FALSE(verifyVPlanIsValid(Plan));
148 #if GTEST_HAS_STREAM_REDIRECTION
149 EXPECT_STREQ("Multiple instances of the same successor.\n",
150 ::testing::internal::GetCapturedStderr().c_str());
151 #endif
154 TEST(VPVerifierTest, DuplicateSuccessorsInsideRegion) {
155 VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
156 auto *CanIV = new VPCanonicalIVPHIRecipe(I1, {});
157 VPInstruction *BranchOnCond =
158 new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
159 VPInstruction *BranchOnCond2 =
160 new VPInstruction(VPInstruction::BranchOnCond, {I1});
162 VPBasicBlock *VPPH = new VPBasicBlock("ph");
163 VPBasicBlock *VPBB1 = new VPBasicBlock();
164 VPBasicBlock *VPBB2 = new VPBasicBlock();
165 VPBasicBlock *VPBB3 = new VPBasicBlock();
167 VPBB1->appendRecipe(I1);
168 VPBB2->appendRecipe(CanIV);
169 VPBB2->appendRecipe(BranchOnCond2);
170 VPBB3->appendRecipe(BranchOnCond);
172 VPBlockUtils::connectBlocks(VPBB2, VPBB3);
173 VPBlockUtils::connectBlocks(VPBB2, VPBB3);
174 VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB3, "R1");
175 VPBlockUtils::connectBlocks(VPBB1, R1);
176 VPBB3->setParent(R1);
178 auto TC = std::make_unique<VPValue>();
179 VPlan Plan(VPPH, &*TC, VPBB1);
181 #if GTEST_HAS_STREAM_REDIRECTION
182 ::testing::internal::CaptureStderr();
183 #endif
184 EXPECT_FALSE(verifyVPlanIsValid(Plan));
185 #if GTEST_HAS_STREAM_REDIRECTION
186 EXPECT_STREQ("Multiple instances of the same successor.\n",
187 ::testing::internal::GetCapturedStderr().c_str());
188 #endif
191 TEST(VPVerifierTest, BlockOutsideRegionWithParent) {
192 VPBasicBlock *VPPH = new VPBasicBlock("ph");
193 VPBasicBlock *VPBB1 = new VPBasicBlock();
194 VPBasicBlock *VPBB2 = new VPBasicBlock();
196 VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
197 VPInstruction *BranchOnCond =
198 new VPInstruction(VPInstruction::BranchOnCond, {DefI});
200 VPBB1->appendRecipe(DefI);
201 VPBB2->appendRecipe(BranchOnCond);
203 VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB2, "R1");
204 VPBlockUtils::connectBlocks(VPBB1, R1);
205 VPBB1->setParent(R1);
207 auto TC = std::make_unique<VPValue>();
208 VPlan Plan(VPPH, &*TC, VPBB1);
210 #if GTEST_HAS_STREAM_REDIRECTION
211 ::testing::internal::CaptureStderr();
212 #endif
213 EXPECT_FALSE(verifyVPlanIsValid(Plan));
214 #if GTEST_HAS_STREAM_REDIRECTION
215 EXPECT_STREQ("Predecessor is not in the same region.\n",
216 ::testing::internal::GetCapturedStderr().c_str());
217 #endif
220 } // namespace