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