mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-18 12:27:55 +00:00
Remap blockaddress correctly when inlining a function. Fixes PR10162.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142684 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -113,8 +113,23 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
|||||||
|
|
||||||
// Create a new basic block and copy instructions into it!
|
// Create a new basic block and copy instructions into it!
|
||||||
BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo);
|
BasicBlock *CBB = CloneBasicBlock(&BB, VMap, NameSuffix, NewFunc, CodeInfo);
|
||||||
VMap[&BB] = CBB; // Add basic block mapping.
|
|
||||||
|
|
||||||
|
// Add basic block mapping.
|
||||||
|
VMap[&BB] = CBB;
|
||||||
|
|
||||||
|
// It is only legal to clone a function if a block address within that
|
||||||
|
// function is never referenced outside of the function. Given that, we
|
||||||
|
// want to map block addresses from the old function to block addresses in
|
||||||
|
// the clone. (This is different from the generic ValueMapper
|
||||||
|
// implementation, which generates an invalid blockaddress when
|
||||||
|
// cloning a function.)
|
||||||
|
if (BB.hasAddressTaken()) {
|
||||||
|
Constant *OldBBAddr = BlockAddress::get(const_cast<Function*>(OldFunc),
|
||||||
|
const_cast<BasicBlock*>(&BB));
|
||||||
|
VMap[OldBBAddr] = BlockAddress::get(NewFunc, CBB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note return instructions for the caller.
|
||||||
if (ReturnInst *RI = dyn_cast<ReturnInst>(CBB->getTerminator()))
|
if (ReturnInst *RI = dyn_cast<ReturnInst>(CBB->getTerminator()))
|
||||||
Returns.push_back(RI);
|
Returns.push_back(RI);
|
||||||
}
|
}
|
||||||
@@ -224,6 +239,22 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
|
|||||||
BBEntry = NewBB = BasicBlock::Create(BB->getContext());
|
BBEntry = NewBB = BasicBlock::Create(BB->getContext());
|
||||||
if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix);
|
if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix);
|
||||||
|
|
||||||
|
// It is only legal to clone a function if a block address within that
|
||||||
|
// function is never referenced outside of the function. Given that, we
|
||||||
|
// want to map block addresses from the old function to block addresses in
|
||||||
|
// the clone. (This is different from the generic ValueMapper
|
||||||
|
// implementation, which generates an invalid blockaddress when
|
||||||
|
// cloning a function.)
|
||||||
|
//
|
||||||
|
// Note that we don't need to fix the mapping for unreachable blocks;
|
||||||
|
// the default mapping there is safe.
|
||||||
|
if (BB->hasAddressTaken()) {
|
||||||
|
Constant *OldBBAddr = BlockAddress::get(const_cast<Function*>(OldFunc),
|
||||||
|
const_cast<BasicBlock*>(BB));
|
||||||
|
VMap[OldBBAddr] = BlockAddress::get(NewFunc, NewBB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false;
|
bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false;
|
||||||
|
|
||||||
// Loop over all instructions, and copy them over, DCE'ing as we go. This
|
// Loop over all instructions, and copy them over, DCE'ing as we go. This
|
||||||
|
27
test/Transforms/Inline/blockaddress.ll
Normal file
27
test/Transforms/Inline/blockaddress.ll
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
; RUN: opt -inline -S < %s | FileCheck %s
|
||||||
|
; PR10162
|
||||||
|
|
||||||
|
; Make sure the blockaddress is mapped correctly when doit is inlined
|
||||||
|
; CHECK: store i8* blockaddress(@f, %here.i), i8** @ptr1, align 8
|
||||||
|
|
||||||
|
@i = global i32 1, align 4
|
||||||
|
@ptr1 = common global i8* null, align 8
|
||||||
|
|
||||||
|
define void @doit(i8** nocapture %pptr, i32 %cond) nounwind uwtable {
|
||||||
|
entry:
|
||||||
|
%tobool = icmp eq i32 %cond, 0
|
||||||
|
br i1 %tobool, label %if.end, label %here
|
||||||
|
|
||||||
|
here:
|
||||||
|
store i8* blockaddress(@doit, %here), i8** %pptr, align 8
|
||||||
|
br label %if.end
|
||||||
|
|
||||||
|
if.end:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @f(i32 %cond) nounwind uwtable {
|
||||||
|
entry:
|
||||||
|
call void @doit(i8** @ptr1, i32 %cond)
|
||||||
|
ret void
|
||||||
|
}
|
Reference in New Issue
Block a user