diff options
author | John McCall <rjmccall@apple.com> | 2012-09-07 23:30:50 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-09-07 23:30:50 +0000 |
commit | f9fdcc0531ca53651c1d7d0877290e232cb5468d (patch) | |
tree | 5703a9d7554e719aa3b44ea6003a0345e5d498e4 /lib/CodeGen/CGCall.cpp | |
parent | ec5fda4dedbc249b61be032f710e8c9d6396fee8 (diff) |
In ARC, if we're emitting assembly markers for calls to
objc_retainAutoreleasedReturnValue, we need to also be killing
them during return peepholing. Make sure we recognize an
intervening bitcast, but more importantly, assert if we can't
find the asm marker at all. rdar://problem/12133032
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163431 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 7d2b9d355e..95bee4bd5a 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1363,12 +1363,23 @@ static llvm::Value *tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF, .objc_retainAutoreleasedReturnValue) { doRetainAutorelease = false; - // Look for an inline asm immediately preceding the call and kill it, too. - llvm::Instruction *prev = call->getPrevNode(); - if (llvm::CallInst *asmCall = dyn_cast_or_null<llvm::CallInst>(prev)) - if (asmCall->getCalledValue() - == CGF.CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker) - insnsToKill.push_back(prev); + // If we emitted an assembly marker for this call (and the + // ARCEntrypoints field should have been set if so), go looking + // for that call. If we can't find it, we can't do this + // optimization. But it should always be the immediately previous + // instruction, unless we needed bitcasts around the call. + if (CGF.CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker) { + llvm::Instruction *prev = call->getPrevNode(); + assert(prev); + if (isa<llvm::BitCastInst>(prev)) { + prev = prev->getPrevNode(); + assert(prev); + } + assert(isa<llvm::CallInst>(prev)); + assert(cast<llvm::CallInst>(prev)->getCalledValue() == + CGF.CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker); + insnsToKill.push_back(prev); + } } else { return 0; } |