xref: /llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp (revision c29900687983824ca66fbd83491390873523339e)
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, DISABLED_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   // CodeExtractor miscompiles this function. There appear to be some issues
50   // with the handling of outlined regions with live output values.
51   //
52   // In the original function, CE adds two reloads in the codeReplacer block:
53   //
54   //   codeRepl:                                         ; preds = %header
55   //     call void @foo_header.split(i32 %z, i32 %x, i32 %y, i32* %.loc, i32* %.loc1)
56   //     %.reload = load i32, i32* %.loc
57   //     %.reload2 = load i32, i32* %.loc1
58   //     br label %notExtracted
59   //
60   // These reloads must flow into the notExtracted block:
61   //
62   //   notExtracted:                                     ; preds = %codeRepl
63   //     %0 = phi i32 [ %.reload, %codeRepl ], [ %.reload2, %body2 ]
64   //
65   // The problem is that the PHI node in notExtracted now has an incoming
66   // value from a BasicBlock that's in a different function.
67 
68   Function *Func = M->getFunction("foo");
69   SmallVector<BasicBlock *, 3> Candidates;
70   for (auto &BB : *Func) {
71     if (BB.getName() == "body1")
72       Candidates.push_back(&BB);
73     if (BB.getName() == "body2")
74       Candidates.push_back(&BB);
75   }
76   // CodeExtractor requires the first basic block
77   // to dominate all the other ones.
78   Candidates.insert(Candidates.begin(), &Func->getEntryBlock());
79 
80   DominatorTree DT(*Func);
81   CodeExtractor CE(Candidates, &DT);
82   EXPECT_TRUE(CE.isEligible());
83 
84   Function *Outlined = CE.extractCodeRegion();
85   EXPECT_TRUE(Outlined);
86   EXPECT_FALSE(verifyFunction(*Outlined));
87 }
88 } // end anonymous namespace
89