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 // TODO: UseI uses DefI but DefI does not dominate UseI. Currently missed by 61 // the verifier. 62 #if GTEST_HAS_STREAM_REDIRECTION 63 ::testing::internal::CaptureStderr(); 64 #endif 65 EXPECT_TRUE(VPlanVerifier::verifyPlanIsValid(Plan)); 66 #if GTEST_HAS_STREAM_REDIRECTION 67 EXPECT_STREQ("", ::testing::internal::GetCapturedStderr().c_str()); 68 #endif 69 } 70 71 TEST(VPVerifierTest, VPBlendUseBeforeDefDifferentBB) { 72 LLVMContext C; 73 IntegerType *Int32 = IntegerType::get(C, 32); 74 auto *Phi = PHINode::Create(Int32, 1); 75 76 VPInstruction *I1 = new VPInstruction(Instruction::Add, {}); 77 VPInstruction *DefI = new VPInstruction(Instruction::Add, {}); 78 auto *CanIV = new VPCanonicalIVPHIRecipe(I1, {}); 79 VPInstruction *BranchOnCond = 80 new VPInstruction(VPInstruction::BranchOnCond, {CanIV}); 81 auto *Blend = new VPBlendRecipe(Phi, {DefI}); 82 83 VPBasicBlock *VPBB1 = new VPBasicBlock(); 84 VPBasicBlock *VPBB2 = new VPBasicBlock(); 85 VPBasicBlock *VPBB3 = new VPBasicBlock(); 86 VPBasicBlock *VPBB4 = new VPBasicBlock(); 87 88 VPBB1->appendRecipe(I1); 89 VPBB2->appendRecipe(CanIV); 90 VPBB3->appendRecipe(Blend); 91 VPBB4->appendRecipe(DefI); 92 VPBB4->appendRecipe(BranchOnCond); 93 94 VPBlockUtils::connectBlocks(VPBB2, VPBB3); 95 VPBlockUtils::connectBlocks(VPBB3, VPBB4); 96 VPRegionBlock *R1 = new VPRegionBlock(VPBB2, VPBB4, "R1"); 97 VPBlockUtils::connectBlocks(VPBB1, R1); 98 99 VPlan Plan; 100 Plan.setEntry(VPBB1); 101 102 // TODO: Blend uses Def but Def does not dominate Blend. Currently missed by 103 // the verifier. 104 #if GTEST_HAS_STREAM_REDIRECTION 105 ::testing::internal::CaptureStderr(); 106 #endif 107 EXPECT_TRUE(VPlanVerifier::verifyPlanIsValid(Plan)); 108 #if GTEST_HAS_STREAM_REDIRECTION 109 EXPECT_STREQ("", ::testing::internal::GetCapturedStderr().c_str()); 110 #endif 111 112 delete Phi; 113 } 114 } // namespace 115