From cfa4e9bdf3b2474594bcf8e447f2ead68f458ab9 Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 7 Sep 2012 23:30:50 +0000 Subject: 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 llvm-svn: 163431 --- clang/lib/CodeGen/CGCall.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'clang/lib/CodeGen') diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 7d2b9d355ec..95bee4bd5a4 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/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(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(prev)) { + prev = prev->getPrevNode(); + assert(prev); + } + assert(isa(prev)); + assert(cast(prev)->getCalledValue() == + CGF.CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker); + insnsToKill.push_back(prev); + } } else { return 0; } -- cgit v1.2.3