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