1 //===- llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp ----------===//
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
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"
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 VPlan
Plan(VPPH
, &*TC
, VPBB1
);
30 #if GTEST_HAS_STREAM_REDIRECTION
31 ::testing::internal::CaptureStderr();
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());
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
});
47 VPBasicBlock
*VPPH
= new VPBasicBlock("ph");
48 VPBasicBlock
*VPBB1
= new VPBasicBlock();
49 VPBasicBlock
*VPBB2
= new VPBasicBlock();
51 VPBB1
->appendRecipe(UseI
);
52 VPBB2
->appendRecipe(CanIV
);
53 VPBB2
->appendRecipe(DefI
);
54 VPBB2
->appendRecipe(BranchOnCond
);
56 VPRegionBlock
*R1
= new VPRegionBlock(VPBB2
, VPBB2
, "R1");
57 VPBlockUtils::connectBlocks(VPBB1
, R1
);
59 auto TC
= std::make_unique
<VPValue
>();
60 VPlan
Plan(VPPH
, &*TC
, VPBB1
);
62 #if GTEST_HAS_STREAM_REDIRECTION
63 ::testing::internal::CaptureStderr();
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());
72 TEST(VPVerifierTest
, VPBlendUseBeforeDefDifferentBB
) {
74 IntegerType
*Int32
= IntegerType::get(C
, 32);
75 auto *Phi
= PHINode::Create(Int32
, 1);
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
});
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();
90 VPBB1
->appendRecipe(I1
);
91 VPBB2
->appendRecipe(CanIV
);
92 VPBB3
->appendRecipe(Blend
);
93 VPBB4
->appendRecipe(DefI
);
94 VPBB4
->appendRecipe(BranchOnCond
);
96 VPBlockUtils::connectBlocks(VPBB2
, VPBB3
);
97 VPBlockUtils::connectBlocks(VPBB3
, VPBB4
);
98 VPRegionBlock
*R1
= new VPRegionBlock(VPBB2
, VPBB4
, "R1");
99 VPBlockUtils::connectBlocks(VPBB1
, R1
);
101 auto TC
= std::make_unique
<VPValue
>();
102 VPlan
Plan(VPPH
, &*TC
, VPBB1
);
104 #if GTEST_HAS_STREAM_REDIRECTION
105 ::testing::internal::CaptureStderr();
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());