Home | History | Annotate | Download | only in ObjCARC
      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