mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[ObjC][ARC] Don't remove autoreleaseRV/retainRV pairs if the call isn't
a tail call Previosly ARC optimizer removed the autoreleaseRV/retainRV pair in the following code, which caused the object returned by @something to be placed in the autorelease pool because the call to @something isn't a tail call: ``` %call = call i8* @something(...) %2 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) %3 = call i8* @objc_autoreleaseReturnValue(i8* %2) ret i8* %3 ``` Fix the bug by checking whether @something is a tail call. rdar://problem/59275894
This commit is contained in:
parent
f3f0aaefef
commit
00ab8cc01c
@ -2296,7 +2296,7 @@ FindPredecessorAutoreleaseWithSafePath(const Value *Arg, BasicBlock *BB,
|
||||
|
||||
/// Look for this pattern:
|
||||
/// \code
|
||||
/// %call = call i8* @something(...)
|
||||
/// %call = tail call i8* @something(...)
|
||||
/// %2 = call i8* @objc_retain(i8* %call)
|
||||
/// %3 = call i8* @objc_autorelease(i8* %2)
|
||||
/// ret i8* %3
|
||||
@ -2344,6 +2344,13 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
|
||||
bool HasSafePathToCall = HasSafePathToPredecessorCall(Arg, Retain,
|
||||
DependingInstructions,
|
||||
Visited, PA);
|
||||
|
||||
// Don't remove retainRV/autoreleaseRV pairs if the call isn't a tail call.
|
||||
if (GetBasicARCInstKind(Retain) == ARCInstKind::RetainRV &&
|
||||
GetBasicARCInstKind(Autorelease) == ARCInstKind::AutoreleaseRV &&
|
||||
!cast<CallInst>(*DependingInstructions.begin())->isTailCall())
|
||||
continue;
|
||||
|
||||
DependingInstructions.clear();
|
||||
Visited.clear();
|
||||
|
||||
|
@ -77,7 +77,7 @@ define void @test2() {
|
||||
; CHECK-NEXT: ret i8* %call
|
||||
define i8* @test3() {
|
||||
entry:
|
||||
%call = call i8* @returner()
|
||||
%call = tail call i8* @returner()
|
||||
%0 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %call) nounwind
|
||||
%1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %0) nounwind
|
||||
ret i8* %1
|
||||
@ -387,6 +387,20 @@ bb3:
|
||||
ret i32* %retval
|
||||
}
|
||||
|
||||
; Don't eliminate the retainRV/autoreleaseRV pair if the call isn't a tail call.
|
||||
|
||||
; CHECK-LABEL: define i8* @test28(
|
||||
; CHECK: call i8* @returner()
|
||||
; CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue(
|
||||
; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(
|
||||
define i8* @test28() {
|
||||
entry:
|
||||
%call = call i8* @returner()
|
||||
%0 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %call) nounwind
|
||||
%1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %0) nounwind
|
||||
ret i8* %1
|
||||
}
|
||||
|
||||
!0 = !{}
|
||||
|
||||
; CHECK: attributes [[NUW]] = { nounwind }
|
||||
|
Loading…
Reference in New Issue
Block a user