2c1ddce32836bc24de349e50dca96194fa0885e8
[oota-llvm.git] / test / Transforms / ObjCARC / retain-block-escape-analysis.ll
1 ; RUN: opt -S -objc-arc < %s | FileCheck %s
2
3 declare i8* @objc_retain(i8*) nonlazybind
4 declare void @objc_release(i8*) nonlazybind
5 declare i8* @objc_retainBlock(i8*)
6
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ; Use by an instruction which copies the value is an escape if the             ;
9 ; result is an escape. The current instructions with this property are:        ;
10 ;                                                                              ;
11 ; 1. BitCast.                                                                  ;
12 ; 2. GEP.                                                                      ;
13 ; 3. PhiNode.                                                                  ;
14 ; 4. SelectInst.                                                               ;
15 ;                                                                              ;
16 ; Make sure that such instructions do not confuse the optimizer into removing  ;
17 ; an objc_retainBlock that is needed.                                          ;
18 ;                                                                              ;
19 ; rdar://13273675. (With extra test cases to handle bitcast, phi, and select.  ;
20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21
22 define void @bitcasttest(i8* %storage, void (...)* %block)  {
23 ; CHECK: define void @bitcasttest
24 entry:
25   %t1 = bitcast void (...)* %block to i8*
26 ; CHECK-NOT: tail call i8* @objc_retain
27   %t2 = tail call i8* @objc_retain(i8* %t1)
28 ; CHECK: tail call i8* @objc_retainBlock
29   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
30   %t4 = bitcast i8* %storage to void (...)**
31   %t5 = bitcast i8* %t3 to void (...)*
32   store void (...)* %t5, void (...)** %t4, align 8
33 ; CHECK-NOT: call void @objc_release
34   call void @objc_release(i8* %t1)
35   ret void
36 }
37
38 define void @geptest(void (...)** %storage_array, void (...)* %block)  {
39 ; CHECK: define void @geptest
40 entry:
41   %t1 = bitcast void (...)* %block to i8*
42 ; CHECK-NOT: tail call i8* @objc_retain
43   %t2 = tail call i8* @objc_retain(i8* %t1)
44 ; CHECK: tail call i8* @objc_retainBlock
45   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
46   %t4 = bitcast i8* %t3 to void (...)*
47   
48   %storage = getelementptr inbounds void (...)** %storage_array, i64 0
49   
50   store void (...)* %t4, void (...)** %storage, align 8
51 ; CHECK-NOT: call void @objc_release
52   call void @objc_release(i8* %t1)
53   ret void
54 }
55
56 define void @selecttest(void (...)** %store1, void (...)** %store2,
57                         void (...)* %block) {
58 ; CHECK: define void @selecttest
59 entry:
60   %t1 = bitcast void (...)* %block to i8*
61 ; CHECK-NOT: tail call i8* @objc_retain
62   %t2 = tail call i8* @objc_retain(i8* %t1)
63 ; CHECK: tail call i8* @objc_retainBlock
64   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
65   %t4 = bitcast i8* %t3 to void (...)*
66   %store = select i1 undef, void (...)** %store1, void (...)** %store2
67   store void (...)* %t4, void (...)** %store, align 8
68 ; CHECK-NOT: call void @objc_release
69   call void @objc_release(i8* %t1)
70   ret void
71 }
72
73 define void @phinodetest(void (...)** %storage1,
74                          void (...)** %storage2,
75                          void (...)* %block) {
76 ; CHECK: define void @phinodetest
77 entry:
78   %t1 = bitcast void (...)* %block to i8*
79 ; CHECK-NOT: tail call i8* @objc_retain
80   %t2 = tail call i8* @objc_retain(i8* %t1)
81 ; CHECK: tail call i8* @objc_retainBlock
82   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
83   %t4 = bitcast i8* %t3 to void (...)*
84   br i1 undef, label %store1_set, label %store2_set
85
86 store1_set:
87   br label %end
88
89 store2_set:
90   br label %end
91
92 end:
93   %storage = phi void (...)** [ %storage1, %store1_set ], [ %storage2, %store2_set]
94   store void (...)* %t4, void (...)** %storage, align 8
95 ; CHECK-NOT: call void @objc_release
96   call void @objc_release(i8* %t1)
97   ret void
98 }
99
100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
101 ; This test makes sure that we do not hang clang when visiting a use ;
102 ; cycle caused by phi nodes during objc-arc analysis. *NOTE* This    ;
103 ; test case looks a little convoluted since it was produced by       ;
104 ; bugpoint.                                                          ;
105 ;                                                                    ;
106 ; bugzilla://14551                                                   ;
107 ; rdar://12851911                                                    ;
108 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
109
110 define void @phinode_use_cycle(i8* %block) uwtable optsize ssp {
111 ; CHECK: define void @phinode_use_cycle(i8* %block)
112 entry:
113   br label %for.body
114
115 for.body:                                         ; preds = %if.then, %for.body, %entry
116   %block.05 = phi void (...)* [ null, %entry ], [ %1, %if.then ], [ %block.05, %for.body ]
117   br i1 undef, label %for.body, label %if.then
118
119 if.then:                                          ; preds = %for.body
120   %0 = call i8* @objc_retainBlock(i8* %block), !clang.arc.copy_on_escape !0
121   %1 = bitcast i8* %0 to void (...)*
122   %2 = bitcast void (...)* %block.05 to i8*
123   call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0
124   br label %for.body
125 }
126
127 !0 = metadata !{}