Marking two more MCJIT PIC tests as XFAIL on i686
[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-LABEL: define void @bitcasttest(
24 entry:
25   %t1 = bitcast void (...)* %block to i8*
26 ; CHECK: 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: call void @objc_release
34   call void @objc_release(i8* %t1)
35   ret void
36 ; CHECK: }
37 }
38
39 define void @bitcasttest_a(i8* %storage, void (...)* %block)  {
40 ; CHECK-LABEL: define void @bitcasttest_a(
41 entry:
42   %t1 = bitcast void (...)* %block to i8*
43 ; CHECK-NOT: tail call i8* @objc_retain
44   %t2 = tail call i8* @objc_retain(i8* %t1)
45 ; CHECK: tail call i8* @objc_retainBlock
46   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
47   %t4 = bitcast i8* %storage to void (...)**
48   %t5 = bitcast i8* %t3 to void (...)*
49   store void (...)* %t5, void (...)** %t4, align 8
50 ; CHECK-NOT: call void @objc_release
51   call void @objc_release(i8* %t1), !clang.imprecise_release !0
52   ret void
53 ; CHECK: }
54 }
55
56 define void @geptest(void (...)** %storage_array, void (...)* %block)  {
57 ; CHECK-LABEL: define void @geptest(
58 entry:
59   %t1 = bitcast void (...)* %block to i8*
60 ; CHECK: tail call i8* @objc_retain
61   %t2 = tail call i8* @objc_retain(i8* %t1)
62 ; CHECK: tail call i8* @objc_retainBlock
63   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
64   %t4 = bitcast i8* %t3 to void (...)*
65   
66   %storage = getelementptr inbounds void (...)** %storage_array, i64 0
67   
68   store void (...)* %t4, void (...)** %storage, align 8
69 ; CHECK: call void @objc_release
70   call void @objc_release(i8* %t1)
71   ret void
72 ; CHECK: }
73 }
74
75 define void @geptest_a(void (...)** %storage_array, void (...)* %block)  {
76 ; CHECK-LABEL: define void @geptest_a(
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   
85   %storage = getelementptr inbounds void (...)** %storage_array, i64 0
86   
87   store void (...)* %t4, void (...)** %storage, align 8
88 ; CHECK-NOT: call void @objc_release
89   call void @objc_release(i8* %t1), !clang.imprecise_release !0
90   ret void
91 ; CHECK: }
92 }
93
94 define void @selecttest(void (...)** %store1, void (...)** %store2,
95                         void (...)* %block) {
96 ; CHECK-LABEL: define void @selecttest(
97 entry:
98   %t1 = bitcast void (...)* %block to i8*
99 ; CHECK: tail call i8* @objc_retain
100   %t2 = tail call i8* @objc_retain(i8* %t1)
101 ; CHECK: tail call i8* @objc_retainBlock
102   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
103   %t4 = bitcast i8* %t3 to void (...)*
104   %store = select i1 undef, void (...)** %store1, void (...)** %store2
105   store void (...)* %t4, void (...)** %store, align 8
106 ; CHECK: call void @objc_release
107   call void @objc_release(i8* %t1)
108   ret void
109 ; CHECK: }
110 }
111
112 define void @selecttest_a(void (...)** %store1, void (...)** %store2,
113                           void (...)* %block) {
114 ; CHECK-LABEL: define void @selecttest_a(
115 entry:
116   %t1 = bitcast void (...)* %block to i8*
117 ; CHECK-NOT: tail call i8* @objc_retain
118   %t2 = tail call i8* @objc_retain(i8* %t1)
119 ; CHECK: tail call i8* @objc_retainBlock
120   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
121   %t4 = bitcast i8* %t3 to void (...)*
122   %store = select i1 undef, void (...)** %store1, void (...)** %store2
123   store void (...)* %t4, void (...)** %store, align 8
124 ; CHECK-NOT: call void @objc_release
125   call void @objc_release(i8* %t1), !clang.imprecise_release !0
126   ret void
127 ; CHECK: }
128 }
129
130 define void @phinodetest(void (...)** %storage1,
131                          void (...)** %storage2,
132                          void (...)* %block) {
133 ; CHECK-LABEL: define void @phinodetest(
134 entry:
135   %t1 = bitcast void (...)* %block to i8*
136 ; CHECK: tail call i8* @objc_retain
137   %t2 = tail call i8* @objc_retain(i8* %t1)
138 ; CHECK: tail call i8* @objc_retainBlock
139   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
140   %t4 = bitcast i8* %t3 to void (...)*
141   br i1 undef, label %store1_set, label %store2_set
142 ; CHECK: store1_set:
143
144 store1_set:
145   br label %end
146
147 store2_set:
148   br label %end
149
150 end:
151 ; CHECK: end:
152   %storage = phi void (...)** [ %storage1, %store1_set ], [ %storage2, %store2_set]
153   store void (...)* %t4, void (...)** %storage, align 8
154 ; CHECK: call void @objc_release
155   call void @objc_release(i8* %t1)
156   ret void
157 ; CHECK: }
158 }
159
160 define void @phinodetest_a(void (...)** %storage1,
161                            void (...)** %storage2,
162                            void (...)* %block) {
163 ; CHECK-LABEL: define void @phinodetest_a(
164 entry:
165   %t1 = bitcast void (...)* %block to i8*
166 ; CHECK-NOT: tail call i8* @objc_retain
167   %t2 = tail call i8* @objc_retain(i8* %t1)
168 ; CHECK: tail call i8* @objc_retainBlock
169   %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0
170   %t4 = bitcast i8* %t3 to void (...)*
171   br i1 undef, label %store1_set, label %store2_set
172
173 store1_set:
174   br label %end
175
176 store2_set:
177   br label %end
178
179 end:
180   %storage = phi void (...)** [ %storage1, %store1_set ], [ %storage2, %store2_set]
181   store void (...)* %t4, void (...)** %storage, align 8
182 ; CHECK-NOT: call void @objc_release
183   call void @objc_release(i8* %t1), !clang.imprecise_release !0
184   ret void
185 }
186
187
188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
189 ; This test makes sure that we do not hang clang when visiting a use ;
190 ; cycle caused by phi nodes during objc-arc analysis. *NOTE* This    ;
191 ; test case looks a little convoluted since it was produced by       ;
192 ; bugpoint.                                                          ;
193 ;                                                                    ;
194 ; bugzilla://14551                                                   ;
195 ; rdar://12851911                                                    ;
196 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
197
198 define void @phinode_use_cycle(i8* %block) uwtable optsize ssp {
199 ; CHECK: define void @phinode_use_cycle(i8* %block)
200 entry:
201   br label %for.body
202
203 for.body:                                         ; preds = %if.then, %for.body, %entry
204   %block.05 = phi void (...)* [ null, %entry ], [ %1, %if.then ], [ %block.05, %for.body ]
205   br i1 undef, label %for.body, label %if.then
206
207 if.then:                                          ; preds = %for.body
208   %0 = call i8* @objc_retainBlock(i8* %block), !clang.arc.copy_on_escape !0
209   %1 = bitcast i8* %0 to void (...)*
210   %2 = bitcast void (...)* %block.05 to i8*
211   call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0
212   br label %for.body
213 }
214
215 !0 = metadata !{}