Mercurial > hg > CbC > CbC_llvm
diff unittests/Analysis/CFGTest.cpp @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 803732b1fca8 |
children |
line wrap: on
line diff
--- a/unittests/Analysis/CFGTest.cpp Sat Feb 17 09:57:20 2018 +0900 +++ b/unittests/Analysis/CFGTest.cpp Wed Aug 14 16:55:33 2019 +0900 @@ -1,13 +1,13 @@ //===- CFGTest.cpp - CFG tests --------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/Analysis/CFG.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/AsmParser/Parser.h" #include "llvm/IR/Dominators.h" @@ -58,24 +58,32 @@ report_fatal_error("@test must have an instruction %A"); if (B == nullptr) report_fatal_error("@test must have an instruction %B"); + + assert(ExclusionSet.empty()); + for (auto I = F->begin(), E = F->end(); I != E; ++I) { + if (I->hasName() && I->getName().startswith("excluded")) + ExclusionSet.insert(&*I); + } } void ExpectPath(bool ExpectedResult) { static char ID; class IsPotentiallyReachableTestPass : public FunctionPass { public: - IsPotentiallyReachableTestPass(bool ExpectedResult, - Instruction *A, Instruction *B) - : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B) {} + IsPotentiallyReachableTestPass(bool ExpectedResult, Instruction *A, + Instruction *B, + SmallPtrSet<BasicBlock *, 4> ExclusionSet) + : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B), + ExclusionSet(ExclusionSet) {} - static int initialize() { - PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass", - "", &ID, nullptr, true, true); - PassRegistry::getPassRegistry()->registerPass(*PI, false); - initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry()); - initializeDominatorTreeWrapperPassPass( - *PassRegistry::getPassRegistry()); - return 0; + static int initialize() { + PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass", "", + &ID, nullptr, true, true); + PassRegistry::getPassRegistry()->registerPass(*PI, false); + initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry()); + initializeDominatorTreeWrapperPassPass( + *PassRegistry::getPassRegistry()); + return 0; } void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -91,22 +99,26 @@ LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr), + EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, nullptr), + ExpectedResult); + EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, nullptr), ExpectedResult); - EXPECT_EQ(isPotentiallyReachable(A, B, DT, nullptr), ExpectedResult); - EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, LI), ExpectedResult); - EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult); + EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, LI), + ExpectedResult); + EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, LI), + ExpectedResult); return false; } bool ExpectedResult; Instruction *A, *B; + SmallPtrSet<BasicBlock *, 4> ExclusionSet; }; static int initialize = IsPotentiallyReachableTestPass::initialize(); (void)initialize; IsPotentiallyReachableTestPass *P = - new IsPotentiallyReachableTestPass(ExpectedResult, A, B); + new IsPotentiallyReachableTestPass(ExpectedResult, A, B, ExclusionSet); legacy::PassManager PM; PM.add(P); PM.run(*M); @@ -115,6 +127,7 @@ LLVMContext Context; std::unique_ptr<Module> M; Instruction *A, *B; + SmallPtrSet<BasicBlock *, 4> ExclusionSet; }; } @@ -386,3 +399,109 @@ S[0] = OldBB; ExpectPath(true); } + +TEST_F(IsPotentiallyReachableTest, UnreachableFromEntryTest) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " %A = bitcast i8 undef to i8\n" + " ret void\n" + "not.reachable:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(false); +} + +TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest1) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " ret void\n" + "not.reachable.1:\n" + " %A = bitcast i8 undef to i8\n" + " br label %not.reachable.2\n" + "not.reachable.2:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(true); +} + +TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest2) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " ret void\n" + "not.reachable.1:\n" + " %B = bitcast i8 undef to i8\n" + " br label %not.reachable.2\n" + "not.reachable.2:\n" + " %A = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(false); +} + +TEST_F(IsPotentiallyReachableTest, SimpleExclusionTest) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " %A = bitcast i8 undef to i8\n" + " br label %excluded\n" + "excluded:\n" + " br label %exit\n" + "exit:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(false); +} + +TEST_F(IsPotentiallyReachableTest, DiamondExcludedTest) { + ParseAssembly("declare i1 @switch()\n" + "\n" + "define void @test() {\n" + "entry:\n" + " %x = call i1 @switch()\n" + " %A = bitcast i8 undef to i8\n" + " br i1 %x, label %excluded.1, label %excluded.2\n" + "excluded.1:\n" + " br label %exit\n" + "excluded.2:\n" + " br label %exit\n" + "exit:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(false); +} + +TEST_F(IsPotentiallyReachableTest, DiamondOneSideExcludedTest) { + ParseAssembly("declare i1 @switch()\n" + "\n" + "define void @test() {\n" + "entry:\n" + " %x = call i1 @switch()\n" + " %A = bitcast i8 undef to i8\n" + " br i1 %x, label %excluded, label %diamond\n" + "excluded:\n" + " br label %exit\n" + "diamond:\n" + " br label %exit\n" + "exit:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(true); +} + +TEST_F(IsPotentiallyReachableTest, UnreachableToReachable) { + ParseAssembly("define void @test() {\n" + "entry:\n" + " br label %exit\n" + "unreachableblock:\n" + " %A = bitcast i8 undef to i8\n" + " br label %exit\n" + "exit:\n" + " %B = bitcast i8 undef to i8\n" + " ret void\n" + "}"); + ExpectPath(true); +}