1 //===- CodeExtractor.cpp - Unit tests for CodeExtractor -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/Transforms/Utils/CodeExtractor.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/IR/BasicBlock.h"
13 #include "llvm/IR/Dominators.h"
14 #include "llvm/IR/LLVMContext.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/IR/Verifier.h"
17 #include "llvm/IRReader/IRReader.h"
18 #include "llvm/Support/SourceMgr.h"
19 #include "gtest/gtest.h"
20 
21 using namespace llvm;
22 
23 namespace {
24 TEST(CodeExtractor, ExitStub) {
25   LLVMContext Ctx;
26   SMDiagnostic Err;
27   std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
28     define i32 @foo(i32 %x, i32 %y, i32 %z) {
29     header:
30       %0 = icmp ugt i32 %x, %y
31       br i1 %0, label %body1, label %body2
32 
33     body1:
34       %1 = add i32 %z, 2
35       br label %notExtracted
36 
37     body2:
38       %2 = mul i32 %z, 7
39       br label %notExtracted
40 
41     notExtracted:
42       %3 = phi i32 [ %1, %body1 ], [ %2, %body2 ]
43       %4 = add i32 %3, %x
44       ret i32 %4
45     }
46   )invalid",
47                                                 Err, Ctx));
48 
49   Function *Func = M->getFunction("foo");
50   SmallVector<BasicBlock *, 3> Candidates;
51   for (auto &BB : *Func) {
52     if (BB.getName() == "body1")
53       Candidates.push_back(&BB);
54     if (BB.getName() == "body2")
55       Candidates.push_back(&BB);
56   }
57   // CodeExtractor requires the first basic block
58   // to dominate all the other ones.
59   Candidates.insert(Candidates.begin(), &Func->getEntryBlock());
60 
61   DominatorTree DT(*Func);
62   CodeExtractor CE(Candidates, &DT);
63   EXPECT_TRUE(CE.isEligible());
64 
65   Function *Outlined = CE.extractCodeRegion();
66   EXPECT_TRUE(Outlined);
67   EXPECT_FALSE(verifyFunction(*Outlined));
68 }
69 } // end anonymous namespace
70