From: Pete Cooper Date: Wed, 2 Jan 2019 21:00:02 +0000 (+0000) Subject: Fix assert in ObjCARC optimizer when deleting retainBlock of null or undef. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6006c2a684f6726972078de431823164e9fc0daf;p=llvm Fix assert in ObjCARC optimizer when deleting retainBlock of null or undef. The caller to EraseInstruction had this conditional: // ARC calls with null are no-ops. Delete them. if (IsNullOrUndef(Arg)) but the assert inside EraseInstruction only allowed ConstantPointerNull and not undef or bitcasts. This adds support for both of these cases. rdar://problem/47003805 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350261 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/ObjCARC/ObjCARC.h b/lib/Transforms/ObjCARC/ObjCARC.h index 1dbe72c7569..751c8f30e81 100644 --- a/lib/Transforms/ObjCARC/ObjCARC.h +++ b/lib/Transforms/ObjCARC/ObjCARC.h @@ -58,7 +58,7 @@ static inline void EraseInstruction(Instruction *CI) { // Replace the return value with the argument. assert((IsForwarding(GetBasicARCInstKind(CI)) || (IsNoopOnNull(GetBasicARCInstKind(CI)) && - isa(OldArg))) && + IsNullOrUndef(OldArg->stripPointerCasts()))) && "Can't delete non-forwarding instruction with users!"); CI->replaceAllUsesWith(OldArg); } diff --git a/test/Transforms/ObjCARC/rv.ll b/test/Transforms/ObjCARC/rv.ll index 604ef59f119..ca3d7e2f848 100644 --- a/test/Transforms/ObjCARC/rv.ll +++ b/test/Transforms/ObjCARC/rv.ll @@ -61,6 +61,11 @@ define void @test2() { call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* null) call i8* @llvm.objc.autoreleaseReturnValue(i8* null) ; call i8* @llvm.objc.retainAutoreleaseReturnValue(i8* null) ; TODO + %bitcast = bitcast i32* null to i8* + %rb = call i8* @llvm.objc.retainBlock(i8* %bitcast) + call void @use_pointer(i8* %rb) + %rb2 = call i8* @llvm.objc.retainBlock(i8* undef) + call void @use_pointer(i8* %rb2) ret void }