diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index a956caeffe0..5ac8c8e6c27 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -1440,8 +1440,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) { break; } - // objc_autorelease(x), objc_autoreleaseRV -> objc_release(x) if x is - // otherwise unused. + // objc_autorelease(x) -> objc_release(x) if x is otherwise unused. if (IsAutorelease(Class) && Inst->use_empty()) { CallInst *Call = cast(Inst); const Value *Arg = Call->getArgOperand(0); @@ -2861,20 +2860,6 @@ void ObjCARCOpt::OptimizeReturns(Function &F) { DependingInstructions.clear(); Visited.clear(); - // Convert the autorelease to an autoreleaseRV, since it's - // returning the value. - if (AutoreleaseClass == IC_Autorelease) { - DEBUG(dbgs() << "ObjCARCOpt::OptimizeReturns: Converting autorelease " - "=> autoreleaseRV since it's returning a value.\n" - " In: " << *Autorelease - << "\n"); - Autorelease->setCalledFunction(getAutoreleaseRVCallee(F.getParent())); - DEBUG(dbgs() << " Out: " << *Autorelease - << "\n"); - Autorelease->setTailCall(); // Always tail call autoreleaseRV. - AutoreleaseClass = IC_AutoreleaseRV; - } - // Check that there is nothing that can affect the reference // count between the retain and the call. // Note that Retain need not be in BB. diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll index bf6ccc8a7fc..828a8a70112 100644 --- a/test/Transforms/ObjCARC/basic.ll +++ b/test/Transforms/ObjCARC/basic.ll @@ -428,11 +428,13 @@ entry: ret void } -; Same as test11 but the value is returned. Do an RV optimization. +; Same as test11 but the value is returned. Do not perform an RV optimization +; since if the frontend emitted code for an __autoreleasing variable, we may +; want it to be in the autorelease pool. ; CHECK: define i8* @test11b( ; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]] -; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %0) [[NUW]] +; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]] ; CHECK: } define i8* @test11b(i8* %x) nounwind { entry: diff --git a/test/Transforms/ObjCARC/rv.ll b/test/Transforms/ObjCARC/rv.ll index a2fef967495..589c60f9f3a 100644 --- a/test/Transforms/ObjCARC/rv.ll +++ b/test/Transforms/ObjCARC/rv.ll @@ -121,7 +121,7 @@ define i8* @test7() { %p = call i8* @returner() call i8* @objc_retainAutoreleasedReturnValue(i8* %p) %t = call i8* @objc_autoreleaseReturnValue(i8* %p) - call void @use_pointer(i8* %t) + call void @use_pointer(i8* %p) ret i8* %t } @@ -133,7 +133,7 @@ define i8* @test7b() { call void @use_pointer(i8* %p) call i8* @objc_retainAutoreleasedReturnValue(i8* %p) %t = call i8* @objc_autoreleaseReturnValue(i8* %p) - ret i8* %t + ret i8* %p } ; Turn objc_retain into objc_retainAutoreleasedReturnValue if its operand @@ -156,11 +156,11 @@ define i8* @test9(i8* %p) { ret i8* %p } -; Apply the RV optimization. +; Do not apply the RV optimization. ; CHECK: define i8* @test10(i8* %p) ; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]] -; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p) [[NUW]] +; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]] ; CHECK-NEXT: ret i8* %p define i8* @test10(i8* %p) { %1 = call i8* @objc_retain(i8* %p) diff --git a/test/Transforms/ObjCARC/tail-call-invariant-enforcement.ll b/test/Transforms/ObjCARC/tail-call-invariant-enforcement.ll index 74ac97c7b30..26cd67727e6 100644 --- a/test/Transforms/ObjCARC/tail-call-invariant-enforcement.ll +++ b/test/Transforms/ObjCARC/tail-call-invariant-enforcement.ll @@ -72,13 +72,3 @@ entry: ret i8* %tmp0 } -; If we convert a called @objc_autorelease to an @objc_autoreleaseReturnValue, -; ensure that the tail call is added. -define i8* @test6(i8* %x) { -entry: - ; CHECK: %tmp0 = tail call i8* @objc_retain(i8* %x) - %tmp0 = tail call i8* @objc_retain(i8* %x) - ; CHECK: %tmp1 = tail call i8* @objc_autoreleaseReturnValue(i8* %x) - %tmp1 = call i8* @objc_autorelease(i8* %x) - ret i8* %x -}