mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-15 23:31:37 +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:
parent
ca7eb3e171
commit
4090e1ce91
@ -113,8 +113,23 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
|
||||
|
||||
// Create a new basic block and copy instructions into it!
|
||||
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()))
|
||||
Returns.push_back(RI);
|
||||
}
|
||||
@ -224,6 +239,22 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
|
||||
BBEntry = NewBB = BasicBlock::Create(BB->getContext());
|
||||
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;
|
||||
|
||||
// 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user