18267b333SNico Weber //===- CodeExtractor.cpp - Unit tests for CodeExtractor -------------------===//
28267b333SNico Weber //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68267b333SNico Weber //
78267b333SNico Weber //===----------------------------------------------------------------------===//
88267b333SNico Weber 
98267b333SNico Weber #include "llvm/Transforms/Utils/CodeExtractor.h"
108267b333SNico Weber #include "llvm/AsmParser/Parser.h"
1150afaa9dSAditya Kumar #include "llvm/Analysis/AssumptionCache.h"
128267b333SNico Weber #include "llvm/IR/BasicBlock.h"
138267b333SNico Weber #include "llvm/IR/Dominators.h"
14d129569eSVedant Kumar #include "llvm/IR/Instructions.h"
158267b333SNico Weber #include "llvm/IR/LLVMContext.h"
168267b333SNico Weber #include "llvm/IR/Module.h"
178267b333SNico Weber #include "llvm/IR/Verifier.h"
188267b333SNico Weber #include "llvm/IRReader/IRReader.h"
198267b333SNico Weber #include "llvm/Support/SourceMgr.h"
208267b333SNico Weber #include "gtest/gtest.h"
218267b333SNico Weber 
228267b333SNico Weber using namespace llvm;
238267b333SNico Weber 
248267b333SNico Weber namespace {
25d129569eSVedant Kumar BasicBlock *getBlockByName(Function *F, StringRef name) {
26d129569eSVedant Kumar   for (auto &BB : *F)
27d129569eSVedant Kumar     if (BB.getName() == name)
28d129569eSVedant Kumar       return &BB;
29d129569eSVedant Kumar   return nullptr;
30d129569eSVedant Kumar }
31d129569eSVedant Kumar 
32d129569eSVedant Kumar TEST(CodeExtractor, ExitStub) {
338267b333SNico Weber   LLVMContext Ctx;
348267b333SNico Weber   SMDiagnostic Err;
358267b333SNico Weber   std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
368267b333SNico Weber     define i32 @foo(i32 %x, i32 %y, i32 %z) {
378267b333SNico Weber     header:
388267b333SNico Weber       %0 = icmp ugt i32 %x, %y
398267b333SNico Weber       br i1 %0, label %body1, label %body2
408267b333SNico Weber 
418267b333SNico Weber     body1:
428267b333SNico Weber       %1 = add i32 %z, 2
438267b333SNico Weber       br label %notExtracted
448267b333SNico Weber 
458267b333SNico Weber     body2:
468267b333SNico Weber       %2 = mul i32 %z, 7
478267b333SNico Weber       br label %notExtracted
488267b333SNico Weber 
498267b333SNico Weber     notExtracted:
508267b333SNico Weber       %3 = phi i32 [ %1, %body1 ], [ %2, %body2 ]
518267b333SNico Weber       %4 = add i32 %3, %x
528267b333SNico Weber       ret i32 %4
538267b333SNico Weber     }
548267b333SNico Weber   )invalid",
558267b333SNico Weber                                                 Err, Ctx));
568267b333SNico Weber 
578267b333SNico Weber   Function *Func = M->getFunction("foo");
58d129569eSVedant Kumar   SmallVector<BasicBlock *, 3> Candidates{ getBlockByName(Func, "header"),
59d129569eSVedant Kumar                                            getBlockByName(Func, "body1"),
60d129569eSVedant Kumar                                            getBlockByName(Func, "body2") };
618267b333SNico Weber 
620e5dd512SVedant Kumar   CodeExtractor CE(Candidates);
638267b333SNico Weber   EXPECT_TRUE(CE.isEligible());
648267b333SNico Weber 
659852699dSVedant Kumar   CodeExtractorAnalysisCache CEAC(*Func);
669852699dSVedant Kumar   Function *Outlined = CE.extractCodeRegion(CEAC);
678267b333SNico Weber   EXPECT_TRUE(Outlined);
68d129569eSVedant Kumar   BasicBlock *Exit = getBlockByName(Func, "notExtracted");
69d129569eSVedant Kumar   BasicBlock *ExitSplit = getBlockByName(Outlined, "notExtracted.split");
70d129569eSVedant Kumar   // Ensure that PHI in exit block has only one incoming value (from code
71d129569eSVedant Kumar   // replacer block).
72d129569eSVedant Kumar   EXPECT_TRUE(Exit && cast<PHINode>(Exit->front()).getNumIncomingValues() == 1);
73d129569eSVedant Kumar   // Ensure that there is a PHI in outlined function with 2 incoming values.
74d129569eSVedant Kumar   EXPECT_TRUE(ExitSplit &&
75d129569eSVedant Kumar               cast<PHINode>(ExitSplit->front()).getNumIncomingValues() == 2);
768267b333SNico Weber   EXPECT_FALSE(verifyFunction(*Outlined));
77d129569eSVedant Kumar   EXPECT_FALSE(verifyFunction(*Func));
78d129569eSVedant Kumar }
79d129569eSVedant Kumar 
80*9d2c859eSAndrew Litteken TEST(CodeExtractor, InputOutputMonitoring) {
81*9d2c859eSAndrew Litteken   LLVMContext Ctx;
82*9d2c859eSAndrew Litteken   SMDiagnostic Err;
83*9d2c859eSAndrew Litteken   std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
84*9d2c859eSAndrew Litteken     define i32 @foo(i32 %x, i32 %y, i32 %z) {
85*9d2c859eSAndrew Litteken     header:
86*9d2c859eSAndrew Litteken       %0 = icmp ugt i32 %x, %y
87*9d2c859eSAndrew Litteken       br i1 %0, label %body1, label %body2
88*9d2c859eSAndrew Litteken 
89*9d2c859eSAndrew Litteken     body1:
90*9d2c859eSAndrew Litteken       %1 = add i32 %z, 2
91*9d2c859eSAndrew Litteken       br label %notExtracted
92*9d2c859eSAndrew Litteken 
93*9d2c859eSAndrew Litteken     body2:
94*9d2c859eSAndrew Litteken       %2 = mul i32 %z, 7
95*9d2c859eSAndrew Litteken       br label %notExtracted
96*9d2c859eSAndrew Litteken 
97*9d2c859eSAndrew Litteken     notExtracted:
98*9d2c859eSAndrew Litteken       %3 = phi i32 [ %1, %body1 ], [ %2, %body2 ]
99*9d2c859eSAndrew Litteken       %4 = add i32 %3, %x
100*9d2c859eSAndrew Litteken       ret i32 %4
101*9d2c859eSAndrew Litteken     }
102*9d2c859eSAndrew Litteken   )invalid",
103*9d2c859eSAndrew Litteken                                                 Err, Ctx));
104*9d2c859eSAndrew Litteken 
105*9d2c859eSAndrew Litteken   Function *Func = M->getFunction("foo");
106*9d2c859eSAndrew Litteken   SmallVector<BasicBlock *, 3> Candidates{getBlockByName(Func, "header"),
107*9d2c859eSAndrew Litteken                                           getBlockByName(Func, "body1"),
108*9d2c859eSAndrew Litteken                                           getBlockByName(Func, "body2")};
109*9d2c859eSAndrew Litteken 
110*9d2c859eSAndrew Litteken   CodeExtractor CE(Candidates);
111*9d2c859eSAndrew Litteken   EXPECT_TRUE(CE.isEligible());
112*9d2c859eSAndrew Litteken 
113*9d2c859eSAndrew Litteken   CodeExtractorAnalysisCache CEAC(*Func);
114*9d2c859eSAndrew Litteken   SetVector<Value *> Inputs, Outputs;
115*9d2c859eSAndrew Litteken   Function *Outlined = CE.extractCodeRegion(CEAC, Inputs, Outputs);
116*9d2c859eSAndrew Litteken   EXPECT_TRUE(Outlined);
117*9d2c859eSAndrew Litteken 
118*9d2c859eSAndrew Litteken   EXPECT_EQ(Inputs.size(), 3u);
119*9d2c859eSAndrew Litteken   EXPECT_EQ(Inputs[0], Func->getArg(2));
120*9d2c859eSAndrew Litteken   EXPECT_EQ(Inputs[1], Func->getArg(0));
121*9d2c859eSAndrew Litteken   EXPECT_EQ(Inputs[2], Func->getArg(1));
122*9d2c859eSAndrew Litteken   EXPECT_EQ(Outputs.size(), 1u);
123*9d2c859eSAndrew Litteken   StoreInst *SI = cast<StoreInst>(Outlined->getArg(3)->user_back());
124*9d2c859eSAndrew Litteken   Value *OutputVal = SI->getValueOperand();
125*9d2c859eSAndrew Litteken   EXPECT_EQ(Outputs[0], OutputVal);
126*9d2c859eSAndrew Litteken   BasicBlock *Exit = getBlockByName(Func, "notExtracted");
127*9d2c859eSAndrew Litteken   BasicBlock *ExitSplit = getBlockByName(Outlined, "notExtracted.split");
128*9d2c859eSAndrew Litteken   // Ensure that PHI in exit block has only one incoming value (from code
129*9d2c859eSAndrew Litteken   // replacer block).
130*9d2c859eSAndrew Litteken   EXPECT_TRUE(Exit && cast<PHINode>(Exit->front()).getNumIncomingValues() == 1);
131*9d2c859eSAndrew Litteken   // Ensure that there is a PHI in outlined function with 2 incoming values.
132*9d2c859eSAndrew Litteken   EXPECT_TRUE(ExitSplit &&
133*9d2c859eSAndrew Litteken               cast<PHINode>(ExitSplit->front()).getNumIncomingValues() == 2);
134*9d2c859eSAndrew Litteken   EXPECT_FALSE(verifyFunction(*Outlined));
135*9d2c859eSAndrew Litteken   EXPECT_FALSE(verifyFunction(*Func));
136*9d2c859eSAndrew Litteken }
137*9d2c859eSAndrew Litteken 
138d129569eSVedant Kumar TEST(CodeExtractor, ExitPHIOnePredFromRegion) {
139d129569eSVedant Kumar   LLVMContext Ctx;
140d129569eSVedant Kumar   SMDiagnostic Err;
141d129569eSVedant Kumar   std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
142d129569eSVedant Kumar     define i32 @foo() {
143d129569eSVedant Kumar     header:
144d129569eSVedant Kumar       br i1 undef, label %extracted1, label %pred
145d129569eSVedant Kumar 
146d129569eSVedant Kumar     pred:
147d129569eSVedant Kumar       br i1 undef, label %exit1, label %exit2
148d129569eSVedant Kumar 
149d129569eSVedant Kumar     extracted1:
150d129569eSVedant Kumar       br i1 undef, label %extracted2, label %exit1
151d129569eSVedant Kumar 
152d129569eSVedant Kumar     extracted2:
153d129569eSVedant Kumar       br label %exit2
154d129569eSVedant Kumar 
155d129569eSVedant Kumar     exit1:
156d129569eSVedant Kumar       %0 = phi i32 [ 1, %extracted1 ], [ 2, %pred ]
157d129569eSVedant Kumar       ret i32 %0
158d129569eSVedant Kumar 
159d129569eSVedant Kumar     exit2:
160d129569eSVedant Kumar       %1 = phi i32 [ 3, %extracted2 ], [ 4, %pred ]
161d129569eSVedant Kumar       ret i32 %1
162d129569eSVedant Kumar     }
163d129569eSVedant Kumar   )invalid", Err, Ctx));
164d129569eSVedant Kumar 
165d129569eSVedant Kumar   Function *Func = M->getFunction("foo");
166d129569eSVedant Kumar   SmallVector<BasicBlock *, 2> ExtractedBlocks{
167d129569eSVedant Kumar     getBlockByName(Func, "extracted1"),
168d129569eSVedant Kumar     getBlockByName(Func, "extracted2")
169d129569eSVedant Kumar   };
170d129569eSVedant Kumar 
1710e5dd512SVedant Kumar   CodeExtractor CE(ExtractedBlocks);
172d129569eSVedant Kumar   EXPECT_TRUE(CE.isEligible());
173d129569eSVedant Kumar 
1749852699dSVedant Kumar   CodeExtractorAnalysisCache CEAC(*Func);
1759852699dSVedant Kumar   Function *Outlined = CE.extractCodeRegion(CEAC);
176d129569eSVedant Kumar   EXPECT_TRUE(Outlined);
177d129569eSVedant Kumar   BasicBlock *Exit1 = getBlockByName(Func, "exit1");
178d129569eSVedant Kumar   BasicBlock *Exit2 = getBlockByName(Func, "exit2");
179d129569eSVedant Kumar   // Ensure that PHIs in exits are not splitted (since that they have only one
180d129569eSVedant Kumar   // incoming value from extracted region).
181d129569eSVedant Kumar   EXPECT_TRUE(Exit1 &&
182d129569eSVedant Kumar           cast<PHINode>(Exit1->front()).getNumIncomingValues() == 2);
183d129569eSVedant Kumar   EXPECT_TRUE(Exit2 &&
184d129569eSVedant Kumar           cast<PHINode>(Exit2->front()).getNumIncomingValues() == 2);
185d129569eSVedant Kumar   EXPECT_FALSE(verifyFunction(*Outlined));
186d129569eSVedant Kumar   EXPECT_FALSE(verifyFunction(*Func));
1878267b333SNico Weber }
188b2a6f8e5SVedant Kumar 
189b2a6f8e5SVedant Kumar TEST(CodeExtractor, StoreOutputInvokeResultAfterEHPad) {
190b2a6f8e5SVedant Kumar   LLVMContext Ctx;
191b2a6f8e5SVedant Kumar   SMDiagnostic Err;
192b2a6f8e5SVedant Kumar   std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
193b2a6f8e5SVedant Kumar     declare i8 @hoge()
194b2a6f8e5SVedant Kumar 
195b2a6f8e5SVedant Kumar     define i32 @foo() personality i8* null {
196b2a6f8e5SVedant Kumar       entry:
197b2a6f8e5SVedant Kumar         %call = invoke i8 @hoge()
198b2a6f8e5SVedant Kumar                 to label %invoke.cont unwind label %lpad
199b2a6f8e5SVedant Kumar 
200b2a6f8e5SVedant Kumar       invoke.cont:                                      ; preds = %entry
201b2a6f8e5SVedant Kumar         unreachable
202b2a6f8e5SVedant Kumar 
203b2a6f8e5SVedant Kumar       lpad:                                             ; preds = %entry
204b2a6f8e5SVedant Kumar         %0 = landingpad { i8*, i32 }
205b2a6f8e5SVedant Kumar                 catch i8* null
206b2a6f8e5SVedant Kumar         br i1 undef, label %catch, label %finally.catchall
207b2a6f8e5SVedant Kumar 
208b2a6f8e5SVedant Kumar       catch:                                            ; preds = %lpad
209b2a6f8e5SVedant Kumar         %call2 = invoke i8 @hoge()
210b2a6f8e5SVedant Kumar                 to label %invoke.cont2 unwind label %lpad2
211b2a6f8e5SVedant Kumar 
212b2a6f8e5SVedant Kumar       invoke.cont2:                                    ; preds = %catch
213b2a6f8e5SVedant Kumar         %call3 = invoke i8 @hoge()
214b2a6f8e5SVedant Kumar                 to label %invoke.cont3 unwind label %lpad2
215b2a6f8e5SVedant Kumar 
216b2a6f8e5SVedant Kumar       invoke.cont3:                                    ; preds = %invoke.cont2
217b2a6f8e5SVedant Kumar         unreachable
218b2a6f8e5SVedant Kumar 
219b2a6f8e5SVedant Kumar       lpad2:                                           ; preds = %invoke.cont2, %catch
220b2a6f8e5SVedant Kumar         %ex.1 = phi i8* [ undef, %invoke.cont2 ], [ null, %catch ]
221b2a6f8e5SVedant Kumar         %1 = landingpad { i8*, i32 }
222b2a6f8e5SVedant Kumar                 catch i8* null
223b2a6f8e5SVedant Kumar         br label %finally.catchall
224b2a6f8e5SVedant Kumar 
225b2a6f8e5SVedant Kumar       finally.catchall:                                 ; preds = %lpad33, %lpad
226b2a6f8e5SVedant Kumar         %ex.2 = phi i8* [ %ex.1, %lpad2 ], [ null, %lpad ]
227b2a6f8e5SVedant Kumar         unreachable
228b2a6f8e5SVedant Kumar     }
229b2a6f8e5SVedant Kumar   )invalid", Err, Ctx));
230b2a6f8e5SVedant Kumar 
231b2a6f8e5SVedant Kumar 	if (!M) {
232b2a6f8e5SVedant Kumar     Err.print("unit", errs());
233b2a6f8e5SVedant Kumar     exit(1);
234b2a6f8e5SVedant Kumar   }
235b2a6f8e5SVedant Kumar 
236b2a6f8e5SVedant Kumar   Function *Func = M->getFunction("foo");
237b2a6f8e5SVedant Kumar   EXPECT_FALSE(verifyFunction(*Func, &errs()));
238b2a6f8e5SVedant Kumar 
239b2a6f8e5SVedant Kumar   SmallVector<BasicBlock *, 2> ExtractedBlocks{
240b2a6f8e5SVedant Kumar     getBlockByName(Func, "catch"),
241b2a6f8e5SVedant Kumar     getBlockByName(Func, "invoke.cont2"),
242b2a6f8e5SVedant Kumar     getBlockByName(Func, "invoke.cont3"),
243b2a6f8e5SVedant Kumar     getBlockByName(Func, "lpad2")
244b2a6f8e5SVedant Kumar   };
245b2a6f8e5SVedant Kumar 
2460e5dd512SVedant Kumar   CodeExtractor CE(ExtractedBlocks);
247b2a6f8e5SVedant Kumar   EXPECT_TRUE(CE.isEligible());
248b2a6f8e5SVedant Kumar 
2499852699dSVedant Kumar   CodeExtractorAnalysisCache CEAC(*Func);
2509852699dSVedant Kumar   Function *Outlined = CE.extractCodeRegion(CEAC);
251b2a6f8e5SVedant Kumar   EXPECT_TRUE(Outlined);
252b2a6f8e5SVedant Kumar   EXPECT_FALSE(verifyFunction(*Outlined, &errs()));
253b2a6f8e5SVedant Kumar   EXPECT_FALSE(verifyFunction(*Func, &errs()));
254b2a6f8e5SVedant Kumar }
255b2a6f8e5SVedant Kumar 
2560e5dd512SVedant Kumar TEST(CodeExtractor, StoreOutputInvokeResultInExitStub) {
2570e5dd512SVedant Kumar   LLVMContext Ctx;
2580e5dd512SVedant Kumar   SMDiagnostic Err;
2590e5dd512SVedant Kumar   std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
2600e5dd512SVedant Kumar     declare i32 @bar()
2610e5dd512SVedant Kumar 
2620e5dd512SVedant Kumar     define i32 @foo() personality i8* null {
2630e5dd512SVedant Kumar     entry:
2640e5dd512SVedant Kumar       %0 = invoke i32 @bar() to label %exit unwind label %lpad
2650e5dd512SVedant Kumar 
2660e5dd512SVedant Kumar     exit:
2670e5dd512SVedant Kumar       ret i32 %0
2680e5dd512SVedant Kumar 
2690e5dd512SVedant Kumar     lpad:
2700e5dd512SVedant Kumar       %1 = landingpad { i8*, i32 }
2710e5dd512SVedant Kumar               cleanup
2720e5dd512SVedant Kumar       resume { i8*, i32 } %1
2730e5dd512SVedant Kumar     }
2740e5dd512SVedant Kumar   )invalid",
2750e5dd512SVedant Kumar                                                 Err, Ctx));
2760e5dd512SVedant Kumar 
2770e5dd512SVedant Kumar   Function *Func = M->getFunction("foo");
2780e5dd512SVedant Kumar   SmallVector<BasicBlock *, 1> Blocks{ getBlockByName(Func, "entry"),
2790e5dd512SVedant Kumar                                        getBlockByName(Func, "lpad") };
2800e5dd512SVedant Kumar 
2810e5dd512SVedant Kumar   CodeExtractor CE(Blocks);
2820e5dd512SVedant Kumar   EXPECT_TRUE(CE.isEligible());
2830e5dd512SVedant Kumar 
2849852699dSVedant Kumar   CodeExtractorAnalysisCache CEAC(*Func);
2859852699dSVedant Kumar   Function *Outlined = CE.extractCodeRegion(CEAC);
2860e5dd512SVedant Kumar   EXPECT_TRUE(Outlined);
2870e5dd512SVedant Kumar   EXPECT_FALSE(verifyFunction(*Outlined));
2880e5dd512SVedant Kumar   EXPECT_FALSE(verifyFunction(*Func));
2890e5dd512SVedant Kumar }
2900e5dd512SVedant Kumar 
29150afaa9dSAditya Kumar TEST(CodeExtractor, ExtractAndInvalidateAssumptionCache) {
29250afaa9dSAditya Kumar   LLVMContext Ctx;
29350afaa9dSAditya Kumar   SMDiagnostic Err;
29450afaa9dSAditya Kumar   std::unique_ptr<Module> M(parseAssemblyString(R"ir(
29550afaa9dSAditya Kumar         target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
29650afaa9dSAditya Kumar         target triple = "aarch64"
29750afaa9dSAditya Kumar 
29850afaa9dSAditya Kumar         %b = type { i64 }
29950afaa9dSAditya Kumar         declare void @g(i8*)
30050afaa9dSAditya Kumar 
30150afaa9dSAditya Kumar         declare void @llvm.assume(i1) #0
30250afaa9dSAditya Kumar 
30350afaa9dSAditya Kumar         define void @test() {
30450afaa9dSAditya Kumar         entry:
30550afaa9dSAditya Kumar           br label %label
30650afaa9dSAditya Kumar 
30750afaa9dSAditya Kumar         label:
30850afaa9dSAditya Kumar           %0 = load %b*, %b** inttoptr (i64 8 to %b**), align 8
30950afaa9dSAditya Kumar           %1 = getelementptr inbounds %b, %b* %0, i64 undef, i32 0
31050afaa9dSAditya Kumar           %2 = load i64, i64* %1, align 8
31150afaa9dSAditya Kumar           %3 = icmp ugt i64 %2, 1
31250afaa9dSAditya Kumar           br i1 %3, label %if.then, label %if.else
31350afaa9dSAditya Kumar 
31450afaa9dSAditya Kumar         if.then:
31550afaa9dSAditya Kumar           unreachable
31650afaa9dSAditya Kumar 
31750afaa9dSAditya Kumar         if.else:
31850afaa9dSAditya Kumar           call void @g(i8* undef)
31950afaa9dSAditya Kumar           store i64 undef, i64* null, align 536870912
32050afaa9dSAditya Kumar           %4 = icmp eq i64 %2, 0
32150afaa9dSAditya Kumar           call void @llvm.assume(i1 %4)
32250afaa9dSAditya Kumar           unreachable
32350afaa9dSAditya Kumar         }
32450afaa9dSAditya Kumar 
32550afaa9dSAditya Kumar         attributes #0 = { nounwind willreturn }
32650afaa9dSAditya Kumar   )ir",
32750afaa9dSAditya Kumar                                                 Err, Ctx));
32850afaa9dSAditya Kumar 
32950afaa9dSAditya Kumar   assert(M && "Could not parse module?");
33050afaa9dSAditya Kumar   Function *Func = M->getFunction("test");
33150afaa9dSAditya Kumar   SmallVector<BasicBlock *, 1> Blocks{ getBlockByName(Func, "if.else") };
33250afaa9dSAditya Kumar   AssumptionCache AC(*Func);
33350afaa9dSAditya Kumar   CodeExtractor CE(Blocks, nullptr, false, nullptr, nullptr, &AC);
33450afaa9dSAditya Kumar   EXPECT_TRUE(CE.isEligible());
33550afaa9dSAditya Kumar 
3369852699dSVedant Kumar   CodeExtractorAnalysisCache CEAC(*Func);
3379852699dSVedant Kumar   Function *Outlined = CE.extractCodeRegion(CEAC);
33850afaa9dSAditya Kumar   EXPECT_TRUE(Outlined);
33950afaa9dSAditya Kumar   EXPECT_FALSE(verifyFunction(*Outlined));
34050afaa9dSAditya Kumar   EXPECT_FALSE(verifyFunction(*Func));
3418359511cSVedant Kumar   EXPECT_FALSE(CE.verifyAssumptionCache(*Func, *Outlined, &AC));
34250afaa9dSAditya Kumar }
343700d2417SGiorgis Georgakoudis 
344700d2417SGiorgis Georgakoudis TEST(CodeExtractor, RemoveBitcastUsesFromOuterLifetimeMarkers) {
345700d2417SGiorgis Georgakoudis   LLVMContext Ctx;
346700d2417SGiorgis Georgakoudis   SMDiagnostic Err;
347700d2417SGiorgis Georgakoudis   std::unique_ptr<Module> M(parseAssemblyString(R"ir(
348700d2417SGiorgis Georgakoudis     target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
349700d2417SGiorgis Georgakoudis     target triple = "x86_64-unknown-linux-gnu"
350700d2417SGiorgis Georgakoudis 
351700d2417SGiorgis Georgakoudis     declare void @use(i32*)
352700d2417SGiorgis Georgakoudis     declare void @llvm.lifetime.start.p0i8(i64, i8*)
353700d2417SGiorgis Georgakoudis     declare void @llvm.lifetime.end.p0i8(i64, i8*)
354700d2417SGiorgis Georgakoudis 
355700d2417SGiorgis Georgakoudis     define void @foo() {
356700d2417SGiorgis Georgakoudis     entry:
357700d2417SGiorgis Georgakoudis       %0 = alloca i32
358700d2417SGiorgis Georgakoudis       br label %extract
359700d2417SGiorgis Georgakoudis 
360700d2417SGiorgis Georgakoudis     extract:
361700d2417SGiorgis Georgakoudis       %1 = bitcast i32* %0 to i8*
362700d2417SGiorgis Georgakoudis       call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
363700d2417SGiorgis Georgakoudis       call void @use(i32* %0)
364700d2417SGiorgis Georgakoudis       br label %exit
365700d2417SGiorgis Georgakoudis 
366700d2417SGiorgis Georgakoudis     exit:
367700d2417SGiorgis Georgakoudis       call void @use(i32* %0)
368700d2417SGiorgis Georgakoudis       call void @llvm.lifetime.end.p0i8(i64 4, i8* %1)
369700d2417SGiorgis Georgakoudis       ret void
370700d2417SGiorgis Georgakoudis     }
371700d2417SGiorgis Georgakoudis   )ir",
372700d2417SGiorgis Georgakoudis                                                 Err, Ctx));
373700d2417SGiorgis Georgakoudis 
374700d2417SGiorgis Georgakoudis   Function *Func = M->getFunction("foo");
375700d2417SGiorgis Georgakoudis   SmallVector<BasicBlock *, 1> Blocks{getBlockByName(Func, "extract")};
376700d2417SGiorgis Georgakoudis 
377700d2417SGiorgis Georgakoudis   CodeExtractor CE(Blocks);
378700d2417SGiorgis Georgakoudis   EXPECT_TRUE(CE.isEligible());
379700d2417SGiorgis Georgakoudis 
380700d2417SGiorgis Georgakoudis   CodeExtractorAnalysisCache CEAC(*Func);
381700d2417SGiorgis Georgakoudis   SetVector<Value *> Inputs, Outputs, SinkingCands, HoistingCands;
382700d2417SGiorgis Georgakoudis   BasicBlock *CommonExit = nullptr;
383700d2417SGiorgis Georgakoudis   CE.findAllocas(CEAC, SinkingCands, HoistingCands, CommonExit);
384700d2417SGiorgis Georgakoudis   CE.findInputsOutputs(Inputs, Outputs, SinkingCands);
385700d2417SGiorgis Georgakoudis   EXPECT_EQ(Outputs.size(), 0U);
386700d2417SGiorgis Georgakoudis 
387700d2417SGiorgis Georgakoudis   Function *Outlined = CE.extractCodeRegion(CEAC);
388700d2417SGiorgis Georgakoudis   EXPECT_TRUE(Outlined);
389700d2417SGiorgis Georgakoudis   EXPECT_FALSE(verifyFunction(*Outlined));
390700d2417SGiorgis Georgakoudis   EXPECT_FALSE(verifyFunction(*Func));
391700d2417SGiorgis Georgakoudis }
3928267b333SNico Weber } // end anonymous namespace
393