xref: /llvm-project/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp (revision b85a402dd899fc0e702a60b459bc06317d532d84)
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 *VPPH = new VPBasicBlock("ph");
23   VPBasicBlock *VPBB1 = new VPBasicBlock();
24   VPBB1->appendRecipe(UseI);
25   VPBB1->appendRecipe(DefI);
26 
27   auto TC = std::make_unique<VPValue>();
28   VPlan Plan(VPPH, &*TC, VPBB1);
29 
30 #if GTEST_HAS_STREAM_REDIRECTION
31   ::testing::internal::CaptureStderr();
32 #endif
33   EXPECT_FALSE(VPlanVerifier::verifyPlanIsValid(Plan));
34 #if GTEST_HAS_STREAM_REDIRECTION
35   EXPECT_STREQ("Use before def!\n",
36                ::testing::internal::GetCapturedStderr().c_str());
37 #endif
38 }
39 
40 TEST(VPVerifierTest, VPInstructionUseBeforeDefDifferentBB) {
41   VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
42   VPInstruction *UseI = new VPInstruction(Instruction::Sub, {DefI});
43   auto *CanIV = new VPCanonicalIVPHIRecipe(UseI, {});
44   VPInstruction *BranchOnCond =
45       new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
46 
47   VPBasicBlock *VPPH = new VPBasicBlock("ph");
48   VPBasicBlock *VPBB1 = new VPBasicBlock();
49   VPBasicBlock *VPBB2 = new VPBasicBlock();
50 
51   VPBB1->appendRecipe(UseI);
52   VPBB2->appendRecipe(CanIV);
53   VPBB2->appendRecipe(DefI);
54   VPBB2->appendRecipe(BranchOnCond);
55 
56   VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB2, "R1");
57   VPBlockUtils::connectBlocks(VPBB1, R1);
58 
59   auto TC = std::make_unique<VPValue>();
60   VPlan Plan(VPPH, &*TC, VPBB1);
61 
62 #if GTEST_HAS_STREAM_REDIRECTION
63   ::testing::internal::CaptureStderr();
64 #endif
65   EXPECT_FALSE(VPlanVerifier::verifyPlanIsValid(Plan));
66 #if GTEST_HAS_STREAM_REDIRECTION
67   EXPECT_STREQ("Use before def!\n",
68                ::testing::internal::GetCapturedStderr().c_str());
69 #endif
70 }
71 
72 TEST(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) {
73   LLVMContext C;
74   IntegerType *Int32 = IntegerType::get(C, 32);
75   auto *Phi = PHINode::Create(Int32, 1);
76 
77   VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
78   VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
79   auto *CanIV = new VPCanonicalIVPHIRecipe(I1, {});
80   VPInstruction *BranchOnCond =
81       new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
82   auto *Blend = new VPBlendRecipe(Phi, {DefI});
83 
84   VPBasicBlock *VPPH = new VPBasicBlock("ph");
85   VPBasicBlock *VPBB1 = new VPBasicBlock();
86   VPBasicBlock *VPBB2 = new VPBasicBlock();
87   VPBasicBlock *VPBB3 = new VPBasicBlock();
88   VPBasicBlock *VPBB4 = new VPBasicBlock();
89 
90   VPBB1->appendRecipe(I1);
91   VPBB2->appendRecipe(CanIV);
92   VPBB3->appendRecipe(Blend);
93   VPBB4->appendRecipe(DefI);
94   VPBB4->appendRecipe(BranchOnCond);
95 
96   VPBlockUtils::connectBlocks(VPBB2, VPBB3);
97   VPBlockUtils::connectBlocks(VPBB3, VPBB4);
98   VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB4, "R1");
99   VPBlockUtils::connectBlocks(VPBB1, R1);
100 
101   auto TC = std::make_unique<VPValue>();
102   VPlan Plan(VPPH, &*TC, VPBB1);
103 
104 #if GTEST_HAS_STREAM_REDIRECTION
105   ::testing::internal::CaptureStderr();
106 #endif
107   EXPECT_FALSE(VPlanVerifier::verifyPlanIsValid(Plan));
108 #if GTEST_HAS_STREAM_REDIRECTION
109   EXPECT_STREQ("Use before def!\n",
110                ::testing::internal::GetCapturedStderr().c_str());
111 #endif
112 
113   delete Phi;
114 }
115 } // namespace
116