diff options
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; } |