1 ; RUN: opt -S -objc-arc < %s | FileCheck %s 2 ; rdar://9503416 3 4 ; Detect loop boundaries and don't move retains and releases 5 ; across them. 6 7 declare void @use_pointer(i8*) 8 declare i8* @objc_retain(i8*) 9 declare void @objc_release(i8*) 10 11 ; CHECK: define void @test0( 12 ; CHECK: call i8* @objc_retain( 13 ; CHECK: for.body: 14 ; CHECK-NOT: @objc 15 ; CHECK: for.end: 16 ; CHECK: call void @objc_release( 17 ; CHECK: } 18 define void @test0(i8* %digits) { 19 entry: 20 %tmp1 = call i8* @objc_retain(i8* %digits) nounwind 21 call void @use_pointer(i8* %tmp1) 22 br label %for.body 23 24 for.body: ; preds = %for.body, %entry 25 %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ] 26 call void @use_pointer(i8* %tmp1) 27 %inc = add i64 %upcDigitIndex.01, 1 28 %cmp = icmp ult i64 %inc, 12 29 br i1 %cmp, label %for.body, label %for.end 30 31 for.end: ; preds = %for.body 32 call void @objc_release(i8* %tmp1) nounwind, !clang.imprecise_release !0 33 ret void 34 } 35 36 ; CHECK: define void @test1( 37 ; CHECK: call i8* @objc_retain( 38 ; CHECK: for.body: 39 ; CHECK-NOT: @objc 40 ; CHECK: for.end: 41 ; CHECK: void @objc_release( 42 ; CHECK: } 43 define void @test1(i8* %digits) { 44 entry: 45 %tmp1 = call i8* @objc_retain(i8* %digits) nounwind 46 br label %for.body 47 48 for.body: ; preds = %for.body, %entry 49 %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ] 50 call void @use_pointer(i8* %tmp1) 51 call void @use_pointer(i8* %tmp1) 52 %inc = add i64 %upcDigitIndex.01, 1 53 %cmp = icmp ult i64 %inc, 12 54 br i1 %cmp, label %for.body, label %for.end 55 56 for.end: ; preds = %for.body 57 call void @objc_release(i8* %tmp1) nounwind, !clang.imprecise_release !0 58 ret void 59 } 60 61 ; CHECK: define void @test2( 62 ; CHECK: call i8* @objc_retain( 63 ; CHECK: for.body: 64 ; CHECK-NOT: @objc 65 ; CHECK: for.end: 66 ; CHECK: void @objc_release( 67 ; CHECK: } 68 define void @test2(i8* %digits) { 69 entry: 70 %tmp1 = call i8* @objc_retain(i8* %digits) nounwind 71 br label %for.body 72 73 for.body: ; preds = %for.body, %entry 74 %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ] 75 call void @use_pointer(i8* %tmp1) 76 %inc = add i64 %upcDigitIndex.01, 1 77 %cmp = icmp ult i64 %inc, 12 78 br i1 %cmp, label %for.body, label %for.end 79 80 for.end: ; preds = %for.body 81 call void @use_pointer(i8* %tmp1) 82 call void @objc_release(i8* %tmp1) nounwind, !clang.imprecise_release !0 83 ret void 84 } 85 86 !0 = metadata !{} 87