1 ; RUN: opt -S -passes=objc-arc < %s | FileCheck %s
6 declare ptr @llvm.objc.retain(ptr)
8 declare void @llvm.objc.release(ptr)
10 declare ptr @llvm.objc.autoreleaseReturnValue(ptr)
12 ; Don't delete the autorelease.
14 ; CHECK-LABEL: define ptr @test0(
15 ; CHECK: @llvm.objc.retain
17 ; CHECK-NOT: @llvm.objc.r
18 ; CHECK: @llvm.objc.autoreleaseReturnValue
19 ; CHECK-NOT: @llvm.objc.
21 define ptr @test0(ptr %buffer) nounwind {
22 %1 = tail call ptr @llvm.objc.retain(ptr %buffer) nounwind
23 br i1 undef, label %.lr.ph, label %._crit_edge
25 .lr.ph: ; preds = %.lr.ph, %0
26 br i1 false, label %.lr.ph, label %._crit_edge
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
35 ; Do delete the autorelease, even with the retain in a different block.
37 ; CHECK-LABEL: define ptr @test1(
40 define ptr @test1() nounwind {
41 %buffer = call ptr @foo()
42 %1 = tail call ptr @llvm.objc.retain(ptr %buffer) nounwind
43 br i1 undef, label %.lr.ph, label %._crit_edge
45 .lr.ph: ; preds = %.lr.ph, %0
46 br i1 false, label %.lr.ph, label %._crit_edge
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