mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-02 22:32:08 +00:00
When eliminating unnecessary retain+autorelease on return values,
handle the case where the retain is in a different basic block. rdar://10210274. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140815 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
597fece886
commit
27e0666725
@ -3198,7 +3198,8 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
|
||||
|
||||
// Check that there is nothing that can affect the reference
|
||||
// count between the retain and the call.
|
||||
FindDependencies(CanChangeRetainCount, Arg, BB, Retain,
|
||||
// Note that Retain need not be in BB.
|
||||
FindDependencies(CanChangeRetainCount, Arg, Retain->getParent(), Retain,
|
||||
DependingInstructions, Visited, PA);
|
||||
if (DependingInstructions.size() != 1)
|
||||
goto next_block;
|
||||
|
59
test/Transforms/ObjCARC/empty-block.ll
Normal file
59
test/Transforms/ObjCARC/empty-block.ll
Normal file
@ -0,0 +1,59 @@
|
||||
; RUN: opt -S -objc-arc < %s | FileCheck %s
|
||||
; rdar://10210274
|
||||
|
||||
%0 = type opaque
|
||||
|
||||
declare i8* @objc_retain(i8*)
|
||||
|
||||
declare void @objc_release(i8*)
|
||||
|
||||
declare i8* @objc_autoreleaseReturnValue(i8*)
|
||||
|
||||
; Don't delete the autorelease.
|
||||
|
||||
; CHECK: define %0* @test0(
|
||||
; CHECK: @objc_retain
|
||||
; CHECK: .lr.ph:
|
||||
; CHECK-NOT: @objc_r
|
||||
; CHECK: @objc_autoreleaseReturnValue
|
||||
; CHECK-NOT: @objc_
|
||||
; CHECK: }
|
||||
define %0* @test0(%0* %buffer) nounwind {
|
||||
%1 = bitcast %0* %buffer to i8*
|
||||
%2 = tail call i8* @objc_retain(i8* %1) nounwind
|
||||
br i1 undef, label %.lr.ph, label %._crit_edge
|
||||
|
||||
.lr.ph: ; preds = %.lr.ph, %0
|
||||
br i1 false, label %.lr.ph, label %._crit_edge
|
||||
|
||||
._crit_edge: ; preds = %.lr.ph, %0
|
||||
%3 = tail call i8* @objc_retain(i8* %1) nounwind
|
||||
tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
|
||||
%4 = tail call i8* @objc_autoreleaseReturnValue(i8* %1) nounwind
|
||||
ret %0* %buffer
|
||||
}
|
||||
|
||||
; Do delete the autorelease, even with the retain in a different block.
|
||||
|
||||
; CHECK: define %0* @test1(
|
||||
; CHECK-NOT: @objc
|
||||
; CHECK: }
|
||||
define %0* @test1() nounwind {
|
||||
%buffer = call %0* @foo()
|
||||
%1 = bitcast %0* %buffer to i8*
|
||||
%2 = tail call i8* @objc_retain(i8* %1) nounwind
|
||||
br i1 undef, label %.lr.ph, label %._crit_edge
|
||||
|
||||
.lr.ph: ; preds = %.lr.ph, %0
|
||||
br i1 false, label %.lr.ph, label %._crit_edge
|
||||
|
||||
._crit_edge: ; preds = %.lr.ph, %0
|
||||
%3 = tail call i8* @objc_retain(i8* %1) nounwind
|
||||
tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
|
||||
%4 = tail call i8* @objc_autoreleaseReturnValue(i8* %1) nounwind
|
||||
ret %0* %buffer
|
||||
}
|
||||
|
||||
declare %0* @foo()
|
||||
|
||||
!0 = metadata !{}
|
Loading…
x
Reference in New Issue
Block a user