From d335c1317b6170918311fcbccc39fe31b3a84bda Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Mon, 22 Jun 2020 13:22:16 -0700 Subject: [PATCH] Fix dynamic alloca detection in CloneBasicBlock Summary: Simply check AI->isStaticAlloca instead of reimplementing checks for static/dynamic allocas. Reviewers: efriedma Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D82328 --- llvm/lib/Transforms/Utils/CloneFunction.cpp | 9 ++-- llvm/unittests/Transforms/Utils/CloningTest.cpp | 59 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index fce926f..788983c 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -46,7 +46,7 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, if (BB->hasName()) NewBB->setName(BB->getName() + NameSuffix); - bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false; + bool hasCalls = false, hasDynamicAllocas = false; Module *TheModule = F ? F->getParent() : nullptr; // Loop over all instructions, and copy them over. @@ -62,18 +62,15 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, hasCalls |= (isa(I) && !isa(I)); if (const AllocaInst *AI = dyn_cast(&I)) { - if (isa(AI->getArraySize())) - hasStaticAllocas = true; - else + if (!AI->isStaticAlloca()) { hasDynamicAllocas = true; + } } } if (CodeInfo) { CodeInfo->ContainsCalls |= hasCalls; CodeInfo->ContainsDynamicAllocas |= hasDynamicAllocas; - CodeInfo->ContainsDynamicAllocas |= hasStaticAllocas && - BB != &BB->getParent()->getEntryBlock(); } return NewBB; } diff --git a/llvm/unittests/Transforms/Utils/CloningTest.cpp b/llvm/unittests/Transforms/Utils/CloningTest.cpp index 28ad4bc..fc0b3de 100644 --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -659,6 +659,65 @@ static int GetDICompileUnitCount(const Module& M) { return 0; } +TEST(CloneFunction, CloneEmptyFunction) { + StringRef ImplAssembly = R"( + define void @foo() { + ret void + } + declare void @bar() + )"; + + LLVMContext Context; + SMDiagnostic Error; + + auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context); + EXPECT_TRUE(ImplModule != nullptr); + auto *ImplFunction = ImplModule->getFunction("foo"); + EXPECT_TRUE(ImplFunction != nullptr); + auto *DeclFunction = ImplModule->getFunction("bar"); + EXPECT_TRUE(DeclFunction != nullptr); + + ValueToValueMapTy VMap; + SmallVector Returns; + ClonedCodeInfo CCI; + CloneFunctionInto(DeclFunction, ImplFunction, VMap, true, Returns, "", &CCI); + + EXPECT_FALSE(verifyModule(*ImplModule, &errs())); + EXPECT_FALSE(CCI.ContainsCalls); + EXPECT_FALSE(CCI.ContainsDynamicAllocas); +} + +TEST(CloneFunction, CloneFunctionWithInalloca) { + StringRef ImplAssembly = R"( + declare void @a(i32* inalloca) + define void @foo() { + %a = alloca inalloca i32 + call void @a(i32* inalloca %a) + ret void + } + declare void @bar() + )"; + + LLVMContext Context; + SMDiagnostic Error; + + auto ImplModule = parseAssemblyString(ImplAssembly, Error, Context); + EXPECT_TRUE(ImplModule != nullptr); + auto *ImplFunction = ImplModule->getFunction("foo"); + EXPECT_TRUE(ImplFunction != nullptr); + auto *DeclFunction = ImplModule->getFunction("bar"); + EXPECT_TRUE(DeclFunction != nullptr); + + ValueToValueMapTy VMap; + SmallVector Returns; + ClonedCodeInfo CCI; + CloneFunctionInto(DeclFunction, ImplFunction, VMap, true, Returns, "", &CCI); + + EXPECT_FALSE(verifyModule(*ImplModule, &errs())); + EXPECT_TRUE(CCI.ContainsCalls); + EXPECT_TRUE(CCI.ContainsDynamicAllocas); +} + TEST(CloneFunction, CloneFunctionToDifferentModule) { StringRef ImplAssembly = R"( define void @foo() { -- 2.7.4