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