1 //===- CodeExtractor.cpp - Unit tests for CodeExtractor -------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/Utils/CodeExtractor.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/Analysis/AssumptionCache.h"
12 #include "llvm/IR/BasicBlock.h"
13 #include "llvm/IR/Dominators.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/IR/Verifier.h"
18 #include "llvm/IRReader/IRReader.h"
19 #include "llvm/Support/SourceMgr.h"
20 #include "gtest/gtest.h"
25 BasicBlock
*getBlockByName(Function
*F
, StringRef name
) {
27 if (BB
.getName() == name
)
32 TEST(CodeExtractor
, ExitStub
) {
35 std::unique_ptr
<Module
> M(parseAssemblyString(R
"invalid(
36 define i32 @foo(i32 %x, i32 %y, i32 %z) {
38 %0 = icmp ugt i32 %x, %y
39 br i1 %0, label %body1, label %body2
43 br label %notExtracted
47 br label %notExtracted
50 %3 = phi i32 [ %1, %body1 ], [ %2, %body2 ]
57 Function
*Func
= M
->getFunction("foo");
58 SmallVector
<BasicBlock
*, 3> Candidates
{ getBlockByName(Func
, "header"),
59 getBlockByName(Func
, "body1"),
60 getBlockByName(Func
, "body2") };
62 CodeExtractor
CE(Candidates
);
63 EXPECT_TRUE(CE
.isEligible());
65 CodeExtractorAnalysisCache
CEAC(*Func
);
66 Function
*Outlined
= CE
.extractCodeRegion(CEAC
);
67 EXPECT_TRUE(Outlined
);
68 BasicBlock
*Exit
= getBlockByName(Func
, "notExtracted");
69 BasicBlock
*ExitSplit
= getBlockByName(Outlined
, "notExtracted.split");
70 // Ensure that PHI in exit block has only one incoming value (from code
72 EXPECT_TRUE(Exit
&& cast
<PHINode
>(Exit
->front()).getNumIncomingValues() == 1);
73 // Ensure that there is a PHI in outlined function with 2 incoming values.
74 EXPECT_TRUE(ExitSplit
&&
75 cast
<PHINode
>(ExitSplit
->front()).getNumIncomingValues() == 2);
76 EXPECT_FALSE(verifyFunction(*Outlined
));
77 EXPECT_FALSE(verifyFunction(*Func
));
80 TEST(CodeExtractor
, ExitPHIOnePredFromRegion
) {
83 std::unique_ptr
<Module
> M(parseAssemblyString(R
"invalid(
86 br i1 undef, label %extracted1, label %pred
89 br i1 undef, label %exit1, label %exit2
92 br i1 undef, label %extracted2, label %exit1
98 %0 = phi i32 [ 1, %extracted1 ], [ 2, %pred ]
102 %1 = phi i32 [ 3, %extracted2 ], [ 4, %pred ]
105 )invalid", Err
, Ctx
));
107 Function
*Func
= M
->getFunction("foo");
108 SmallVector
<BasicBlock
*, 2> ExtractedBlocks
{
109 getBlockByName(Func
, "extracted1"),
110 getBlockByName(Func
, "extracted2")
113 CodeExtractor
CE(ExtractedBlocks
);
114 EXPECT_TRUE(CE
.isEligible());
116 CodeExtractorAnalysisCache
CEAC(*Func
);
117 Function
*Outlined
= CE
.extractCodeRegion(CEAC
);
118 EXPECT_TRUE(Outlined
);
119 BasicBlock
*Exit1
= getBlockByName(Func
, "exit1");
120 BasicBlock
*Exit2
= getBlockByName(Func
, "exit2");
121 // Ensure that PHIs in exits are not splitted (since that they have only one
122 // incoming value from extracted region).
124 cast
<PHINode
>(Exit1
->front()).getNumIncomingValues() == 2);
126 cast
<PHINode
>(Exit2
->front()).getNumIncomingValues() == 2);
127 EXPECT_FALSE(verifyFunction(*Outlined
));
128 EXPECT_FALSE(verifyFunction(*Func
));
131 TEST(CodeExtractor
, StoreOutputInvokeResultAfterEHPad
) {
134 std::unique_ptr
<Module
> M(parseAssemblyString(R
"invalid(
137 define i32 @foo() personality i8* null {
139 %call = invoke i8 @hoge()
140 to label %invoke.cont unwind label %lpad
142 invoke.cont: ; preds = %entry
145 lpad: ; preds = %entry
146 %0 = landingpad { i8*, i32 }
148 br i1 undef, label %catch, label %finally.catchall
150 catch: ; preds = %lpad
151 %call2 = invoke i8 @hoge()
152 to label %invoke.cont2 unwind label %lpad2
154 invoke.cont2: ; preds = %catch
155 %call3 = invoke i8 @hoge()
156 to label %invoke.cont3 unwind label %lpad2
158 invoke.cont3: ; preds = %invoke.cont2
161 lpad2: ; preds = %invoke.cont2, %catch
162 %ex.1 = phi i8* [ undef, %invoke.cont2 ], [ null, %catch ]
163 %1 = landingpad { i8*, i32 }
165 br label %finally.catchall
167 finally.catchall: ; preds = %lpad33, %lpad
168 %ex.2 = phi i8* [ %ex.1, %lpad2 ], [ null, %lpad ]
171 )invalid", Err
, Ctx
));
174 Err
.print("unit", errs());
178 Function
*Func
= M
->getFunction("foo");
179 EXPECT_FALSE(verifyFunction(*Func
, &errs()));
181 SmallVector
<BasicBlock
*, 2> ExtractedBlocks
{
182 getBlockByName(Func
, "catch"),
183 getBlockByName(Func
, "invoke.cont2"),
184 getBlockByName(Func
, "invoke.cont3"),
185 getBlockByName(Func
, "lpad2")
188 CodeExtractor
CE(ExtractedBlocks
);
189 EXPECT_TRUE(CE
.isEligible());
191 CodeExtractorAnalysisCache
CEAC(*Func
);
192 Function
*Outlined
= CE
.extractCodeRegion(CEAC
);
193 EXPECT_TRUE(Outlined
);
194 EXPECT_FALSE(verifyFunction(*Outlined
, &errs()));
195 EXPECT_FALSE(verifyFunction(*Func
, &errs()));
198 TEST(CodeExtractor
, StoreOutputInvokeResultInExitStub
) {
201 std::unique_ptr
<Module
> M(parseAssemblyString(R
"invalid(
204 define i32 @foo() personality i8* null {
206 %0 = invoke i32 @bar() to label %exit unwind label %lpad
212 %1 = landingpad { i8*, i32 }
214 resume { i8*, i32 } %1
219 Function
*Func
= M
->getFunction("foo");
220 SmallVector
<BasicBlock
*, 1> Blocks
{ getBlockByName(Func
, "entry"),
221 getBlockByName(Func
, "lpad") };
223 CodeExtractor
CE(Blocks
);
224 EXPECT_TRUE(CE
.isEligible());
226 CodeExtractorAnalysisCache
CEAC(*Func
);
227 Function
*Outlined
= CE
.extractCodeRegion(CEAC
);
228 EXPECT_TRUE(Outlined
);
229 EXPECT_FALSE(verifyFunction(*Outlined
));
230 EXPECT_FALSE(verifyFunction(*Func
));
233 TEST(CodeExtractor
, ExtractAndInvalidateAssumptionCache
) {
236 std::unique_ptr
<Module
> M(parseAssemblyString(R
"ir(
237 target datalayout = "e
-m
:e
-i8
:8:32-i16
:16:32-i64
:64-i128
:128-n32
:64-S128
"
238 target triple = "aarch64
"
243 declare void @llvm.assume(i1) #0
245 define void @test() {
250 %0 = load %b*, %b** inttoptr (i64 8 to %b**), align 8
251 %1 = getelementptr inbounds %b, %b* %0, i64 undef, i32 0
252 %2 = load i64, i64* %1, align 8
253 %3 = icmp ugt i64 %2, 1
254 br i1 %3, label %if.then, label %if.else
260 call void @g(i8* undef)
261 store i64 undef, i64* null, align 536870912
262 %4 = icmp eq i64 %2, 0
263 call void @llvm.assume(i1 %4)
267 attributes #0 = { nounwind willreturn }
271 assert(M
&& "Could not parse module?");
272 Function
*Func
= M
->getFunction("test");
273 SmallVector
<BasicBlock
*, 1> Blocks
{ getBlockByName(Func
, "if.else") };
274 AssumptionCache
AC(*Func
);
275 CodeExtractor
CE(Blocks
, nullptr, false, nullptr, nullptr, &AC
);
276 EXPECT_TRUE(CE
.isEligible());
278 CodeExtractorAnalysisCache
CEAC(*Func
);
279 Function
*Outlined
= CE
.extractCodeRegion(CEAC
);
280 EXPECT_TRUE(Outlined
);
281 EXPECT_FALSE(verifyFunction(*Outlined
));
282 EXPECT_FALSE(verifyFunction(*Func
));
283 EXPECT_FALSE(CE
.verifyAssumptionCache(*Func
, &AC
));
285 } // end anonymous namespace