xref: /aosp_15_r20/external/llvm/test/Transforms/ObjCARC/cfg-hazards.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -objc-arc < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; rdar://9503416
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; Detect loop boundaries and don't move retains and releases
5*9880d681SAndroid Build Coastguard Worker; across them.
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Workerdeclare void @use_pointer(i8*)
8*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retain(i8*)
9*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*)
10*9880d681SAndroid Build Coastguard Workerdeclare void @callee()
11*9880d681SAndroid Build Coastguard Workerdeclare void @block_callee(void ()*)
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test0(
14*9880d681SAndroid Build Coastguard Worker; CHECK:   call i8* @objc_retain(
15*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
16*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc
17*9880d681SAndroid Build Coastguard Worker; CHECK: for.end:
18*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @objc_release(
19*9880d681SAndroid Build Coastguard Worker; CHECK: }
20*9880d681SAndroid Build Coastguard Workerdefine void @test0(i8* %digits) {
21*9880d681SAndroid Build Coastguard Workerentry:
22*9880d681SAndroid Build Coastguard Worker  %tmp1 = call i8* @objc_retain(i8* %digits) nounwind
23*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %digits)
24*9880d681SAndroid Build Coastguard Worker  br label %for.body
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
27*9880d681SAndroid Build Coastguard Worker  %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]
28*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %digits)
29*9880d681SAndroid Build Coastguard Worker  %inc = add i64 %upcDigitIndex.01, 1
30*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ult i64 %inc, 12
31*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.body, label %for.end
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
34*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0
35*9880d681SAndroid Build Coastguard Worker  ret void
36*9880d681SAndroid Build Coastguard Worker}
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test1(
39*9880d681SAndroid Build Coastguard Worker; CHECK:   call i8* @objc_retain(
40*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
41*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc
42*9880d681SAndroid Build Coastguard Worker; CHECK: for.end:
43*9880d681SAndroid Build Coastguard Worker; CHECK:   void @objc_release(
44*9880d681SAndroid Build Coastguard Worker; CHECK: }
45*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8* %digits) {
46*9880d681SAndroid Build Coastguard Workerentry:
47*9880d681SAndroid Build Coastguard Worker  %tmp1 = call i8* @objc_retain(i8* %digits) nounwind
48*9880d681SAndroid Build Coastguard Worker  br label %for.body
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
51*9880d681SAndroid Build Coastguard Worker  %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]
52*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %digits)
53*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %digits)
54*9880d681SAndroid Build Coastguard Worker  %inc = add i64 %upcDigitIndex.01, 1
55*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ult i64 %inc, 12
56*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.body, label %for.end
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
59*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0
60*9880d681SAndroid Build Coastguard Worker  ret void
61*9880d681SAndroid Build Coastguard Worker}
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test2(
64*9880d681SAndroid Build Coastguard Worker; CHECK:   call i8* @objc_retain(
65*9880d681SAndroid Build Coastguard Worker; CHECK: for.body:
66*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc
67*9880d681SAndroid Build Coastguard Worker; CHECK: for.end:
68*9880d681SAndroid Build Coastguard Worker; CHECK:   void @objc_release(
69*9880d681SAndroid Build Coastguard Worker; CHECK: }
70*9880d681SAndroid Build Coastguard Workerdefine void @test2(i8* %digits) {
71*9880d681SAndroid Build Coastguard Workerentry:
72*9880d681SAndroid Build Coastguard Worker  %tmp1 = call i8* @objc_retain(i8* %digits) nounwind
73*9880d681SAndroid Build Coastguard Worker  br label %for.body
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
76*9880d681SAndroid Build Coastguard Worker  %upcDigitIndex.01 = phi i64 [ 2, %entry ], [ %inc, %for.body ]
77*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %digits)
78*9880d681SAndroid Build Coastguard Worker  %inc = add i64 %upcDigitIndex.01, 1
79*9880d681SAndroid Build Coastguard Worker  %cmp = icmp ult i64 %inc, 12
80*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %for.body, label %for.end
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
83*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %digits)
84*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %digits) nounwind, !clang.imprecise_release !0
85*9880d681SAndroid Build Coastguard Worker  ret void
86*9880d681SAndroid Build Coastguard Worker}
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker; Delete nested retain+release pairs around loops.
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test3(i8* %a) #0 {
91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   tail call i8* @objc_retain(i8* %a) [[NUW:#[0-9]+]]
93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
94*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
95*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @objc_release(i8* %a)
97*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
98*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
99*9880d681SAndroid Build Coastguard Workerdefine void @test3(i8* %a) nounwind {
100*9880d681SAndroid Build Coastguard Workerentry:
101*9880d681SAndroid Build Coastguard Worker  %outer = call i8* @objc_retain(i8* %a) nounwind
102*9880d681SAndroid Build Coastguard Worker  %inner = call i8* @objc_retain(i8* %a) nounwind
103*9880d681SAndroid Build Coastguard Worker  br label %loop
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Workerloop:
106*9880d681SAndroid Build Coastguard Worker  call void @callee()
107*9880d681SAndroid Build Coastguard Worker  store i8 0, i8* %a
108*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %exit
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Workerexit:
111*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
112*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
113*9880d681SAndroid Build Coastguard Worker  ret void
114*9880d681SAndroid Build Coastguard Worker}
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test4(i8* %a) #0 {
117*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
118*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   tail call i8* @objc_retain(i8* %a) [[NUW]]
119*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
120*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
121*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
122*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @objc_release(i8* %a)
123*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
124*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
125*9880d681SAndroid Build Coastguard Workerdefine void @test4(i8* %a) nounwind {
126*9880d681SAndroid Build Coastguard Workerentry:
127*9880d681SAndroid Build Coastguard Worker  %outer = call i8* @objc_retain(i8* %a) nounwind
128*9880d681SAndroid Build Coastguard Worker  %inner = call i8* @objc_retain(i8* %a) nounwind
129*9880d681SAndroid Build Coastguard Worker  br label %loop
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Workerloop:
132*9880d681SAndroid Build Coastguard Worker  br label %more
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Workermore:
135*9880d681SAndroid Build Coastguard Worker  call void @callee()
136*9880d681SAndroid Build Coastguard Worker  call void @callee()
137*9880d681SAndroid Build Coastguard Worker  store i8 0, i8* %a
138*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %exit
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Workerexit:
141*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
142*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
143*9880d681SAndroid Build Coastguard Worker  ret void
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test5(i8* %a) #0 {
147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   tail call i8* @objc_retain(i8* %a) [[NUW]]
149*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @callee()
150*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
151*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
152*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @use_pointer(i8* %a)
154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @objc_release(i8* %a)
155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
157*9880d681SAndroid Build Coastguard Workerdefine void @test5(i8* %a) nounwind {
158*9880d681SAndroid Build Coastguard Workerentry:
159*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
160*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
161*9880d681SAndroid Build Coastguard Worker  call void @callee()
162*9880d681SAndroid Build Coastguard Worker  br label %loop
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Workerloop:
165*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Workertrue:
168*9880d681SAndroid Build Coastguard Worker  br label %more
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Workermore:
171*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Workerexit:
174*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %a)
175*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
176*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
177*9880d681SAndroid Build Coastguard Worker  ret void
178*9880d681SAndroid Build Coastguard Worker}
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test6(i8* %a) #0 {
181*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
182*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   tail call i8* @objc_retain(i8* %a) [[NUW]]
183*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
184*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
185*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
186*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @use_pointer(i8* %a)
187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @objc_release(i8* %a)
188*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
189*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
190*9880d681SAndroid Build Coastguard Workerdefine void @test6(i8* %a) nounwind {
191*9880d681SAndroid Build Coastguard Workerentry:
192*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
193*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
194*9880d681SAndroid Build Coastguard Worker  br label %loop
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Workerloop:
197*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Workertrue:
200*9880d681SAndroid Build Coastguard Worker  call void @callee()
201*9880d681SAndroid Build Coastguard Worker  br label %more
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Workermore:
204*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Workerexit:
207*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %a)
208*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
209*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
210*9880d681SAndroid Build Coastguard Worker  ret void
211*9880d681SAndroid Build Coastguard Worker}
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test7(i8* %a) #0 {
214*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
215*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   tail call i8* @objc_retain(i8* %a) [[NUW]]
216*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @callee()
217*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
218*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
219*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
220*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @objc_release(i8* %a)
221*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
222*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
223*9880d681SAndroid Build Coastguard Workerdefine void @test7(i8* %a) nounwind {
224*9880d681SAndroid Build Coastguard Workerentry:
225*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
226*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
227*9880d681SAndroid Build Coastguard Worker  call void @callee()
228*9880d681SAndroid Build Coastguard Worker  br label %loop
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Workerloop:
231*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Workertrue:
234*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %a)
235*9880d681SAndroid Build Coastguard Worker  br label %more
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Workermore:
238*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Workerexit:
241*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
242*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
243*9880d681SAndroid Build Coastguard Worker  ret void
244*9880d681SAndroid Build Coastguard Worker}
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test8(i8* %a) #0 {
247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   tail call i8* @objc_retain(i8* %a) [[NUW]]
249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
250*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
251*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   call void @objc_release(i8* %a)
253*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
254*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
255*9880d681SAndroid Build Coastguard Workerdefine void @test8(i8* %a) nounwind {
256*9880d681SAndroid Build Coastguard Workerentry:
257*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
258*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
259*9880d681SAndroid Build Coastguard Worker  br label %loop
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Workerloop:
262*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Workertrue:
265*9880d681SAndroid Build Coastguard Worker  call void @callee()
266*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %a)
267*9880d681SAndroid Build Coastguard Worker  br label %more
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Workermore:
270*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Workerexit:
273*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
274*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
275*9880d681SAndroid Build Coastguard Worker  ret void
276*9880d681SAndroid Build Coastguard Worker}
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test9(i8* %a) #0 {
279*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
280*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
281*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
282*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
283*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
284*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
285*9880d681SAndroid Build Coastguard Workerdefine void @test9(i8* %a) nounwind {
286*9880d681SAndroid Build Coastguard Workerentry:
287*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
288*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
289*9880d681SAndroid Build Coastguard Worker  br label %loop
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Workerloop:
292*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Workertrue:
295*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %a)
296*9880d681SAndroid Build Coastguard Worker  br label %more
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Workermore:
299*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Workerexit:
302*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
303*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
304*9880d681SAndroid Build Coastguard Worker  ret void
305*9880d681SAndroid Build Coastguard Worker}
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test10(i8* %a) #0 {
308*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
309*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
310*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
311*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
312*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
313*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
314*9880d681SAndroid Build Coastguard Workerdefine void @test10(i8* %a) nounwind {
315*9880d681SAndroid Build Coastguard Workerentry:
316*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
317*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
318*9880d681SAndroid Build Coastguard Worker  br label %loop
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Workerloop:
321*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Workertrue:
324*9880d681SAndroid Build Coastguard Worker  call void @callee()
325*9880d681SAndroid Build Coastguard Worker  br label %more
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Workermore:
328*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
329*9880d681SAndroid Build Coastguard Worker
330*9880d681SAndroid Build Coastguard Workerexit:
331*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
332*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
333*9880d681SAndroid Build Coastguard Worker  ret void
334*9880d681SAndroid Build Coastguard Worker}
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test11(i8* %a) #0 {
337*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
338*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
339*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
340*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
341*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
342*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
343*9880d681SAndroid Build Coastguard Workerdefine void @test11(i8* %a) nounwind {
344*9880d681SAndroid Build Coastguard Workerentry:
345*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
346*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
347*9880d681SAndroid Build Coastguard Worker  br label %loop
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Workerloop:
350*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Workertrue:
353*9880d681SAndroid Build Coastguard Worker  br label %more
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Workermore:
356*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Workerexit:
359*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
360*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
361*9880d681SAndroid Build Coastguard Worker  ret void
362*9880d681SAndroid Build Coastguard Worker}
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker; Don't delete anything if they're not balanced.
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker;      CHECK: define void @test12(i8* %a) #0 {
367*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
368*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   %outer = tail call i8* @objc_retain(i8* %a) [[NUW]]
369*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   %inner = tail call i8* @objc_retain(i8* %a) [[NUW]]
370*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   br label %loop
371*9880d681SAndroid Build Coastguard Worker;  CHECK-NOT:   @objc_
372*9880d681SAndroid Build Coastguard Worker;      CHECK: exit:
373*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) [[NUW]]
374*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %a) [[NUW]], !clang.imprecise_release !0
375*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   ret void
376*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
377*9880d681SAndroid Build Coastguard Workerdefine void @test12(i8* %a) nounwind {
378*9880d681SAndroid Build Coastguard Workerentry:
379*9880d681SAndroid Build Coastguard Worker  %outer = tail call i8* @objc_retain(i8* %a) nounwind
380*9880d681SAndroid Build Coastguard Worker  %inner = tail call i8* @objc_retain(i8* %a) nounwind
381*9880d681SAndroid Build Coastguard Worker  br label %loop
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Workerloop:
384*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %true, label %more
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Workertrue:
387*9880d681SAndroid Build Coastguard Worker  ret void
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Workermore:
390*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %exit, label %loop
391*9880d681SAndroid Build Coastguard Worker
392*9880d681SAndroid Build Coastguard Workerexit:
393*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind
394*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
395*9880d681SAndroid Build Coastguard Worker  ret void
396*9880d681SAndroid Build Coastguard Worker}
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker; Do not improperly pair retains in a for loop with releases outside of a for
399*9880d681SAndroid Build Coastguard Worker; loop when the proper pairing is disguised by a separate provenance represented
400*9880d681SAndroid Build Coastguard Worker; by an alloca.
401*9880d681SAndroid Build Coastguard Worker; rdar://12969722
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test13(i8* %a) [[NUW]] {
404*9880d681SAndroid Build Coastguard Worker; CHECK: entry:
405*9880d681SAndroid Build Coastguard Worker; CHECK:   tail call i8* @objc_retain(i8* %a) [[NUW]]
406*9880d681SAndroid Build Coastguard Worker; CHECK: loop:
407*9880d681SAndroid Build Coastguard Worker; CHECK:   tail call i8* @objc_retain(i8* %a) [[NUW]]
408*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @block_callee
409*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @objc_release(i8* %reloaded_a) [[NUW]]
410*9880d681SAndroid Build Coastguard Worker; CHECK: exit:
411*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @objc_release(i8* %a) [[NUW]]
412*9880d681SAndroid Build Coastguard Worker; CHECK: }
413*9880d681SAndroid Build Coastguard Workerdefine void @test13(i8* %a) nounwind {
414*9880d681SAndroid Build Coastguard Workerentry:
415*9880d681SAndroid Build Coastguard Worker  %block = alloca i8*
416*9880d681SAndroid Build Coastguard Worker  %a1 = tail call i8* @objc_retain(i8* %a) nounwind
417*9880d681SAndroid Build Coastguard Worker  br label %loop
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Workerloop:
420*9880d681SAndroid Build Coastguard Worker  %a2 = tail call i8* @objc_retain(i8* %a) nounwind
421*9880d681SAndroid Build Coastguard Worker  store i8* %a, i8** %block, align 8
422*9880d681SAndroid Build Coastguard Worker  %casted_block = bitcast i8** %block to void ()*
423*9880d681SAndroid Build Coastguard Worker  call void @block_callee(void ()* %casted_block)
424*9880d681SAndroid Build Coastguard Worker  %reloaded_a = load i8*, i8** %block, align 8
425*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %reloaded_a) nounwind, !clang.imprecise_release !0
426*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %exit
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Workerexit:
429*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0
430*9880d681SAndroid Build Coastguard Worker  ret void
431*9880d681SAndroid Build Coastguard Worker}
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker; CHECK: attributes [[NUW]] = { nounwind }
434*9880d681SAndroid Build Coastguard Worker
435*9880d681SAndroid Build Coastguard Worker!0 = !{}
436