The ARC language-specific optimizer. Credit to Dan Gohman.
[oota-llvm.git] / test / Transforms / ObjCARC / cfg-hazards.ll
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 !{}