diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -46,7 +46,7 @@ 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 @@ 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 --- a/llvm/unittests/Transforms/Utils/CloningTest.cpp +++ b/llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -659,6 +659,65 @@ 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() {