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