]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Transforms/ObjCARC/nested.ll
Vendor import of llvm release_30 branch r142614:
[FreeBSD/FreeBSD.git] / test / Transforms / ObjCARC / nested.ll
1 ; RUN: opt -objc-arc -S < %s | FileCheck %s
2
3 %struct.__objcFastEnumerationState = type { i64, i8**, i64*, [5 x i64] }
4
5 @"\01L_OBJC_METH_VAR_NAME_" = internal global [43 x i8] c"countByEnumeratingWithState:objects:count:\00", section "__TEXT,__objc_methname,cstring_literals", align 1
6 @"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([43 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
7 @g = common global i8* null, align 8
8 @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
9
10 declare void @callee()
11 declare i8* @returner()
12 declare i8* @objc_retainAutoreleasedReturnValue(i8*)
13 declare i8* @objc_retain(i8*)
14 declare void @objc_enumerationMutation(i8*)
15 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
16 declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
17 declare void @use(i8*)
18 declare void @objc_release(i8*)
19
20 !0 = metadata !{}
21
22 ; Delete a nested retain+release pair.
23
24 ; CHECK: define void @test0(
25 ; CHECK: call i8* @objc_retain
26 ; CHECK-NOT: @objc_retain
27 ; CHECK: }
28 define void @test0(i8* %a) nounwind {
29 entry:
30   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
31   %items.ptr = alloca [16 x i8*], align 8
32   %0 = call i8* @objc_retain(i8* %a) nounwind
33   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
34   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
35   %1 = call i8* @objc_retain(i8* %0) nounwind
36   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
37   %call = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
38   %iszero = icmp eq i64 %call, 0
39   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
40
41 forcoll.loopinit:
42   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
43   %mutationsptr = load i64** %mutationsptr.ptr, align 8
44   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
45   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
46   br label %forcoll.loopbody.outer
47
48 forcoll.loopbody.outer:
49   %forcoll.count.ph = phi i64 [ %call, %forcoll.loopinit ], [ %call6, %forcoll.refetch ]
50   %tmp7 = icmp ugt i64 %forcoll.count.ph, 1
51   %umax = select i1 %tmp7, i64 %forcoll.count.ph, i64 1
52   br label %forcoll.loopbody
53
54 forcoll.loopbody:
55   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
56   %mutationsptr3 = load i64** %mutationsptr.ptr, align 8
57   %statemutations = load i64* %mutationsptr3, align 8
58   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
59   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
60
61 forcoll.mutated:
62   call void @objc_enumerationMutation(i8* %1)
63   br label %forcoll.notmutated
64
65 forcoll.notmutated:
66   %stateitems = load i8*** %stateitems.ptr, align 8
67   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
68   %3 = load i8** %currentitem.ptr, align 8
69   call void @use(i8* %3)
70   %4 = add i64 %forcoll.index, 1
71   %exitcond = icmp eq i64 %4, %umax
72   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
73
74 forcoll.refetch:
75   %tmp5 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
76   %call6 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp5, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
77   %5 = icmp eq i64 %call6, 0
78   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
79
80 forcoll.empty:
81   call void @objc_release(i8* %1) nounwind
82   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
83   ret void
84 }
85
86 ; Delete a nested retain+release pair.
87
88 ; CHECK: define void @test2(
89 ; CHECK: call i8* @objc_retain
90 ; CHECK-NOT: @objc_retain
91 ; CHECK: }
92 define void @test2() nounwind {
93 entry:
94   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
95   %items.ptr = alloca [16 x i8*], align 8
96   %call = call i8* @returner()
97   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
98   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
99   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
100   %1 = call i8* @objc_retain(i8* %0) nounwind
101   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
102   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
103   %iszero = icmp eq i64 %call3, 0
104   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
105
106 forcoll.loopinit:
107   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
108   %mutationsptr = load i64** %mutationsptr.ptr, align 8
109   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
110   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
111   br label %forcoll.loopbody.outer
112
113 forcoll.loopbody.outer:
114   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
115   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
116   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
117   br label %forcoll.loopbody
118
119 forcoll.loopbody:
120   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
121   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
122   %statemutations = load i64* %mutationsptr4, align 8
123   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
124   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
125
126 forcoll.mutated:
127   call void @objc_enumerationMutation(i8* %1)
128   br label %forcoll.notmutated
129
130 forcoll.notmutated:
131   %stateitems = load i8*** %stateitems.ptr, align 8
132   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
133   %3 = load i8** %currentitem.ptr, align 8
134   call void @use(i8* %3)
135   %4 = add i64 %forcoll.index, 1
136   %exitcond = icmp eq i64 %4, %umax
137   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
138
139 forcoll.refetch:
140   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
141   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
142   %5 = icmp eq i64 %call7, 0
143   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
144
145 forcoll.empty:
146   call void @objc_release(i8* %1) nounwind
147   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
148   ret void
149 }
150
151 ; Delete a nested retain+release pair.
152
153 ; CHECK: define void @test4(
154 ; CHECK: call i8* @objc_retain
155 ; CHECK-NOT: @objc_retain
156 ; CHECK: }
157 define void @test4() nounwind {
158 entry:
159   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
160   %items.ptr = alloca [16 x i8*], align 8
161   %tmp = load i8** @g, align 8
162   %0 = call i8* @objc_retain(i8* %tmp) nounwind
163   %tmp2 = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
164   call void @llvm.memset.p0i8.i64(i8* %tmp2, i8 0, i64 64, i32 8, i1 false)
165   %1 = call i8* @objc_retain(i8* %0) nounwind
166   %tmp4 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
167   %call = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp4, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
168   %iszero = icmp eq i64 %call, 0
169   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
170
171 forcoll.loopinit:
172   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
173   %mutationsptr = load i64** %mutationsptr.ptr, align 8
174   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
175   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
176   br label %forcoll.loopbody.outer
177
178 forcoll.loopbody.outer:
179   %forcoll.count.ph = phi i64 [ %call, %forcoll.loopinit ], [ %call8, %forcoll.refetch ]
180   %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
181   %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
182   br label %forcoll.loopbody
183
184 forcoll.loopbody:
185   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
186   %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
187   %statemutations = load i64* %mutationsptr5, align 8
188   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
189   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
190
191 forcoll.mutated:
192   call void @objc_enumerationMutation(i8* %1)
193   br label %forcoll.notmutated
194
195 forcoll.notmutated:
196   %stateitems = load i8*** %stateitems.ptr, align 8
197   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
198   %3 = load i8** %currentitem.ptr, align 8
199   call void @use(i8* %3)
200   %4 = add i64 %forcoll.index, 1
201   %exitcond = icmp eq i64 %4, %umax
202   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
203
204 forcoll.refetch:
205   %tmp7 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
206   %call8 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp7, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
207   %5 = icmp eq i64 %call8, 0
208   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
209
210 forcoll.empty:
211   call void @objc_release(i8* %1) nounwind
212   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
213   ret void
214 }
215
216 ; Delete a nested retain+release pair.
217
218 ; CHECK: define void @test5(
219 ; CHECK: call i8* @objc_retain
220 ; CHECK-NOT: @objc_retain
221 ; CHECK: }
222 define void @test5() nounwind {
223 entry:
224   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
225   %items.ptr = alloca [16 x i8*], align 8
226   %call = call i8* @returner()
227   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
228   call void @callee()
229   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
230   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
231   %1 = call i8* @objc_retain(i8* %0) nounwind
232   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
233   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
234   %iszero = icmp eq i64 %call3, 0
235   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
236
237 forcoll.loopinit:
238   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
239   %mutationsptr = load i64** %mutationsptr.ptr, align 8
240   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
241   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
242   br label %forcoll.loopbody.outer
243
244 forcoll.loopbody.outer:
245   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
246   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
247   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
248   br label %forcoll.loopbody
249
250 forcoll.loopbody:
251   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
252   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
253   %statemutations = load i64* %mutationsptr4, align 8
254   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
255   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
256
257 forcoll.mutated:
258   call void @objc_enumerationMutation(i8* %1)
259   br label %forcoll.notmutated
260
261 forcoll.notmutated:
262   %stateitems = load i8*** %stateitems.ptr, align 8
263   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
264   %3 = load i8** %currentitem.ptr, align 8
265   call void @use(i8* %3)
266   %4 = add i64 %forcoll.index, 1
267   %exitcond = icmp eq i64 %4, %umax
268   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
269
270 forcoll.refetch:
271   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
272   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
273   %5 = icmp eq i64 %call7, 0
274   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
275
276 forcoll.empty:
277   call void @objc_release(i8* %1) nounwind
278   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
279   ret void
280 }
281
282 ; Delete a nested retain+release pair.
283
284 ; CHECK: define void @test6(
285 ; CHECK: call i8* @objc_retain
286 ; CHECK-NOT: @objc_retain
287 ; CHECK: }
288 define void @test6() nounwind {
289 entry:
290   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
291   %items.ptr = alloca [16 x i8*], align 8
292   %call = call i8* @returner()
293   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
294   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
295   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
296   %1 = call i8* @objc_retain(i8* %0) nounwind
297   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
298   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
299   %iszero = icmp eq i64 %call3, 0
300   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
301
302 forcoll.loopinit:
303   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
304   %mutationsptr = load i64** %mutationsptr.ptr, align 8
305   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
306   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
307   br label %forcoll.loopbody.outer
308
309 forcoll.loopbody.outer:
310   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
311   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
312   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
313   br label %forcoll.loopbody
314
315 forcoll.loopbody:
316   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
317   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
318   %statemutations = load i64* %mutationsptr4, align 8
319   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
320   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
321
322 forcoll.mutated:
323   call void @objc_enumerationMutation(i8* %1)
324   br label %forcoll.notmutated
325
326 forcoll.notmutated:
327   %stateitems = load i8*** %stateitems.ptr, align 8
328   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
329   %3 = load i8** %currentitem.ptr, align 8
330   call void @use(i8* %3)
331   %4 = add i64 %forcoll.index, 1
332   %exitcond = icmp eq i64 %4, %umax
333   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
334
335 forcoll.refetch:
336   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
337   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
338   %5 = icmp eq i64 %call7, 0
339   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
340
341 forcoll.empty:
342   call void @objc_release(i8* %1) nounwind
343   call void @callee()
344   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
345   ret void
346 }
347
348 ; Delete a nested retain+release pair.
349
350 ; CHECK: define void @test7(
351 ; CHECK: call i8* @objc_retain
352 ; CHECK-NOT: @objc_retain
353 ; CHECK: }
354 define void @test7() nounwind {
355 entry:
356   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
357   %items.ptr = alloca [16 x i8*], align 8
358   %call = call i8* @returner()
359   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
360   call void @callee()
361   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
362   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
363   %1 = call i8* @objc_retain(i8* %0) nounwind
364   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
365   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
366   %iszero = icmp eq i64 %call3, 0
367   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
368
369 forcoll.loopinit:
370   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
371   %mutationsptr = load i64** %mutationsptr.ptr, align 8
372   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
373   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
374   br label %forcoll.loopbody.outer
375
376 forcoll.loopbody.outer:
377   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
378   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
379   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
380   br label %forcoll.loopbody
381
382 forcoll.loopbody:
383   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.notmutated ]
384   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
385   %statemutations = load i64* %mutationsptr4, align 8
386   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
387   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
388
389 forcoll.mutated:
390   call void @objc_enumerationMutation(i8* %1)
391   br label %forcoll.notmutated
392
393 forcoll.notmutated:
394   %stateitems = load i8*** %stateitems.ptr, align 8
395   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
396   %3 = load i8** %currentitem.ptr, align 8
397   call void @use(i8* %3)
398   %4 = add i64 %forcoll.index, 1
399   %exitcond = icmp eq i64 %4, %umax
400   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
401
402 forcoll.refetch:
403   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
404   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
405   %5 = icmp eq i64 %call7, 0
406   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
407
408 forcoll.empty:
409   call void @objc_release(i8* %1) nounwind
410   call void @callee()
411   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
412   ret void
413 }
414
415 ; Delete a nested retain+release pair.
416
417 ; CHECK: define void @test8(
418 ; CHECK: call i8* @objc_retain
419 ; CHECK-NOT: @objc_retain
420 ; CHECK: }
421 define void @test8() nounwind {
422 entry:
423   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
424   %items.ptr = alloca [16 x i8*], align 8
425   %call = call i8* @returner()
426   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
427   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
428   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
429   %1 = call i8* @objc_retain(i8* %0) nounwind
430   %tmp2 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
431   %call3 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp2, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
432   %iszero = icmp eq i64 %call3, 0
433   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
434
435 forcoll.loopinit:
436   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
437   %mutationsptr = load i64** %mutationsptr.ptr, align 8
438   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
439   %stateitems.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 1
440   br label %forcoll.loopbody.outer
441
442 forcoll.loopbody.outer:
443   %forcoll.count.ph = phi i64 [ %call3, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
444   %tmp8 = icmp ugt i64 %forcoll.count.ph, 1
445   %umax = select i1 %tmp8, i64 %forcoll.count.ph, i64 1
446   br label %forcoll.loopbody
447
448 forcoll.loopbody:
449   %forcoll.index = phi i64 [ 0, %forcoll.loopbody.outer ], [ %4, %forcoll.next ]
450   %mutationsptr4 = load i64** %mutationsptr.ptr, align 8
451   %statemutations = load i64* %mutationsptr4, align 8
452   %2 = icmp eq i64 %statemutations, %forcoll.initial-mutations
453   br i1 %2, label %forcoll.notmutated, label %forcoll.mutated
454
455 forcoll.mutated:
456   call void @objc_enumerationMutation(i8* %1)
457   br label %forcoll.notmutated
458
459 forcoll.notmutated:
460   %stateitems = load i8*** %stateitems.ptr, align 8
461   %currentitem.ptr = getelementptr i8** %stateitems, i64 %forcoll.index
462   %3 = load i8** %currentitem.ptr, align 8
463   %tobool = icmp eq i8* %3, null
464   br i1 %tobool, label %forcoll.next, label %if.then
465
466 if.then:
467   call void @callee()
468   br label %forcoll.next
469
470 forcoll.next:
471   %4 = add i64 %forcoll.index, 1
472   %exitcond = icmp eq i64 %4, %umax
473   br i1 %exitcond, label %forcoll.refetch, label %forcoll.loopbody
474
475 forcoll.refetch:
476   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
477   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %1, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
478   %5 = icmp eq i64 %call7, 0
479   br i1 %5, label %forcoll.empty, label %forcoll.loopbody.outer
480
481 forcoll.empty:
482   call void @objc_release(i8* %1) nounwind
483   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
484   ret void
485 }
486
487 ; Delete a nested retain+release pair.
488
489 ; CHECK: define void @test9(
490 ; CHECK: call i8* @objc_retain
491 ; CHECK: call i8* @objc_retain
492 ; CHECK-NOT: @objc_retain
493 ; CHECK: }
494 define void @test9() nounwind {
495 entry:
496   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
497   %items.ptr = alloca [16 x i8*], align 8
498   %call = call i8* @returner()
499   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
500   %call1 = call i8* @returner()
501   %1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) nounwind
502   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
503   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
504   %2 = call i8* @objc_retain(i8* %0) nounwind
505   %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
506   %call4 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp3, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
507   %iszero = icmp eq i64 %call4, 0
508   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
509
510 forcoll.loopinit:
511   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
512   %mutationsptr = load i64** %mutationsptr.ptr, align 8
513   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
514   br label %forcoll.loopbody.outer
515
516 forcoll.loopbody.outer:
517   %forcoll.count.ph = phi i64 [ %call4, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
518   %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
519   %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
520   br label %forcoll.loopbody
521
522 forcoll.loopbody:
523   %forcoll.index = phi i64 [ %phitmp, %forcoll.notmutated.forcoll.loopbody_crit_edge ], [ 1, %forcoll.loopbody.outer ]
524   %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
525   %statemutations = load i64* %mutationsptr5, align 8
526   %3 = icmp eq i64 %statemutations, %forcoll.initial-mutations
527   br i1 %3, label %forcoll.notmutated, label %forcoll.mutated
528
529 forcoll.mutated:
530   call void @objc_enumerationMutation(i8* %2)
531   br label %forcoll.notmutated
532
533 forcoll.notmutated:
534   %exitcond = icmp eq i64 %forcoll.index, %umax
535   br i1 %exitcond, label %forcoll.refetch, label %forcoll.notmutated.forcoll.loopbody_crit_edge
536
537 forcoll.notmutated.forcoll.loopbody_crit_edge:
538   %phitmp = add i64 %forcoll.index, 1
539   br label %forcoll.loopbody
540
541 forcoll.refetch:
542   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
543   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
544   %4 = icmp eq i64 %call7, 0
545   br i1 %4, label %forcoll.empty, label %forcoll.loopbody.outer
546
547 forcoll.empty:
548   call void @objc_release(i8* %2) nounwind
549   call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
550   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
551   ret void
552 }
553
554 ; Delete a nested retain+release pair.
555
556 ; CHECK: define void @test10(
557 ; CHECK: call i8* @objc_retain
558 ; CHECK: call i8* @objc_retain
559 ; CHECK-NOT: @objc_retain
560 ; CHECK: }
561 define void @test10() nounwind {
562 entry:
563   %state.ptr = alloca %struct.__objcFastEnumerationState, align 8
564   %items.ptr = alloca [16 x i8*], align 8
565   %call = call i8* @returner()
566   %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
567   %call1 = call i8* @returner()
568   %1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call1) nounwind
569   call void @callee()
570   %tmp = bitcast %struct.__objcFastEnumerationState* %state.ptr to i8*
571   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 64, i32 8, i1 false)
572   %2 = call i8* @objc_retain(i8* %0) nounwind
573   %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
574   %call4 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp3, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
575   %iszero = icmp eq i64 %call4, 0
576   br i1 %iszero, label %forcoll.empty, label %forcoll.loopinit
577
578 forcoll.loopinit:
579   %mutationsptr.ptr = getelementptr inbounds %struct.__objcFastEnumerationState* %state.ptr, i64 0, i32 2
580   %mutationsptr = load i64** %mutationsptr.ptr, align 8
581   %forcoll.initial-mutations = load i64* %mutationsptr, align 8
582   br label %forcoll.loopbody.outer
583
584 forcoll.loopbody.outer:
585   %forcoll.count.ph = phi i64 [ %call4, %forcoll.loopinit ], [ %call7, %forcoll.refetch ]
586   %tmp9 = icmp ugt i64 %forcoll.count.ph, 1
587   %umax = select i1 %tmp9, i64 %forcoll.count.ph, i64 1
588   br label %forcoll.loopbody
589
590 forcoll.loopbody:
591   %forcoll.index = phi i64 [ %phitmp, %forcoll.notmutated.forcoll.loopbody_crit_edge ], [ 1, %forcoll.loopbody.outer ]
592   %mutationsptr5 = load i64** %mutationsptr.ptr, align 8
593   %statemutations = load i64* %mutationsptr5, align 8
594   %3 = icmp eq i64 %statemutations, %forcoll.initial-mutations
595   br i1 %3, label %forcoll.notmutated, label %forcoll.mutated
596
597 forcoll.mutated:
598   call void @objc_enumerationMutation(i8* %2)
599   br label %forcoll.notmutated
600
601 forcoll.notmutated:
602   %exitcond = icmp eq i64 %forcoll.index, %umax
603   br i1 %exitcond, label %forcoll.refetch, label %forcoll.notmutated.forcoll.loopbody_crit_edge
604
605 forcoll.notmutated.forcoll.loopbody_crit_edge:
606   %phitmp = add i64 %forcoll.index, 1
607   br label %forcoll.loopbody
608
609 forcoll.refetch:
610   %tmp6 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
611   %call7 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)(i8* %2, i8* %tmp6, %struct.__objcFastEnumerationState* %state.ptr, [16 x i8*]* %items.ptr, i64 16)
612   %4 = icmp eq i64 %call7, 0
613   br i1 %4, label %forcoll.empty, label %forcoll.loopbody.outer
614
615 forcoll.empty:
616   call void @objc_release(i8* %2) nounwind
617   call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
618   call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
619   ret void
620 }