xref: /llvm-project/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp (revision b6b3d20d06987d33f18a68c02dfefc792d1b0b01)
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 #if GTEST_HAS_STREAM_REDIRECTION
61   ::testing::internal::CaptureStderr();
62 #endif
63   EXPECT_FALSE(VPlanVerifier::verifyPlanIsValid(Plan));
64 #if GTEST_HAS_STREAM_REDIRECTION
65   EXPECT_STREQ("Use before def!\n",
66                ::testing::internal::GetCapturedStderr().c_str());
67 #endif
68 }
69 
70 TEST(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) {
71   LLVMContext C;
72   IntegerType *Int32 = IntegerType::get(C, 32);
73   auto *Phi = PHINode::Create(Int32, 1);
74 
75   VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
76   VPInstruction *DefI = new VPInstruction(Instruction::Add, {});
77   auto *CanIV = new VPCanonicalIVPHIRecipe(I1, {});
78   VPInstruction *BranchOnCond =
79       new VPInstruction(VPInstruction::BranchOnCond, {CanIV});
80   auto *Blend = new VPBlendRecipe(Phi, {DefI});
81 
82   VPBasicBlock *VPBB1 = new VPBasicBlock();
83   VPBasicBlock *VPBB2 = new VPBasicBlock();
84   VPBasicBlock *VPBB3 = new VPBasicBlock();
85   VPBasicBlock *VPBB4 = new VPBasicBlock();
86 
87   VPBB1->appendRecipe(I1);
88   VPBB2->appendRecipe(CanIV);
89   VPBB3->appendRecipe(Blend);
90   VPBB4->appendRecipe(DefI);
91   VPBB4->appendRecipe(BranchOnCond);
92 
93   VPBlockUtils::connectBlocks(VPBB2, VPBB3);
94   VPBlockUtils::connectBlocks(VPBB3, VPBB4);
95   VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB4, "R1");
96   VPBlockUtils::connectBlocks(VPBB1, R1);
97 
98   VPlan Plan;
99   Plan.setEntry(VPBB1);
100 
101 #if GTEST_HAS_STREAM_REDIRECTION
102   ::testing::internal::CaptureStderr();
103 #endif
104   EXPECT_FALSE(VPlanVerifier::verifyPlanIsValid(Plan));
105 #if GTEST_HAS_STREAM_REDIRECTION
106   EXPECT_STREQ("Use before def!\n",
107                ::testing::internal::GetCapturedStderr().c_str());
108 #endif
109 
110   delete Phi;
111 }
112 } // namespace
113