diff options
author | Michael Gottesman <mgottesman@apple.com> | 2013-01-12 01:25:15 +0000 |
---|---|---|
committer | Michael Gottesman <mgottesman@apple.com> | 2013-01-12 01:25:15 +0000 |
commit | e8c161a92451ad38919525ea73ae3c6936c24bdf (patch) | |
tree | 1a695f9d0bcb9c782436b4beb22561336436da3d /test/Transforms/ObjCARC/rv.ll | |
parent | ec3199f675b17b12fd779df557c6bff25aa4e862 (diff) | |
download | llvm-e8c161a92451ad38919525ea73ae3c6936c24bdf.tar.gz llvm-e8c161a92451ad38919525ea73ae3c6936c24bdf.tar.bz2 llvm-e8c161a92451ad38919525ea73ae3c6936c24bdf.tar.xz |
Fixed a bug where we were tail calling objc_autorelease causing an object to not be placed into an autorelease pool.
The reason that this occurs is that tail calling objc_autorelease eventually
tail calls -[NSObject autorelease] which supports fast autorelease. This can
cause us to violate the semantic gaurantees of __autoreleasing variables that
assignment to an __autoreleasing variables always yields an object that is
placed into the innermost autorelease pool.
The fix included in this patch works by:
1. In the peephole optimization function OptimizeIndividualFunctions, always
remove tail call from objc_autorelease.
2. Whenever we convert to/from an objc_autorelease, set/unset the tail call
keyword as appropriate.
*NOTE* I also handled the case where objc_autorelease is converted in
OptimizeReturns to an autoreleaseRV which still violates the ARC semantics. I
will be removing that in a later patch and I wanted to make sure that the tree
is in a consistent state vis-a-vis ARC always.
Additionally some test cases are provided and all tests that have tail call marked
objc_autorelease keywords have been modified so that tail call has been removed.
*NOTE* One test fails due to a separate bug that I am going to commit soon. Thus
I marked the check line TMP: instead of CHECK: so make check does not fail.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172287 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/ObjCARC/rv.ll')
-rw-r--r-- | test/Transforms/ObjCARC/rv.ll | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/test/Transforms/ObjCARC/rv.ll b/test/Transforms/ObjCARC/rv.ll index 9353a19f71..638b89ccc7 100644 --- a/test/Transforms/ObjCARC/rv.ll +++ b/test/Transforms/ObjCARC/rv.ll @@ -150,7 +150,7 @@ define void @test8() { ; Don't apply the RV optimization to autorelease if there's no retain. ; CHECK: define i8* @test9(i8* %p) -; CHECK: tail call i8* @objc_autorelease(i8* %p) +; CHECK: call i8* @objc_autorelease(i8* %p) define i8* @test9(i8* %p) { call i8* @objc_autorelease(i8* %p) ret i8* %p @@ -174,7 +174,7 @@ define i8* @test10(i8* %p) { ; CHECK: define i8* @test11(i8* %p) ; CHECK: tail call i8* @objc_retain(i8* %p) ; CHECK-NEXT: call void @use_pointer(i8* %p) -; CHECK: tail call i8* @objc_autorelease(i8* %p) +; CHECK: call i8* @objc_autorelease(i8* %p) ; CHECK-NEXT: ret i8* %p define i8* @test11(i8* %p) { %1 = call i8* @objc_retain(i8* %p) @@ -201,7 +201,7 @@ define i8* @test12(i8* %p) { ; CHECK: define i8* @test13( ; CHECK: tail call i8* @objc_retainAutoreleasedReturnValue(i8* %p) -; CHECK: tail call i8* @objc_autorelease(i8* %p) +; CHECK: call i8* @objc_autorelease(i8* %p) ; CHECK: ret i8* %p define i8* @test13() { %p = call i8* @returner() @@ -323,7 +323,7 @@ define i8* @test22(i8* %p) { ; Convert autoreleaseRV to autorelease. ; CHECK: define void @test23( -; CHECK: tail call i8* @objc_autorelease(i8* %p) nounwind +; CHECK: call i8* @objc_autorelease(i8* %p) nounwind define void @test23(i8* %p) { store i8 0, i8* %p call i8* @objc_autoreleaseReturnValue(i8* %p) |