1 ; RUN: opt -S -objc-arc < %s | FileCheck %s 2 ; rdar://10210274 3 4 %0 = type opaque 5 6 declare i8* @objc_retain(i8*) 7 8 declare void @objc_release(i8*) 9 10 declare i8* @objc_autoreleaseReturnValue(i8*) 11 12 ; Don't delete the autorelease. 13 14 ; CHECK-LABEL: define %0* @test0( 15 ; CHECK: @objc_retain 16 ; CHECK: .lr.ph: 17 ; CHECK-NOT: @objc_r 18 ; CHECK: @objc_autoreleaseReturnValue 19 ; CHECK-NOT: @objc_ 20 ; CHECK: } 21 define %0* @test0(%0* %buffer) nounwind { 22 %1 = bitcast %0* %buffer to i8* 23 %2 = tail call i8* @objc_retain(i8* %1) nounwind 24 br i1 undef, label %.lr.ph, label %._crit_edge 25 26 .lr.ph: ; preds = %.lr.ph, %0 27 br i1 false, label %.lr.ph, label %._crit_edge 28 29 ._crit_edge: ; preds = %.lr.ph, %0 30 %3 = tail call i8* @objc_retain(i8* %1) nounwind 31 tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0 32 %4 = tail call i8* @objc_autoreleaseReturnValue(i8* %1) nounwind 33 ret %0* %buffer 34 } 35 36 ; Do delete the autorelease, even with the retain in a different block. 37 38 ; CHECK-LABEL: define %0* @test1( 39 ; CHECK-NOT: @objc 40 ; CHECK: } 41 define %0* @test1() nounwind { 42 %buffer = call %0* @foo() 43 %1 = bitcast %0* %buffer to i8* 44 %2 = tail call i8* @objc_retain(i8* %1) nounwind 45 br i1 undef, label %.lr.ph, label %._crit_edge 46 47 .lr.ph: ; preds = %.lr.ph, %0 48 br i1 false, label %.lr.ph, label %._crit_edge 49 50 ._crit_edge: ; preds = %.lr.ph, %0 51 %3 = tail call i8* @objc_retain(i8* %1) nounwind 52 tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0 53 %4 = tail call i8* @objc_autoreleaseReturnValue(i8* %1) nounwind 54 ret %0* %buffer 55 } 56 57 declare %0* @foo() 58 59 !0 = !{} 60