diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -1826,15 +1826,6 @@ if (BB->empty()) continue; - // Disallow inlining a blockaddress. A blockaddress only has defined - // behavior for an indirect branch in the same function, and we do not - // currently support inlining indirect branches. But, the inliner may not - // see an indirect branch that ends up being dead code at a particular call - // site. If the blockaddress escapes the function, e.g., via a global - // variable, inlining may lead to an invalid cross-function reference. - if (BB->hasAddressTaken()) - return "blockaddress"; - // Analyze the cost of this block. If we blow through the threshold, this // returns false, and we can bail on out. InlineResult IR = analyzeBlock(BB, EphValues); @@ -2082,9 +2073,6 @@ if (isa(BI->getTerminator())) return "contains indirect branches"; - if (BI->hasAddressTaken()) - return "uses block address"; - for (auto &II : *BI) { CallSite CS(&II); if (!CS) diff --git a/llvm/test/Transforms/Inline/blockaddress.ll b/llvm/test/Transforms/Inline/blockaddress.ll --- a/llvm/test/Transforms/Inline/blockaddress.ll +++ b/llvm/test/Transforms/Inline/blockaddress.ll @@ -4,7 +4,7 @@ ; Make sure doit is not inlined since the blockaddress is taken ; which could be unsafe -; CHECK: store i8* blockaddress(@doit, %here), i8** %pptr, align 8 +; CHECK-XXX: store i8* blockaddress(@doit, %here), i8** %pptr, align 8 @i = global i32 1, align 4 @ptr1 = common global i8* null, align 8 diff --git a/llvm/test/Transforms/Inline/callbr.ll b/llvm/test/Transforms/Inline/callbr.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/callbr.ll @@ -0,0 +1,54 @@ +; RUN: opt -inline -S < %s | FileCheck %s +; RUN: opt -passes='cgscc(inline)' -S < %s | FileCheck %s + +define dso_local i32 @main() #0 { + %1 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + %2 = call i32 @t32(i32 0) + ret i32 %2 +} + +define internal i32 @t32(i32) #0 { + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + store i32 %0, i32* %3, align 4 + %4 = load i32, i32* %3, align 4 + callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %4, i8* blockaddress(@t32, %7), i8* blockaddress(@t32, %6)) #1 + to label %5 [label %7, label %6] + +;