1; RUN: opt -S -objc-arc < %s | FileCheck %s 2; rdar://10210274 3 4%0 = type opaque 5 6declare i8* @objc_retain(i8*) 7 8declare void @objc_release(i8*) 9 10declare i8* @objc_autoreleaseReturnValue(i8*) 11 12; Don't delete the autorelease. 13 14; CHECK: 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: } 21define %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: define %0* @test1( 39; CHECK-NOT: @objc 40; CHECK: } 41define %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 57declare %0* @foo() 58 59!0 = metadata !{} 60