1; RUN: opt -basicaa -objc-arc -S < %s | FileCheck %s
2
3target datalayout = "e-p:64:64:64"
4
5declare i8* @objc_retain(i8*)
6declare i8* @objc_retainAutoreleasedReturnValue(i8*)
7declare void @objc_release(i8*)
8declare i8* @objc_autorelease(i8*)
9declare i8* @objc_autoreleaseReturnValue(i8*)
10declare void @objc_autoreleasePoolPop(i8*)
11declare i8* @objc_autoreleasePoolPush()
12declare i8* @objc_retainBlock(i8*)
13
14declare i8* @objc_retainedObject(i8*)
15declare i8* @objc_unretainedObject(i8*)
16declare i8* @objc_unretainedPointer(i8*)
17
18declare void @use_pointer(i8*)
19declare void @callee()
20declare void @callee_fnptr(void ()*)
21declare void @invokee()
22declare i8* @returner()
23declare void @bar(i32 ()*)
24
25declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
26
27declare i8* @objc_msgSend(i8*, i8*, ...)
28
29; Simple retain+release pair deletion, with some intervening control
30; flow and harmless instructions.
31
32; CHECK: define void @test0_precise(i32* %x, i1 %p) [[NUW:#[0-9]+]] {
33; CHECK: @objc_retain
34; CHECK: @objc_release
35; CHECK: }
36define void @test0_precise(i32* %x, i1 %p) nounwind {
37entry:
38  %a = bitcast i32* %x to i8*
39  %0 = call i8* @objc_retain(i8* %a) nounwind
40  br i1 %p, label %t, label %f
41
42t:
43  store i8 3, i8* %a
44  %b = bitcast i32* %x to float*
45  store float 2.0, float* %b
46  br label %return
47
48f:
49  store i32 7, i32* %x
50  br label %return
51
52return:
53  %c = bitcast i32* %x to i8*
54  call void @objc_release(i8* %c) nounwind
55  ret void
56}
57
58; CHECK: define void @test0_imprecise(i32* %x, i1 %p) [[NUW]] {
59; CHECK-NOT: @objc_
60; CHECK: }
61define void @test0_imprecise(i32* %x, i1 %p) nounwind {
62entry:
63  %a = bitcast i32* %x to i8*
64  %0 = call i8* @objc_retain(i8* %a) nounwind
65  br i1 %p, label %t, label %f
66
67t:
68  store i8 3, i8* %a
69  %b = bitcast i32* %x to float*
70  store float 2.0, float* %b
71  br label %return
72
73f:
74  store i32 7, i32* %x
75  br label %return
76
77return:
78  %c = bitcast i32* %x to i8*
79  call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0
80  ret void
81}
82
83; Like test0 but the release isn't always executed when the retain is,
84; so the optimization is not safe.
85
86; TODO: Make the objc_release's argument be %0.
87
88; CHECK: define void @test1_precise(i32* %x, i1 %p, i1 %q) [[NUW]] {
89; CHECK: @objc_retain(i8* %a)
90; CHECK: @objc_release
91; CHECK: }
92define void @test1_precise(i32* %x, i1 %p, i1 %q) nounwind {
93entry:
94  %a = bitcast i32* %x to i8*
95  %0 = call i8* @objc_retain(i8* %a) nounwind
96  br i1 %p, label %t, label %f
97
98t:
99  store i8 3, i8* %a
100  %b = bitcast i32* %x to float*
101  store float 2.0, float* %b
102  br label %return
103
104f:
105  store i32 7, i32* %x
106  call void @callee()
107  br i1 %q, label %return, label %alt_return
108
109return:
110  %c = bitcast i32* %x to i8*
111  call void @objc_release(i8* %c) nounwind
112  ret void
113
114alt_return:
115  ret void
116}
117
118; CHECK: define void @test1_imprecise(i32* %x, i1 %p, i1 %q) [[NUW]] {
119; CHECK: @objc_retain(i8* %a)
120; CHECK: @objc_release
121; CHECK: }
122define void @test1_imprecise(i32* %x, i1 %p, i1 %q) nounwind {
123entry:
124  %a = bitcast i32* %x to i8*
125  %0 = call i8* @objc_retain(i8* %a) nounwind
126  br i1 %p, label %t, label %f
127
128t:
129  store i8 3, i8* %a
130  %b = bitcast i32* %x to float*
131  store float 2.0, float* %b
132  br label %return
133
134f:
135  store i32 7, i32* %x
136  call void @callee()
137  br i1 %q, label %return, label %alt_return
138
139return:
140  %c = bitcast i32* %x to i8*
141  call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0
142  ret void
143
144alt_return:
145  ret void
146}
147
148
149; Don't do partial elimination into two different CFG diamonds.
150
151; CHECK: define void @test1b_precise(i8* %x, i1 %p, i1 %q) {
152; CHECK: entry:
153; CHECK:   tail call i8* @objc_retain(i8* %x) [[NUW]]
154; CHECK-NOT: @objc_
155; CHECK: if.end5:
156; CHECK:   tail call void @objc_release(i8* %x) [[NUW]]
157; CHECK-NOT: @objc_
158; CHECK: }
159define void @test1b_precise(i8* %x, i1 %p, i1 %q) {
160entry:
161  tail call i8* @objc_retain(i8* %x) nounwind
162  br i1 %p, label %if.then, label %if.end
163
164if.then:                                          ; preds = %entry
165  tail call void @callee()
166  br label %if.end
167
168if.end:                                           ; preds = %if.then, %entry
169  br i1 %q, label %if.then3, label %if.end5
170
171if.then3:                                         ; preds = %if.end
172  tail call void @use_pointer(i8* %x)
173  br label %if.end5
174
175if.end5:                                          ; preds = %if.then3, %if.end
176  tail call void @objc_release(i8* %x) nounwind
177  ret void
178}
179
180; CHECK-LABEL: define void @test1b_imprecise(
181; CHECK: entry:
182; CHECK:   tail call i8* @objc_retain(i8* %x) [[NUW:#[0-9]+]]
183; CHECK-NOT: @objc_
184; CHECK: if.end5:
185; CHECK:   tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE:[0-9]+]]
186; CHECK-NOT: @objc_
187; CHECK: }
188define void @test1b_imprecise(i8* %x, i1 %p, i1 %q) {
189entry:
190  tail call i8* @objc_retain(i8* %x) nounwind
191  br i1 %p, label %if.then, label %if.end
192
193if.then:                                          ; preds = %entry
194  tail call void @callee()
195  br label %if.end
196
197if.end:                                           ; preds = %if.then, %entry
198  br i1 %q, label %if.then3, label %if.end5
199
200if.then3:                                         ; preds = %if.end
201  tail call void @use_pointer(i8* %x)
202  br label %if.end5
203
204if.end5:                                          ; preds = %if.then3, %if.end
205  tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
206  ret void
207}
208
209
210; Like test0 but the pointer is passed to an intervening call,
211; so the optimization is not safe.
212
213; CHECK-LABEL: define void @test2_precise(
214; CHECK: @objc_retain(i8* %a)
215; CHECK: @objc_release
216; CHECK: }
217define void @test2_precise(i32* %x, i1 %p) nounwind {
218entry:
219  %a = bitcast i32* %x to i8*
220  %0 = call i8* @objc_retain(i8* %a) nounwind
221  br i1 %p, label %t, label %f
222
223t:
224  store i8 3, i8* %a
225  %b = bitcast i32* %x to float*
226  store float 2.0, float* %b
227  br label %return
228
229f:
230  store i32 7, i32* %x
231  call void @use_pointer(i8* %0)
232  %d = bitcast i32* %x to float*
233  store float 3.0, float* %d
234  br label %return
235
236return:
237  %c = bitcast i32* %x to i8*
238  call void @objc_release(i8* %c) nounwind
239  ret void
240}
241
242; CHECK-LABEL: define void @test2_imprecise(
243; CHECK: @objc_retain(i8* %a)
244; CHECK: @objc_release
245; CHECK: }
246define void @test2_imprecise(i32* %x, i1 %p) nounwind {
247entry:
248  %a = bitcast i32* %x to i8*
249  %0 = call i8* @objc_retain(i8* %a) nounwind
250  br i1 %p, label %t, label %f
251
252t:
253  store i8 3, i8* %a
254  %b = bitcast i32* %x to float*
255  store float 2.0, float* %b
256  br label %return
257
258f:
259  store i32 7, i32* %x
260  call void @use_pointer(i8* %0)
261  %d = bitcast i32* %x to float*
262  store float 3.0, float* %d
263  br label %return
264
265return:
266  %c = bitcast i32* %x to i8*
267  call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0
268  ret void
269}
270
271; Like test0 but the release is in a loop,
272; so the optimization is not safe.
273
274; TODO: For now, assume this can't happen.
275
276; CHECK-LABEL: define void @test3_precise(
277; TODO: @objc_retain(i8* %a)
278; TODO: @objc_release
279; CHECK: }
280define void @test3_precise(i32* %x, i1* %q) nounwind {
281entry:
282  %a = bitcast i32* %x to i8*
283  %0 = call i8* @objc_retain(i8* %a) nounwind
284  br label %loop
285
286loop:
287  %c = bitcast i32* %x to i8*
288  call void @objc_release(i8* %c) nounwind
289  %j = load volatile i1, i1* %q
290  br i1 %j, label %loop, label %return
291
292return:
293  ret void
294}
295
296; CHECK-LABEL: define void @test3_imprecise(
297; TODO: @objc_retain(i8* %a)
298; TODO: @objc_release
299; CHECK: }
300define void @test3_imprecise(i32* %x, i1* %q) nounwind {
301entry:
302  %a = bitcast i32* %x to i8*
303  %0 = call i8* @objc_retain(i8* %a) nounwind
304  br label %loop
305
306loop:
307  %c = bitcast i32* %x to i8*
308  call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0
309  %j = load volatile i1, i1* %q
310  br i1 %j, label %loop, label %return
311
312return:
313  ret void
314}
315
316
317; TODO: For now, assume this can't happen.
318
319; Like test0 but the retain is in a loop,
320; so the optimization is not safe.
321
322; CHECK-LABEL: define void @test4_precise(
323; TODO: @objc_retain(i8* %a)
324; TODO: @objc_release
325; CHECK: }
326define void @test4_precise(i32* %x, i1* %q) nounwind {
327entry:
328  br label %loop
329
330loop:
331  %a = bitcast i32* %x to i8*
332  %0 = call i8* @objc_retain(i8* %a) nounwind
333  %j = load volatile i1, i1* %q
334  br i1 %j, label %loop, label %return
335
336return:
337  %c = bitcast i32* %x to i8*
338  call void @objc_release(i8* %c) nounwind
339  ret void
340}
341
342; CHECK-LABEL: define void @test4_imprecise(
343; TODO: @objc_retain(i8* %a)
344; TODO: @objc_release
345; CHECK: }
346define void @test4_imprecise(i32* %x, i1* %q) nounwind {
347entry:
348  br label %loop
349
350loop:
351  %a = bitcast i32* %x to i8*
352  %0 = call i8* @objc_retain(i8* %a) nounwind
353  %j = load volatile i1, i1* %q
354  br i1 %j, label %loop, label %return
355
356return:
357  %c = bitcast i32* %x to i8*
358  call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0
359  ret void
360}
361
362
363; Like test0 but the pointer is conditionally passed to an intervening call,
364; so the optimization is not safe.
365
366; CHECK-LABEL: define void @test5a(
367; CHECK: @objc_retain(i8*
368; CHECK: @objc_release
369; CHECK: }
370define void @test5a(i32* %x, i1 %q, i8* %y) nounwind {
371entry:
372  %a = bitcast i32* %x to i8*
373  %0 = call i8* @objc_retain(i8* %a) nounwind
374  %s = select i1 %q, i8* %y, i8* %0
375  call void @use_pointer(i8* %s)
376  store i32 7, i32* %x
377  %c = bitcast i32* %x to i8*
378  call void @objc_release(i8* %c) nounwind
379  ret void
380}
381
382; CHECK-LABEL: define void @test5b(
383; CHECK: @objc_retain(i8*
384; CHECK: @objc_release
385; CHECK: }
386define void @test5b(i32* %x, i1 %q, i8* %y) nounwind {
387entry:
388  %a = bitcast i32* %x to i8*
389  %0 = call i8* @objc_retain(i8* %a) nounwind
390  %s = select i1 %q, i8* %y, i8* %0
391  call void @use_pointer(i8* %s)
392  store i32 7, i32* %x
393  %c = bitcast i32* %x to i8*
394  call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0
395  ret void
396}
397
398
399; retain+release pair deletion, where the release happens on two different
400; flow paths.
401
402; CHECK-LABEL: define void @test6a(
403; CHECK: entry:
404; CHECK:   tail call i8* @objc_retain(
405; CHECK: t:
406; CHECK:   call void @objc_release(
407; CHECK: f:
408; CHECK:   call void @objc_release(
409; CHECK: return:
410; CHECK: }
411define void @test6a(i32* %x, i1 %p) nounwind {
412entry:
413  %a = bitcast i32* %x to i8*
414  %0 = call i8* @objc_retain(i8* %a) nounwind
415  br i1 %p, label %t, label %f
416
417t:
418  store i8 3, i8* %a
419  %b = bitcast i32* %x to float*
420  store float 2.0, float* %b
421  %ct = bitcast i32* %x to i8*
422  call void @objc_release(i8* %ct) nounwind
423  br label %return
424
425f:
426  store i32 7, i32* %x
427  call void @callee()
428  %cf = bitcast i32* %x to i8*
429  call void @objc_release(i8* %cf) nounwind
430  br label %return
431
432return:
433  ret void
434}
435
436; CHECK-LABEL: define void @test6b(
437; CHECK-NOT: @objc_
438; CHECK: }
439define void @test6b(i32* %x, i1 %p) nounwind {
440entry:
441  %a = bitcast i32* %x to i8*
442  %0 = call i8* @objc_retain(i8* %a) nounwind
443  br i1 %p, label %t, label %f
444
445t:
446  store i8 3, i8* %a
447  %b = bitcast i32* %x to float*
448  store float 2.0, float* %b
449  %ct = bitcast i32* %x to i8*
450  call void @objc_release(i8* %ct) nounwind, !clang.imprecise_release !0
451  br label %return
452
453f:
454  store i32 7, i32* %x
455  call void @callee()
456  %cf = bitcast i32* %x to i8*
457  call void @objc_release(i8* %cf) nounwind, !clang.imprecise_release !0
458  br label %return
459
460return:
461  ret void
462}
463
464; CHECK-LABEL: define void @test6c(
465; CHECK: entry:
466; CHECK:   tail call i8* @objc_retain(
467; CHECK: t:
468; CHECK:   call void @objc_release(
469; CHECK: f:
470; CHECK:   call void @objc_release(
471; CHECK: return:
472; CHECK: }
473define void @test6c(i32* %x, i1 %p) nounwind {
474entry:
475  %a = bitcast i32* %x to i8*
476  %0 = call i8* @objc_retain(i8* %a) nounwind
477  br i1 %p, label %t, label %f
478
479t:
480  store i8 3, i8* %a
481  %b = bitcast i32* %x to float*
482  store float 2.0, float* %b
483  %ct = bitcast i32* %x to i8*
484  call void @objc_release(i8* %ct) nounwind
485  br label %return
486
487f:
488  store i32 7, i32* %x
489  call void @callee()
490  %cf = bitcast i32* %x to i8*
491  call void @objc_release(i8* %cf) nounwind, !clang.imprecise_release !0
492  br label %return
493
494return:
495  ret void
496}
497
498; CHECK-LABEL: define void @test6d(
499; CHECK: entry:
500; CHECK:   tail call i8* @objc_retain(
501; CHECK: t:
502; CHECK:   call void @objc_release(
503; CHECK: f:
504; CHECK:   call void @objc_release(
505; CHECK: return:
506; CHECK: }
507define void @test6d(i32* %x, i1 %p) nounwind {
508entry:
509  %a = bitcast i32* %x to i8*
510  %0 = call i8* @objc_retain(i8* %a) nounwind
511  br i1 %p, label %t, label %f
512
513t:
514  store i8 3, i8* %a
515  %b = bitcast i32* %x to float*
516  store float 2.0, float* %b
517  %ct = bitcast i32* %x to i8*
518  call void @objc_release(i8* %ct) nounwind, !clang.imprecise_release !0
519  br label %return
520
521f:
522  store i32 7, i32* %x
523  call void @callee()
524  %cf = bitcast i32* %x to i8*
525  call void @objc_release(i8* %cf) nounwind
526  br label %return
527
528return:
529  ret void
530}
531
532
533; retain+release pair deletion, where the retain happens on two different
534; flow paths.
535
536; CHECK-LABEL:     define void @test7(
537; CHECK:     entry:
538; CHECK-NOT:   objc_
539; CHECK:     t:
540; CHECK:       call i8* @objc_retain
541; CHECK:     f:
542; CHECK:       call i8* @objc_retain
543; CHECK:     return:
544; CHECK:       call void @objc_release
545; CHECK: }
546define void @test7(i32* %x, i1 %p) nounwind {
547entry:
548  %a = bitcast i32* %x to i8*
549  br i1 %p, label %t, label %f
550
551t:
552  %0 = call i8* @objc_retain(i8* %a) nounwind
553  store i8 3, i8* %a
554  %b = bitcast i32* %x to float*
555  store float 2.0, float* %b
556  br label %return
557
558f:
559  %1 = call i8* @objc_retain(i8* %a) nounwind
560  store i32 7, i32* %x
561  call void @callee()
562  br label %return
563
564return:
565  %c = bitcast i32* %x to i8*
566  call void @objc_release(i8* %c) nounwind
567  ret void
568}
569
570; CHECK-LABEL: define void @test7b(
571; CHECK-NOT: @objc_
572; CHECK: }
573define void @test7b(i32* %x, i1 %p) nounwind {
574entry:
575  %a = bitcast i32* %x to i8*
576  br i1 %p, label %t, label %f
577
578t:
579  %0 = call i8* @objc_retain(i8* %a) nounwind
580  store i8 3, i8* %a
581  %b = bitcast i32* %x to float*
582  store float 2.0, float* %b
583  br label %return
584
585f:
586  %1 = call i8* @objc_retain(i8* %a) nounwind
587  store i32 7, i32* %x
588  call void @callee()
589  br label %return
590
591return:
592  %c = bitcast i32* %x to i8*
593  call void @objc_release(i8* %c) nounwind, !clang.imprecise_release !0
594  ret void
595}
596
597; Like test7, but there's a retain/retainBlock mismatch. Don't delete!
598
599; CHECK-LABEL: define void @test7c(
600; CHECK: t:
601; CHECK:   call i8* @objc_retainBlock
602; CHECK: f:
603; CHECK:   call i8* @objc_retain
604; CHECK: return:
605; CHECK:   call void @objc_release
606; CHECK: }
607define void @test7c(i32* %x, i1 %p) nounwind {
608entry:
609  %a = bitcast i32* %x to i8*
610  br i1 %p, label %t, label %f
611
612t:
613  %0 = call i8* @objc_retainBlock(i8* %a) nounwind
614  store i8 3, i8* %a
615  %b = bitcast i32* %x to float*
616  store float 2.0, float* %b
617  br label %return
618
619f:
620  %1 = call i8* @objc_retain(i8* %a) nounwind
621  store i32 7, i32* %x
622  call void @callee()
623  br label %return
624
625return:
626  %c = bitcast i32* %x to i8*
627  call void @objc_release(i8* %c) nounwind
628  ret void
629}
630
631; retain+release pair deletion, where the retain and release both happen on
632; different flow paths. Wild!
633
634; CHECK-LABEL: define void @test8a(
635; CHECK: entry:
636; CHECK: t:
637; CHECK:   @objc_retain
638; CHECK: f:
639; CHECK:   @objc_retain
640; CHECK: mid:
641; CHECK: u:
642; CHECK:   @objc_release
643; CHECK: g:
644; CHECK:   @objc_release
645; CHECK: return:
646; CHECK: }
647define void @test8a(i32* %x, i1 %p, i1 %q) nounwind {
648entry:
649  %a = bitcast i32* %x to i8*
650  br i1 %p, label %t, label %f
651
652t:
653  %0 = call i8* @objc_retain(i8* %a) nounwind
654  store i8 3, i8* %a
655  %b = bitcast i32* %x to float*
656  store float 2.0, float* %b
657  br label %mid
658
659f:
660  %1 = call i8* @objc_retain(i8* %a) nounwind
661  store i32 7, i32* %x
662  br label %mid
663
664mid:
665  br i1 %q, label %u, label %g
666
667u:
668  call void @callee()
669  %cu = bitcast i32* %x to i8*
670  call void @objc_release(i8* %cu) nounwind
671  br label %return
672
673g:
674  %cg = bitcast i32* %x to i8*
675  call void @objc_release(i8* %cg) nounwind
676  br label %return
677
678return:
679  ret void
680}
681
682; CHECK-LABEL: define void @test8b(
683; CHECK-NOT: @objc_
684; CHECK: }
685define void @test8b(i32* %x, i1 %p, i1 %q) nounwind {
686entry:
687  %a = bitcast i32* %x to i8*
688  br i1 %p, label %t, label %f
689
690t:
691  %0 = call i8* @objc_retain(i8* %a) nounwind
692  store i8 3, i8* %a
693  %b = bitcast i32* %x to float*
694  store float 2.0, float* %b
695  br label %mid
696
697f:
698  %1 = call i8* @objc_retain(i8* %a) nounwind
699  store i32 7, i32* %x
700  br label %mid
701
702mid:
703  br i1 %q, label %u, label %g
704
705u:
706  call void @callee()
707  %cu = bitcast i32* %x to i8*
708  call void @objc_release(i8* %cu) nounwind, !clang.imprecise_release !0
709  br label %return
710
711g:
712  %cg = bitcast i32* %x to i8*
713  call void @objc_release(i8* %cg) nounwind, !clang.imprecise_release !0
714  br label %return
715
716return:
717  ret void
718}
719
720; CHECK-LABEL: define void @test8c(
721; CHECK: entry:
722; CHECK: t:
723; CHECK:   @objc_retain
724; CHECK: f:
725; CHECK:   @objc_retain
726; CHECK: mid:
727; CHECK: u:
728; CHECK:   @objc_release
729; CHECK: g:
730; CHECK:   @objc_release
731; CHECK: return:
732; CHECK: }
733define void @test8c(i32* %x, i1 %p, i1 %q) nounwind {
734entry:
735  %a = bitcast i32* %x to i8*
736  br i1 %p, label %t, label %f
737
738t:
739  %0 = call i8* @objc_retain(i8* %a) nounwind
740  store i8 3, i8* %a
741  %b = bitcast i32* %x to float*
742  store float 2.0, float* %b
743  br label %mid
744
745f:
746  %1 = call i8* @objc_retain(i8* %a) nounwind
747  store i32 7, i32* %x
748  br label %mid
749
750mid:
751  br i1 %q, label %u, label %g
752
753u:
754  call void @callee()
755  %cu = bitcast i32* %x to i8*
756  call void @objc_release(i8* %cu) nounwind
757  br label %return
758
759g:
760  %cg = bitcast i32* %x to i8*
761  call void @objc_release(i8* %cg) nounwind, !clang.imprecise_release !0
762  br label %return
763
764return:
765  ret void
766}
767
768; CHECK-LABEL: define void @test8d(
769; CHECK: entry:
770; CHECK: t:
771; CHECK:   @objc_retain
772; CHECK: f:
773; CHECK:   @objc_retain
774; CHECK: mid:
775; CHECK: u:
776; CHECK:   @objc_release
777; CHECK: g:
778; CHECK:   @objc_release
779; CHECK: return:
780; CHECK: }
781define void @test8d(i32* %x, i1 %p, i1 %q) nounwind {
782entry:
783  %a = bitcast i32* %x to i8*
784  br i1 %p, label %t, label %f
785
786t:
787  %0 = call i8* @objc_retain(i8* %a) nounwind
788  store i8 3, i8* %a
789  %b = bitcast i32* %x to float*
790  store float 2.0, float* %b
791  br label %mid
792
793f:
794  %1 = call i8* @objc_retain(i8* %a) nounwind
795  store i32 7, i32* %x
796  br label %mid
797
798mid:
799  br i1 %q, label %u, label %g
800
801u:
802  call void @callee()
803  %cu = bitcast i32* %x to i8*
804  call void @objc_release(i8* %cu) nounwind, !clang.imprecise_release !0
805  br label %return
806
807g:
808  %cg = bitcast i32* %x to i8*
809  call void @objc_release(i8* %cg) nounwind
810  br label %return
811
812return:
813  ret void
814}
815
816; Trivial retain+release pair deletion.
817
818; CHECK-LABEL: define void @test9(
819; CHECK-NOT: @objc_
820; CHECK: }
821define void @test9(i8* %x) nounwind {
822entry:
823  %0 = call i8* @objc_retain(i8* %x) nounwind
824  call void @objc_release(i8* %0) nounwind
825  ret void
826}
827
828; Retain+release pair, but on an unknown pointer relationship. Don't delete!
829
830; CHECK-LABEL: define void @test9b(
831; CHECK: @objc_retain(i8* %x)
832; CHECK: @objc_release(i8* %s)
833; CHECK: }
834define void @test9b(i8* %x, i1 %j, i8* %p) nounwind {
835entry:
836  %0 = call i8* @objc_retain(i8* %x) nounwind
837  %s = select i1 %j, i8* %x, i8* %p
838  call void @objc_release(i8* %s) nounwind
839  ret void
840}
841
842; Trivial retain+release pair with intervening calls - don't delete!
843
844; CHECK-LABEL: define void @test10(
845; CHECK: @objc_retain(i8* %x)
846; CHECK: @callee
847; CHECK: @use_pointer
848; CHECK: @objc_release
849; CHECK: }
850define void @test10(i8* %x) nounwind {
851entry:
852  %0 = call i8* @objc_retain(i8* %x) nounwind
853  call void @callee()
854  call void @use_pointer(i8* %x)
855  call void @objc_release(i8* %0) nounwind
856  ret void
857}
858
859; Trivial retain+autoreleaserelease pair. Don't delete!
860; Also, add a tail keyword, since objc_retain can never be passed
861; a stack argument.
862
863; CHECK-LABEL: define void @test11(
864; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
865; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]]
866; CHECK: }
867define void @test11(i8* %x) nounwind {
868entry:
869  %0 = call i8* @objc_retain(i8* %x) nounwind
870  call i8* @objc_autorelease(i8* %0) nounwind
871  call void @use_pointer(i8* %x)
872  ret void
873}
874
875; Same as test11 but with no use_pointer call. Delete the pair!
876
877; CHECK-LABEL: define void @test11a(
878; CHECK: entry:
879; CHECK-NEXT: ret void
880; CHECK: }
881define void @test11a(i8* %x) nounwind {
882entry:
883  %0 = call i8* @objc_retain(i8* %x) nounwind
884  call i8* @objc_autorelease(i8* %0) nounwind
885  ret void
886}
887
888; Same as test11 but the value is returned. Do not perform an RV optimization
889; since if the frontend emitted code for an __autoreleasing variable, we may
890; want it to be in the autorelease pool.
891
892; CHECK-LABEL: define i8* @test11b(
893; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
894; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]]
895; CHECK: }
896define i8* @test11b(i8* %x) nounwind {
897entry:
898  %0 = call i8* @objc_retain(i8* %x) nounwind
899  call i8* @objc_autorelease(i8* %0) nounwind
900  ret i8* %x
901}
902
903; We can not delete this retain, release since we do not have a post-dominating
904; use of the release.
905
906; CHECK-LABEL: define void @test12(
907; CHECK-NEXT: entry:
908; CHECK-NEXT: @objc_retain(i8* %x)
909; CHECK-NEXT: @objc_retain
910; CHECK: @objc_release
911; CHECK: }
912define void @test12(i8* %x, i64 %n) {
913entry:
914  call i8* @objc_retain(i8* %x) nounwind
915  call i8* @objc_retain(i8* %x) nounwind
916  call void @use_pointer(i8* %x)
917  call void @use_pointer(i8* %x)
918  call void @objc_release(i8* %x) nounwind
919  ret void
920}
921
922; Trivial retain,autorelease pair. Don't delete!
923
924; CHECK-LABEL: define void @test13(
925; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
926; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
927; CHECK: @use_pointer(i8* %x)
928; CHECK: call i8* @objc_autorelease(i8* %x) [[NUW]]
929; CHECK: }
930define void @test13(i8* %x, i64 %n) {
931entry:
932  call i8* @objc_retain(i8* %x) nounwind
933  call i8* @objc_retain(i8* %x) nounwind
934  call void @use_pointer(i8* %x)
935  call i8* @objc_autorelease(i8* %x) nounwind
936  ret void
937}
938
939; Delete the retain+release pair.
940
941; CHECK-LABEL: define void @test13b(
942; CHECK-NEXT: entry:
943; CHECK-NEXT: @objc_retain(i8* %x)
944; CHECK-NEXT: @use_pointer
945; CHECK-NEXT: @use_pointer
946; CHECK-NEXT: @use_pointer
947; CHECK-NEXT: @objc_release
948; CHECK-NEXT: ret void
949; CHECK-NEXT: }
950define void @test13b(i8* %x, i64 %n) {
951entry:
952  call i8* @objc_retain(i8* %x) nounwind
953  call i8* @objc_retain(i8* %x) nounwind
954  call void @use_pointer(i8* %x)
955  call void @use_pointer(i8* %x)
956  call void @objc_release(i8* %x) nounwind
957  call void @use_pointer(i8* %x)
958  call void @objc_release(i8* %x) nounwind
959  ret void
960}
961
962; Don't delete the retain+release pair because there's an
963; autoreleasePoolPop in the way.
964
965; CHECK-LABEL: define void @test13c(
966; CHECK: @objc_retain(i8* %x)
967; CHECK: @objc_autoreleasePoolPop
968; CHECK: @objc_retain(i8* %x)
969; CHECK: @use_pointer
970; CHECK: @objc_release
971; CHECK: }
972define void @test13c(i8* %x, i64 %n) {
973entry:
974  call i8* @objc_retain(i8* %x) nounwind
975  call void @objc_autoreleasePoolPop(i8* undef)
976  call i8* @objc_retain(i8* %x) nounwind
977  call void @use_pointer(i8* %x)
978  call void @use_pointer(i8* %x)
979  call void @objc_release(i8* %x) nounwind
980  ret void
981}
982
983; Like test13c, but there's an autoreleasePoolPush in the way, but that
984; doesn't matter.
985
986; CHECK-LABEL: define void @test13d(
987; CHECK-NEXT: entry:
988; CHECK-NEXT: @objc_retain(i8* %x)
989; CHECK-NEXT: @objc_autoreleasePoolPush
990; CHECK-NEXT: @use_pointer
991; CHECK-NEXT: @use_pointer
992; CHECK-NEXT: @use_pointer
993; CHECK-NEXT: @objc_release
994; CHECK-NEXT: ret void
995; CHECK-NEXT: }
996define void @test13d(i8* %x, i64 %n) {
997entry:
998  call i8* @objc_retain(i8* %x) nounwind
999  call i8* @objc_autoreleasePoolPush()
1000  call i8* @objc_retain(i8* %x) nounwind
1001  call void @use_pointer(i8* %x)
1002  call void @use_pointer(i8* %x)
1003  call void @objc_release(i8* %x) nounwind
1004  call void @use_pointer(i8* %x)
1005  call void @objc_release(i8* %x) nounwind
1006  ret void
1007}
1008
1009; Trivial retain,release pair with intervening call, and it's post-dominated by
1010; another release. But it is not known safe in the top down direction. We can
1011; not eliminate it.
1012
1013; CHECK-LABEL: define void @test14(
1014; CHECK-NEXT: entry:
1015; CHECK-NEXT: @objc_retain
1016; CHECK-NEXT: @use_pointer
1017; CHECK-NEXT: @use_pointer
1018; CHECK-NEXT: @objc_release
1019; CHECK-NEXT: @objc_release
1020; CHECK-NEXT: ret void
1021; CHECK-NEXT: }
1022define void @test14(i8* %x, i64 %n) {
1023entry:
1024  call i8* @objc_retain(i8* %x) nounwind
1025  call void @use_pointer(i8* %x)
1026  call void @use_pointer(i8* %x)
1027  call void @objc_release(i8* %x) nounwind
1028  call void @objc_release(i8* %x) nounwind
1029  ret void
1030}
1031
1032; Trivial retain,autorelease pair with intervening call, but it's post-dominated
1033; by another release. Don't delete anything.
1034
1035; CHECK-LABEL: define void @test15(
1036; CHECK-NEXT: entry:
1037; CHECK-NEXT: @objc_retain(i8* %x)
1038; CHECK-NEXT: @use_pointer
1039; CHECK-NEXT: @objc_autorelease(i8* %x)
1040; CHECK-NEXT: @objc_release
1041; CHECK-NEXT: ret void
1042; CHECK-NEXT: }
1043define void @test15(i8* %x, i64 %n) {
1044entry:
1045  call i8* @objc_retain(i8* %x) nounwind
1046  call void @use_pointer(i8* %x)
1047  call i8* @objc_autorelease(i8* %x) nounwind
1048  call void @objc_release(i8* %x) nounwind
1049  ret void
1050}
1051
1052; Trivial retain,autorelease pair, post-dominated
1053; by another release. Delete the retain and release.
1054
1055; CHECK-LABEL: define void @test15b(
1056; CHECK-NEXT: entry:
1057; CHECK-NEXT: @objc_retain
1058; CHECK-NEXT: @objc_autorelease
1059; CHECK-NEXT: @objc_release
1060; CHECK-NEXT: ret void
1061; CHECK-NEXT: }
1062define void @test15b(i8* %x, i64 %n) {
1063entry:
1064  call i8* @objc_retain(i8* %x) nounwind
1065  call i8* @objc_autorelease(i8* %x) nounwind
1066  call void @objc_release(i8* %x) nounwind
1067  ret void
1068}
1069
1070; CHECK-LABEL: define void @test15c(
1071; CHECK-NEXT: entry:
1072; CHECK-NEXT: @objc_autorelease
1073; CHECK-NEXT: ret void
1074; CHECK-NEXT: }
1075define void @test15c(i8* %x, i64 %n) {
1076entry:
1077  call i8* @objc_retain(i8* %x) nounwind
1078  call i8* @objc_autorelease(i8* %x) nounwind
1079  call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1080  ret void
1081}
1082
1083; Retain+release pairs in diamonds, all dominated by a retain.
1084
1085; CHECK-LABEL: define void @test16a(
1086; CHECK: @objc_retain(i8* %x)
1087; CHECK-NOT: @objc
1088; CHECK: purple:
1089; CHECK: @use_pointer
1090; CHECK: @objc_release
1091; CHECK: }
1092define void @test16a(i1 %a, i1 %b, i8* %x) {
1093entry:
1094  call i8* @objc_retain(i8* %x) nounwind
1095  br i1 %a, label %red, label %orange
1096
1097red:
1098  call i8* @objc_retain(i8* %x) nounwind
1099  br label %yellow
1100
1101orange:
1102  call i8* @objc_retain(i8* %x) nounwind
1103  br label %yellow
1104
1105yellow:
1106  call void @use_pointer(i8* %x)
1107  call void @use_pointer(i8* %x)
1108  br i1 %b, label %green, label %blue
1109
1110green:
1111  call void @objc_release(i8* %x) nounwind
1112  br label %purple
1113
1114blue:
1115  call void @objc_release(i8* %x) nounwind
1116  br label %purple
1117
1118purple:
1119  call void @use_pointer(i8* %x)
1120  call void @objc_release(i8* %x) nounwind
1121  ret void
1122}
1123
1124; CHECK-LABEL: define void @test16b(
1125; CHECK: @objc_retain(i8* %x)
1126; CHECK-NOT: @objc
1127; CHECK: purple:
1128; CHECK-NEXT: @use_pointer
1129; CHECK-NEXT: @use_pointer
1130; CHECK-NEXT: @objc_release
1131; CHECK: }
1132define void @test16b(i1 %a, i1 %b, i8* %x) {
1133entry:
1134  call i8* @objc_retain(i8* %x) nounwind
1135  br i1 %a, label %red, label %orange
1136
1137red:
1138  call i8* @objc_retain(i8* %x) nounwind
1139  br label %yellow
1140
1141orange:
1142  call i8* @objc_retain(i8* %x) nounwind
1143  br label %yellow
1144
1145yellow:
1146  call void @use_pointer(i8* %x)
1147  call void @use_pointer(i8* %x)
1148  br i1 %b, label %green, label %blue
1149
1150green:
1151  call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1152  br label %purple
1153
1154blue:
1155  call void @objc_release(i8* %x) nounwind
1156  br label %purple
1157
1158purple:
1159  call void @use_pointer(i8* %x)
1160  call void @use_pointer(i8* %x)
1161  call void @objc_release(i8* %x) nounwind
1162  ret void
1163}
1164
1165; CHECK-LABEL: define void @test16c(
1166; CHECK: @objc_retain(i8* %x)
1167; CHECK-NOT: @objc
1168; CHECK: purple:
1169; CHECK: @use_pointer
1170; CHECK: @objc_release
1171; CHECK: }
1172define void @test16c(i1 %a, i1 %b, i8* %x) {
1173entry:
1174  call i8* @objc_retain(i8* %x) nounwind
1175  br i1 %a, label %red, label %orange
1176
1177red:
1178  call i8* @objc_retain(i8* %x) nounwind
1179  br label %yellow
1180
1181orange:
1182  call i8* @objc_retain(i8* %x) nounwind
1183  br label %yellow
1184
1185yellow:
1186  call void @use_pointer(i8* %x)
1187  call void @use_pointer(i8* %x)
1188  br i1 %b, label %green, label %blue
1189
1190green:
1191  call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1192  br label %purple
1193
1194blue:
1195  call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1196  br label %purple
1197
1198purple:
1199  call void @use_pointer(i8* %x)
1200  call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1201  ret void
1202}
1203
1204; CHECK-LABEL: define void @test16d(
1205; CHECK: @objc_retain(i8* %x)
1206; CHECK: @objc
1207; CHECK: }
1208define void @test16d(i1 %a, i1 %b, i8* %x) {
1209entry:
1210  call i8* @objc_retain(i8* %x) nounwind
1211  br i1 %a, label %red, label %orange
1212
1213red:
1214  call i8* @objc_retain(i8* %x) nounwind
1215  br label %yellow
1216
1217orange:
1218  call i8* @objc_retain(i8* %x) nounwind
1219  br label %yellow
1220
1221yellow:
1222  call void @use_pointer(i8* %x)
1223  call void @use_pointer(i8* %x)
1224  br i1 %b, label %green, label %blue
1225
1226green:
1227  call void @objc_release(i8* %x) nounwind
1228  br label %purple
1229
1230blue:
1231  call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1232  br label %purple
1233
1234purple:
1235  ret void
1236}
1237
1238; Delete no-ops.
1239
1240; CHECK-LABEL: define void @test18(
1241; CHECK-NOT: @objc_
1242; CHECK: }
1243define void @test18() {
1244  call i8* @objc_retain(i8* null)
1245  call void @objc_release(i8* null)
1246  call i8* @objc_autorelease(i8* null)
1247  ret void
1248}
1249
1250; Delete no-ops where undef can be assumed to be null.
1251
1252; CHECK-LABEL: define void @test18b(
1253; CHECK-NOT: @objc_
1254; CHECK: }
1255define void @test18b() {
1256  call i8* @objc_retain(i8* undef)
1257  call void @objc_release(i8* undef)
1258  call i8* @objc_autorelease(i8* undef)
1259  ret void
1260}
1261
1262; Replace uses of arguments with uses of return values, to reduce
1263; register pressure.
1264
1265; CHECK: define void @test19(i32* %y) {
1266; CHECK:   %z = bitcast i32* %y to i8*
1267; CHECK:   %0 = bitcast i32* %y to i8*
1268; CHECK:   %1 = tail call i8* @objc_retain(i8* %0)
1269; CHECK:   call void @use_pointer(i8* %z)
1270; CHECK:   call void @use_pointer(i8* %z)
1271; CHECK:   %2 = bitcast i32* %y to i8*
1272; CHECK:   call void @objc_release(i8* %2)
1273; CHECK:   ret void
1274; CHECK: }
1275define void @test19(i32* %y) {
1276entry:
1277  %x = bitcast i32* %y to i8*
1278  %0 = call i8* @objc_retain(i8* %x) nounwind
1279  %z = bitcast i32* %y to i8*
1280  call void @use_pointer(i8* %z)
1281  call void @use_pointer(i8* %z)
1282  call void @objc_release(i8* %x)
1283  ret void
1284}
1285
1286; Bitcast insertion
1287
1288; CHECK-LABEL: define void @test20(
1289; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) [[NUW]]
1290; CHECK-NEXT: invoke
1291; CHECK: }
1292define void @test20(double* %self) personality i32 (...)* @__gxx_personality_v0 {
1293if.then12:
1294  %tmp = bitcast double* %self to i8*
1295  %tmp1 = call i8* @objc_retain(i8* %tmp) nounwind
1296  invoke void @invokee()
1297          to label %invoke.cont23 unwind label %lpad20
1298
1299invoke.cont23:                                    ; preds = %if.then12
1300  invoke void @invokee()
1301          to label %if.end unwind label %lpad20
1302
1303lpad20:                                           ; preds = %invoke.cont23, %if.then12
1304  %tmp502 = phi double* [ undef, %invoke.cont23 ], [ %self, %if.then12 ]
1305  %exn = landingpad {i8*, i32}
1306           cleanup
1307  unreachable
1308
1309if.end:                                           ; preds = %invoke.cont23
1310  ret void
1311}
1312
1313; Delete a redundant retain,autorelease when forwaring a call result
1314; directly to a return value.
1315
1316; CHECK-LABEL: define i8* @test21(
1317; CHECK: call i8* @returner()
1318; CHECK-NEXT: ret i8* %call
1319; CHECK-NEXT: }
1320define i8* @test21() {
1321entry:
1322  %call = call i8* @returner()
1323  %0 = call i8* @objc_retain(i8* %call) nounwind
1324  %1 = call i8* @objc_autorelease(i8* %0) nounwind
1325  ret i8* %1
1326}
1327
1328; Move an objc call up through a phi that has null operands.
1329
1330; CHECK-LABEL: define void @test22(
1331; CHECK: B:
1332; CHECK:   %1 = bitcast double* %p to i8*
1333; CHECK:   call void @objc_release(i8* %1)
1334; CHECK:   br label %C
1335; CHECK: C:                                                ; preds = %B, %A
1336; CHECK-NOT: @objc_release
1337; CHECK: }
1338define void @test22(double* %p, i1 %a) {
1339  br i1 %a, label %A, label %B
1340A:
1341  br label %C
1342B:
1343  br label %C
1344C:
1345  %h = phi double* [ null, %A ], [ %p, %B ]
1346  %c = bitcast double* %h to i8*
1347  call void @objc_release(i8* %c)
1348  ret void
1349}
1350
1351; Any call can decrement a retain count.
1352
1353; CHECK-LABEL: define void @test24(
1354; CHECK: @objc_retain(i8* %a)
1355; CHECK: @objc_release
1356; CHECK: }
1357define void @test24(i8* %r, i8* %a) {
1358  call i8* @objc_retain(i8* %a)
1359  call void @use_pointer(i8* %r)
1360  %q = load i8, i8* %a
1361  call void @objc_release(i8* %a)
1362  ret void
1363}
1364
1365; Don't move a retain/release pair if the release can be moved
1366; but the retain can't be moved to balance it.
1367
1368; CHECK-LABEL: define void @test25(
1369; CHECK: entry:
1370; CHECK:   call i8* @objc_retain(i8* %p)
1371; CHECK: true:
1372; CHECK: done:
1373; CHECK:   call void @objc_release(i8* %p)
1374; CHECK: }
1375define void @test25(i8* %p, i1 %x) {
1376entry:
1377  %f0 = call i8* @objc_retain(i8* %p)
1378  call void @callee()
1379  br i1 %x, label %true, label %done
1380
1381true:
1382  store i8 0, i8* %p
1383  br label %done
1384
1385done:
1386  call void @objc_release(i8* %p)
1387  ret void
1388}
1389
1390; Don't move a retain/release pair if the retain can be moved
1391; but the release can't be moved to balance it.
1392
1393; CHECK-LABEL: define void @test26(
1394; CHECK: entry:
1395; CHECK:   call i8* @objc_retain(i8* %p)
1396; CHECK: true:
1397; CHECK: done:
1398; CHECK:   call void @objc_release(i8* %p)
1399; CHECK: }
1400define void @test26(i8* %p, i1 %x) {
1401entry:
1402  %f0 = call i8* @objc_retain(i8* %p)
1403  br i1 %x, label %true, label %done
1404
1405true:
1406  call void @callee()
1407  br label %done
1408
1409done:
1410  store i8 0, i8* %p
1411  call void @objc_release(i8* %p)
1412  ret void
1413}
1414
1415; Don't sink the retain,release into the loop.
1416
1417; CHECK-LABEL: define void @test27(
1418; CHECK: entry:
1419; CHECK: call i8* @objc_retain(i8* %p)
1420; CHECK: loop:
1421; CHECK-NOT: @objc_
1422; CHECK: done:
1423; CHECK: call void @objc_release
1424; CHECK: }
1425define void @test27(i8* %p, i1 %x, i1 %y) {
1426entry:
1427  %f0 = call i8* @objc_retain(i8* %p)
1428  br i1 %x, label %loop, label %done
1429
1430loop:
1431  call void @callee()
1432  store i8 0, i8* %p
1433  br i1 %y, label %done, label %loop
1434
1435done:
1436  call void @objc_release(i8* %p)
1437  ret void
1438}
1439
1440; Trivial code motion case: Triangle.
1441
1442; CHECK-LABEL: define void @test28(
1443; CHECK-NOT: @objc_
1444; CHECK: true:
1445; CHECK: call i8* @objc_retain(
1446; CHECK: call void @callee()
1447; CHECK: store
1448; CHECK: call void @objc_release
1449; CHECK: done:
1450; CHECK-NOT: @objc_
1451; CHECK: }
1452define void @test28(i8* %p, i1 %x) {
1453entry:
1454  %f0 = call i8* @objc_retain(i8* %p)
1455  br i1 %x, label %true, label %done
1456
1457true:
1458  call void @callee()
1459  store i8 0, i8* %p
1460  br label %done
1461
1462done:
1463  call void @objc_release(i8* %p), !clang.imprecise_release !0
1464  ret void
1465}
1466
1467; Trivial code motion case: Triangle, but no metadata. Don't move past
1468; unrelated memory references!
1469
1470; CHECK-LABEL: define void @test28b(
1471; CHECK: call i8* @objc_retain(
1472; CHECK: true:
1473; CHECK-NOT: @objc_
1474; CHECK: call void @callee()
1475; CHECK-NOT: @objc_
1476; CHECK: store
1477; CHECK-NOT: @objc_
1478; CHECK: done:
1479; CHECK: @objc_release
1480; CHECK: }
1481define void @test28b(i8* %p, i1 %x, i8* noalias %t) {
1482entry:
1483  %f0 = call i8* @objc_retain(i8* %p)
1484  br i1 %x, label %true, label %done
1485
1486true:
1487  call void @callee()
1488  store i8 0, i8* %p
1489  br label %done
1490
1491done:
1492  store i8 0, i8* %t
1493  call void @objc_release(i8* %p)
1494  ret void
1495}
1496
1497; Trivial code motion case: Triangle, with metadata. Do move past
1498; unrelated memory references! And preserve the metadata.
1499
1500; CHECK-LABEL: define void @test28c(
1501; CHECK-NOT: @objc_
1502; CHECK: true:
1503; CHECK: call i8* @objc_retain(
1504; CHECK: call void @callee()
1505; CHECK: store
1506; CHECK: call void @objc_release(i8* %p) [[NUW]], !clang.imprecise_release
1507; CHECK: done:
1508; CHECK-NOT: @objc_
1509; CHECK: }
1510define void @test28c(i8* %p, i1 %x, i8* noalias %t) {
1511entry:
1512  %f0 = call i8* @objc_retain(i8* %p)
1513  br i1 %x, label %true, label %done
1514
1515true:
1516  call void @callee()
1517  store i8 0, i8* %p
1518  br label %done
1519
1520done:
1521  store i8 0, i8* %t
1522  call void @objc_release(i8* %p), !clang.imprecise_release !0
1523  ret void
1524}
1525
1526; Like test28. but with two releases.
1527
1528; CHECK-LABEL: define void @test29(
1529; CHECK-NOT: @objc_
1530; CHECK: true:
1531; CHECK: call i8* @objc_retain(
1532; CHECK: call void @callee()
1533; CHECK: store
1534; CHECK: call void @objc_release
1535; CHECK-NOT: @objc_release
1536; CHECK: done:
1537; CHECK-NOT: @objc_
1538; CHECK: ohno:
1539; CHECK-NOT: @objc_
1540; CHECK: }
1541define void @test29(i8* %p, i1 %x, i1 %y) {
1542entry:
1543  %f0 = call i8* @objc_retain(i8* %p)
1544  br i1 %x, label %true, label %done
1545
1546true:
1547  call void @callee()
1548  store i8 0, i8* %p
1549  br i1 %y, label %done, label %ohno
1550
1551done:
1552  call void @objc_release(i8* %p)
1553  ret void
1554
1555ohno:
1556  call void @objc_release(i8* %p)
1557  ret void
1558}
1559
1560; Basic case with the use and call in a diamond
1561; with an extra release.
1562
1563; CHECK-LABEL: define void @test30(
1564; CHECK-NOT: @objc_
1565; CHECK: true:
1566; CHECK: call i8* @objc_retain(
1567; CHECK: call void @callee()
1568; CHECK: store
1569; CHECK: call void @objc_release
1570; CHECK-NOT: @objc_release
1571; CHECK: false:
1572; CHECK-NOT: @objc_
1573; CHECK: done:
1574; CHECK-NOT: @objc_
1575; CHECK: ohno:
1576; CHECK-NOT: @objc_
1577; CHECK: }
1578define void @test30(i8* %p, i1 %x, i1 %y, i1 %z) {
1579entry:
1580  %f0 = call i8* @objc_retain(i8* %p)
1581  br i1 %x, label %true, label %false
1582
1583true:
1584  call void @callee()
1585  store i8 0, i8* %p
1586  br i1 %y, label %done, label %ohno
1587
1588false:
1589  br i1 %z, label %done, label %ohno
1590
1591done:
1592  call void @objc_release(i8* %p)
1593  ret void
1594
1595ohno:
1596  call void @objc_release(i8* %p)
1597  ret void
1598}
1599
1600; Basic case with a mergeable release.
1601
1602; CHECK-LABEL: define void @test31(
1603; CHECK: call i8* @objc_retain(i8* %p)
1604; CHECK: call void @callee()
1605; CHECK: store
1606; CHECK: call void @objc_release
1607; CHECK-NOT: @objc_release
1608; CHECK: true:
1609; CHECK-NOT: @objc_release
1610; CHECK: false:
1611; CHECK-NOT: @objc_release
1612; CHECK: ret void
1613; CHECK-NOT: @objc_release
1614; CHECK: }
1615define void @test31(i8* %p, i1 %x) {
1616entry:
1617  %f0 = call i8* @objc_retain(i8* %p)
1618  call void @callee()
1619  store i8 0, i8* %p
1620  br i1 %x, label %true, label %false
1621true:
1622  call void @objc_release(i8* %p)
1623  ret void
1624false:
1625  call void @objc_release(i8* %p)
1626  ret void
1627}
1628
1629; Don't consider bitcasts or getelementptrs direct uses.
1630
1631; CHECK-LABEL: define void @test32(
1632; CHECK-NOT: @objc_
1633; CHECK: true:
1634; CHECK: call i8* @objc_retain(
1635; CHECK: call void @callee()
1636; CHECK: store
1637; CHECK: call void @objc_release
1638; CHECK: done:
1639; CHECK-NOT: @objc_
1640; CHECK: }
1641define void @test32(i8* %p, i1 %x) {
1642entry:
1643  %f0 = call i8* @objc_retain(i8* %p)
1644  br i1 %x, label %true, label %done
1645
1646true:
1647  call void @callee()
1648  store i8 0, i8* %p
1649  br label %done
1650
1651done:
1652  %g = bitcast i8* %p to i8*
1653  %h = getelementptr i8, i8* %g, i64 0
1654  call void @objc_release(i8* %g)
1655  ret void
1656}
1657
1658; Do consider icmps to be direct uses.
1659
1660; CHECK-LABEL: define void @test33(
1661; CHECK-NOT: @objc_
1662; CHECK: true:
1663; CHECK: call i8* @objc_retain(
1664; CHECK: call void @callee()
1665; CHECK: icmp
1666; CHECK: call void @objc_release
1667; CHECK: done:
1668; CHECK-NOT: @objc_
1669; CHECK: }
1670define void @test33(i8* %p, i1 %x, i8* %y) {
1671entry:
1672  %f0 = call i8* @objc_retain(i8* %p)
1673  br i1 %x, label %true, label %done
1674
1675true:
1676  call void @callee()
1677  %v = icmp eq i8* %p, %y
1678  br label %done
1679
1680done:
1681  %g = bitcast i8* %p to i8*
1682  %h = getelementptr i8, i8* %g, i64 0
1683  call void @objc_release(i8* %g)
1684  ret void
1685}
1686
1687; Delete retain,release if there's just a possible dec and we have imprecise
1688; releases.
1689
1690; CHECK-LABEL: define void @test34a(
1691; CHECK:   call i8* @objc_retain
1692; CHECK: true:
1693; CHECK: done:
1694; CHECK: call void @objc_release
1695; CHECK: }
1696define void @test34a(i8* %p, i1 %x, i8* %y) {
1697entry:
1698  %f0 = call i8* @objc_retain(i8* %p)
1699  br i1 %x, label %true, label %done
1700
1701true:
1702  call void @callee()
1703  br label %done
1704
1705done:
1706  %g = bitcast i8* %p to i8*
1707  %h = getelementptr i8, i8* %g, i64 0
1708  call void @objc_release(i8* %g)
1709  ret void
1710}
1711
1712; CHECK-LABEL: define void @test34b(
1713; CHECK-NOT: @objc_
1714; CHECK: }
1715define void @test34b(i8* %p, i1 %x, i8* %y) {
1716entry:
1717  %f0 = call i8* @objc_retain(i8* %p)
1718  br i1 %x, label %true, label %done
1719
1720true:
1721  call void @callee()
1722  br label %done
1723
1724done:
1725  %g = bitcast i8* %p to i8*
1726  %h = getelementptr i8, i8* %g, i64 0
1727  call void @objc_release(i8* %g), !clang.imprecise_release !0
1728  ret void
1729}
1730
1731
1732; Delete retain,release if there's just a use and we do not have a precise
1733; release.
1734
1735; Precise.
1736; CHECK-LABEL: define void @test35a(
1737; CHECK: entry:
1738; CHECK:   call i8* @objc_retain
1739; CHECK: true:
1740; CHECK: done:
1741; CHECK:   call void @objc_release
1742; CHECK: }
1743define void @test35a(i8* %p, i1 %x, i8* %y) {
1744entry:
1745  %f0 = call i8* @objc_retain(i8* %p)
1746  br i1 %x, label %true, label %done
1747
1748true:
1749  %v = icmp eq i8* %p, %y
1750  br label %done
1751
1752done:
1753  %g = bitcast i8* %p to i8*
1754  %h = getelementptr i8, i8* %g, i64 0
1755  call void @objc_release(i8* %g)
1756  ret void
1757}
1758
1759; Imprecise.
1760; CHECK-LABEL: define void @test35b(
1761; CHECK-NOT: @objc_
1762; CHECK: }
1763define void @test35b(i8* %p, i1 %x, i8* %y) {
1764entry:
1765  %f0 = call i8* @objc_retain(i8* %p)
1766  br i1 %x, label %true, label %done
1767
1768true:
1769  %v = icmp eq i8* %p, %y
1770  br label %done
1771
1772done:
1773  %g = bitcast i8* %p to i8*
1774  %h = getelementptr i8, i8* %g, i64 0
1775  call void @objc_release(i8* %g), !clang.imprecise_release !0
1776  ret void
1777}
1778
1779; Delete a retain,release if there's no actual use and we have precise release.
1780
1781; CHECK-LABEL: define void @test36a(
1782; CHECK: @objc_retain
1783; CHECK: call void @callee()
1784; CHECK-NOT: @objc_
1785; CHECK: call void @callee()
1786; CHECK: @objc_release
1787; CHECK: }
1788define void @test36a(i8* %p) {
1789entry:
1790  call i8* @objc_retain(i8* %p)
1791  call void @callee()
1792  call void @callee()
1793  call void @objc_release(i8* %p)
1794  ret void
1795}
1796
1797; Like test36, but with metadata.
1798
1799; CHECK-LABEL: define void @test36b(
1800; CHECK-NOT: @objc_
1801; CHECK: }
1802define void @test36b(i8* %p) {
1803entry:
1804  call i8* @objc_retain(i8* %p)
1805  call void @callee()
1806  call void @callee()
1807  call void @objc_release(i8* %p), !clang.imprecise_release !0
1808  ret void
1809}
1810
1811; Be aggressive about analyzing phis to eliminate possible uses.
1812
1813; CHECK-LABEL: define void @test38(
1814; CHECK-NOT: @objc_
1815; CHECK: }
1816define void @test38(i8* %p, i1 %u, i1 %m, i8* %z, i8* %y, i8* %x, i8* %w) {
1817entry:
1818  call i8* @objc_retain(i8* %p)
1819  br i1 %u, label %true, label %false
1820true:
1821  br i1 %m, label %a, label %b
1822false:
1823  br i1 %m, label %c, label %d
1824a:
1825  br label %e
1826b:
1827  br label %e
1828c:
1829  br label %f
1830d:
1831  br label %f
1832e:
1833  %j = phi i8* [ %z, %a ], [ %y, %b ]
1834  br label %g
1835f:
1836  %k = phi i8* [ %w, %c ], [ %x, %d ]
1837  br label %g
1838g:
1839  %h = phi i8* [ %j, %e ], [ %k, %f ]
1840  call void @use_pointer(i8* %h)
1841  call void @objc_release(i8* %p), !clang.imprecise_release !0
1842  ret void
1843}
1844
1845; Delete retain,release pairs around loops.
1846
1847; CHECK-LABEL: define void @test39(
1848; CHECK-NOT: @objc_
1849; CHECK: }
1850define void @test39(i8* %p) {
1851entry:
1852  %0 = call i8* @objc_retain(i8* %p)
1853  br label %loop
1854
1855loop:                                             ; preds = %loop, %entry
1856  br i1 undef, label %loop, label %exit
1857
1858exit:                                             ; preds = %loop
1859  call void @objc_release(i8* %0), !clang.imprecise_release !0
1860  ret void
1861}
1862
1863; Delete retain,release pairs around loops containing uses.
1864
1865; CHECK-LABEL: define void @test39b(
1866; CHECK-NOT: @objc_
1867; CHECK: }
1868define void @test39b(i8* %p) {
1869entry:
1870  %0 = call i8* @objc_retain(i8* %p)
1871  br label %loop
1872
1873loop:                                             ; preds = %loop, %entry
1874  store i8 0, i8* %0
1875  br i1 undef, label %loop, label %exit
1876
1877exit:                                             ; preds = %loop
1878  call void @objc_release(i8* %0), !clang.imprecise_release !0
1879  ret void
1880}
1881
1882; Delete retain,release pairs around loops containing potential decrements.
1883
1884; CHECK-LABEL: define void @test39c(
1885; CHECK-NOT: @objc_
1886; CHECK: }
1887define void @test39c(i8* %p) {
1888entry:
1889  %0 = call i8* @objc_retain(i8* %p)
1890  br label %loop
1891
1892loop:                                             ; preds = %loop, %entry
1893  call void @use_pointer(i8* %0)
1894  br i1 undef, label %loop, label %exit
1895
1896exit:                                             ; preds = %loop
1897  call void @objc_release(i8* %0), !clang.imprecise_release !0
1898  ret void
1899}
1900
1901; Delete retain,release pairs around loops even if
1902; the successors are in a different order.
1903
1904; CHECK-LABEL: define void @test40(
1905; CHECK-NOT: @objc_
1906; CHECK: }
1907define void @test40(i8* %p) {
1908entry:
1909  %0 = call i8* @objc_retain(i8* %p)
1910  br label %loop
1911
1912loop:                                             ; preds = %loop, %entry
1913  call void @use_pointer(i8* %0)
1914  br i1 undef, label %exit, label %loop
1915
1916exit:                                             ; preds = %loop
1917  call void @objc_release(i8* %0), !clang.imprecise_release !0
1918  ret void
1919}
1920
1921; Do the known-incremented retain+release elimination even if the pointer
1922; is also autoreleased.
1923
1924; CHECK-LABEL: define void @test42(
1925; CHECK-NEXT: entry:
1926; CHECK-NEXT: call i8* @objc_retain(i8* %p)
1927; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
1928; CHECK-NEXT: call void @use_pointer(i8* %p)
1929; CHECK-NEXT: call void @use_pointer(i8* %p)
1930; CHECK-NEXT: call void @use_pointer(i8* %p)
1931; CHECK-NEXT: call void @use_pointer(i8* %p)
1932; CHECK-NEXT: call void @objc_release(i8* %p)
1933; CHECK-NEXT: ret void
1934; CHECK-NEXT: }
1935define void @test42(i8* %p) {
1936entry:
1937  call i8* @objc_retain(i8* %p)
1938  call i8* @objc_autorelease(i8* %p)
1939  call i8* @objc_retain(i8* %p)
1940  call void @use_pointer(i8* %p)
1941  call void @use_pointer(i8* %p)
1942  call void @objc_release(i8* %p)
1943  call void @use_pointer(i8* %p)
1944  call void @use_pointer(i8* %p)
1945  call void @objc_release(i8* %p)
1946  ret void
1947}
1948
1949; Don't the known-incremented retain+release elimination if the pointer is
1950; autoreleased and there's an autoreleasePoolPop.
1951
1952; CHECK-LABEL: define void @test43(
1953; CHECK-NEXT: entry:
1954; CHECK-NEXT: call i8* @objc_retain(i8* %p)
1955; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
1956; CHECK-NEXT: call i8* @objc_retain
1957; CHECK-NEXT: call void @use_pointer(i8* %p)
1958; CHECK-NEXT: call void @use_pointer(i8* %p)
1959; CHECK-NEXT: call void @objc_autoreleasePoolPop(i8* undef)
1960; CHECK-NEXT: call void @objc_release
1961; CHECK-NEXT: ret void
1962; CHECK-NEXT: }
1963define void @test43(i8* %p) {
1964entry:
1965  call i8* @objc_retain(i8* %p)
1966  call i8* @objc_autorelease(i8* %p)
1967  call i8* @objc_retain(i8* %p)
1968  call void @use_pointer(i8* %p)
1969  call void @use_pointer(i8* %p)
1970  call void @objc_autoreleasePoolPop(i8* undef)
1971  call void @objc_release(i8* %p)
1972  ret void
1973}
1974
1975; Do the known-incremented retain+release elimination if the pointer is
1976; autoreleased and there's an autoreleasePoolPush.
1977
1978; CHECK-LABEL: define void @test43b(
1979; CHECK-NEXT: entry:
1980; CHECK-NEXT: call i8* @objc_retain(i8* %p)
1981; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
1982; CHECK-NEXT: call void @use_pointer(i8* %p)
1983; CHECK-NEXT: call void @use_pointer(i8* %p)
1984; CHECK-NEXT: call i8* @objc_autoreleasePoolPush()
1985; CHECK-NEXT: call void @use_pointer(i8* %p)
1986; CHECK-NEXT: call void @objc_release
1987; CHECK-NEXT: ret void
1988; CHECK-NEXT: }
1989define void @test43b(i8* %p) {
1990entry:
1991  call i8* @objc_retain(i8* %p)
1992  call i8* @objc_autorelease(i8* %p)
1993  call i8* @objc_retain(i8* %p)
1994  call void @use_pointer(i8* %p)
1995  call void @use_pointer(i8* %p)
1996  call i8* @objc_autoreleasePoolPush()
1997  call void @objc_release(i8* %p)
1998  call void @use_pointer(i8* %p)
1999  call void @objc_release(i8* %p)
2000  ret void
2001}
2002
2003; Do retain+release elimination for non-provenance pointers.
2004
2005; CHECK-LABEL: define void @test44(
2006; CHECK-NOT: objc_
2007; CHECK: }
2008define void @test44(i8** %pp) {
2009  %p = load i8*, i8** %pp
2010  %q = call i8* @objc_retain(i8* %p)
2011  call void @objc_release(i8* %q)
2012  ret void
2013}
2014
2015; Don't delete retain+release with an unknown-provenance
2016; may-alias objc_release between them.
2017
2018; CHECK-LABEL: define void @test45(
2019; CHECK: call i8* @objc_retain(i8* %p)
2020; CHECK: call void @objc_release(i8* %q)
2021; CHECK: call void @use_pointer(i8* %p)
2022; CHECK: call void @objc_release(i8* %p)
2023; CHECK: }
2024define void @test45(i8** %pp, i8** %qq) {
2025  %p = load i8*, i8** %pp
2026  %q = load i8*, i8** %qq
2027  call i8* @objc_retain(i8* %p)
2028  call void @objc_release(i8* %q)
2029  call void @use_pointer(i8* %p)
2030  call void @objc_release(i8* %p)
2031  ret void
2032}
2033
2034; Don't delete retain and autorelease here.
2035
2036; CHECK-LABEL: define void @test46(
2037; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]]
2038; CHECK: true:
2039; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]]
2040; CHECK: }
2041define void @test46(i8* %p, i1 %a) {
2042entry:
2043  call i8* @objc_retain(i8* %p)
2044  br i1 %a, label %true, label %false
2045
2046true:
2047  call i8* @objc_autorelease(i8* %p)
2048  call void @use_pointer(i8* %p)
2049  ret void
2050
2051false:
2052  ret void
2053}
2054
2055; Delete no-op cast calls.
2056
2057; CHECK-LABEL: define i8* @test47(
2058; CHECK-NOT: call
2059; CHECK: ret i8* %p
2060; CHECK: }
2061define i8* @test47(i8* %p) nounwind {
2062  %x = call i8* @objc_retainedObject(i8* %p)
2063  ret i8* %x
2064}
2065
2066; Delete no-op cast calls.
2067
2068; CHECK-LABEL: define i8* @test48(
2069; CHECK-NOT: call
2070; CHECK: ret i8* %p
2071; CHECK: }
2072define i8* @test48(i8* %p) nounwind {
2073  %x = call i8* @objc_unretainedObject(i8* %p)
2074  ret i8* %x
2075}
2076
2077; Delete no-op cast calls.
2078
2079; CHECK-LABEL: define i8* @test49(
2080; CHECK-NOT: call
2081; CHECK: ret i8* %p
2082; CHECK: }
2083define i8* @test49(i8* %p) nounwind {
2084  %x = call i8* @objc_unretainedPointer(i8* %p)
2085  ret i8* %x
2086}
2087
2088; Do delete retain+release with intervening stores of the address value if we
2089; have imprecise release attached to objc_release.
2090
2091; CHECK-LABEL:      define void @test50a(
2092; CHECK-NEXT:   call i8* @objc_retain
2093; CHECK-NEXT:   call void @callee
2094; CHECK-NEXT:   store
2095; CHECK-NEXT:   call void @objc_release
2096; CHECK-NEXT:   ret void
2097; CHECK-NEXT: }
2098define void @test50a(i8* %p, i8** %pp) {
2099  call i8* @objc_retain(i8* %p)
2100  call void @callee()
2101  store i8* %p, i8** %pp
2102  call void @objc_release(i8* %p)
2103  ret void
2104}
2105
2106; CHECK-LABEL: define void @test50b(
2107; CHECK-NOT: @objc_
2108; CHECK: }
2109define void @test50b(i8* %p, i8** %pp) {
2110  call i8* @objc_retain(i8* %p)
2111  call void @callee()
2112  store i8* %p, i8** %pp
2113  call void @objc_release(i8* %p), !clang.imprecise_release !0
2114  ret void
2115}
2116
2117
2118; Don't delete retain+release with intervening stores through the
2119; address value.
2120
2121; CHECK-LABEL: define void @test51a(
2122; CHECK: call i8* @objc_retain(i8* %p)
2123; CHECK: call void @objc_release(i8* %p)
2124; CHECK: ret void
2125; CHECK: }
2126define void @test51a(i8* %p) {
2127  call i8* @objc_retain(i8* %p)
2128  call void @callee()
2129  store i8 0, i8* %p
2130  call void @objc_release(i8* %p)
2131  ret void
2132}
2133
2134; CHECK-LABEL: define void @test51b(
2135; CHECK: call i8* @objc_retain(i8* %p)
2136; CHECK: call void @objc_release(i8* %p)
2137; CHECK: ret void
2138; CHECK: }
2139define void @test51b(i8* %p) {
2140  call i8* @objc_retain(i8* %p)
2141  call void @callee()
2142  store i8 0, i8* %p
2143  call void @objc_release(i8* %p), !clang.imprecise_release !0
2144  ret void
2145}
2146
2147; Don't delete retain+release with intervening use of a pointer of
2148; unknown provenance.
2149
2150; CHECK-LABEL: define void @test52a(
2151; CHECK: call i8* @objc_retain
2152; CHECK: call void @callee()
2153; CHECK: call void @use_pointer(i8* %z)
2154; CHECK: call void @objc_release
2155; CHECK: ret void
2156; CHECK: }
2157define void @test52a(i8** %zz, i8** %pp) {
2158  %p = load i8*, i8** %pp
2159  %1 = call i8* @objc_retain(i8* %p)
2160  call void @callee()
2161  %z = load i8*, i8** %zz
2162  call void @use_pointer(i8* %z)
2163  call void @objc_release(i8* %p)
2164  ret void
2165}
2166
2167; CHECK-LABEL: define void @test52b(
2168; CHECK: call i8* @objc_retain
2169; CHECK: call void @callee()
2170; CHECK: call void @use_pointer(i8* %z)
2171; CHECK: call void @objc_release
2172; CHECK: ret void
2173; CHECK: }
2174define void @test52b(i8** %zz, i8** %pp) {
2175  %p = load i8*, i8** %pp
2176  %1 = call i8* @objc_retain(i8* %p)
2177  call void @callee()
2178  %z = load i8*, i8** %zz
2179  call void @use_pointer(i8* %z)
2180  call void @objc_release(i8* %p), !clang.imprecise_release !0
2181  ret void
2182}
2183
2184; Like test52, but the pointer has function type, so it's assumed to
2185; be not reference counted.
2186; Oops. That's wrong. Clang sometimes uses function types gratuitously.
2187; See rdar://10551239.
2188
2189; CHECK-LABEL: define void @test53(
2190; CHECK: @objc_
2191; CHECK: }
2192define void @test53(void ()** %zz, i8** %pp) {
2193  %p = load i8*, i8** %pp
2194  %1 = call i8* @objc_retain(i8* %p)
2195  call void @callee()
2196  %z = load void ()*, void ()** %zz
2197  call void @callee_fnptr(void ()* %z)
2198  call void @objc_release(i8* %p)
2199  ret void
2200}
2201
2202; Convert autorelease to release if the value is unused.
2203
2204; CHECK-LABEL: define void @test54(
2205; CHECK: call i8* @returner()
2206; CHECK-NEXT: call void @objc_release(i8* %t) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2207; CHECK-NEXT: ret void
2208; CHECK: }
2209define void @test54() {
2210  %t = call i8* @returner()
2211  call i8* @objc_autorelease(i8* %t)
2212  ret void
2213}
2214
2215; Nested retain+release pairs. Delete them both.
2216
2217; CHECK-LABEL: define void @test55(
2218; CHECK-NOT: @objc
2219; CHECK: }
2220define void @test55(i8* %x) {
2221entry:
2222  %0 = call i8* @objc_retain(i8* %x) nounwind
2223  %1 = call i8* @objc_retain(i8* %x) nounwind
2224  call void @objc_release(i8* %x) nounwind
2225  call void @objc_release(i8* %x) nounwind
2226  ret void
2227}
2228
2229; Nested retain+release pairs where the inner pair depends
2230; on the outer pair to be removed, and then the outer pair
2231; can be partially eliminated. Plus an extra outer pair to
2232; eliminate, for fun.
2233
2234; CHECK-LABEL: define void @test56(
2235; CHECK-NOT: @objc
2236; CHECK: if.then:
2237; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]]
2238; CHECK-NEXT: tail call void @use_pointer(i8* %x)
2239; CHECK-NEXT: tail call void @use_pointer(i8* %x)
2240; CHECK-NEXT: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2241; CHECK-NEXT: br label %if.end
2242; CHECK-NOT: @objc
2243; CHECK: }
2244define void @test56(i8* %x, i32 %n) {
2245entry:
2246  %0 = tail call i8* @objc_retain(i8* %x) nounwind
2247  %1 = tail call i8* @objc_retain(i8* %0) nounwind
2248  %tobool = icmp eq i32 %n, 0
2249  br i1 %tobool, label %if.end, label %if.then
2250
2251if.then:                                          ; preds = %entry
2252  %2 = tail call i8* @objc_retain(i8* %1) nounwind
2253  tail call void @use_pointer(i8* %2)
2254  tail call void @use_pointer(i8* %2)
2255  tail call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0
2256  br label %if.end
2257
2258if.end:                                           ; preds = %entry, %if.then
2259  tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
2260  tail call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
2261  ret void
2262}
2263
2264; When there are adjacent retain+release pairs, the first one is known
2265; unnecessary because the presence of the second one means that the first one
2266; won't be deleting the object.
2267
2268; CHECK-LABEL:      define void @test57(
2269; CHECK-NEXT: entry:
2270; CHECK-NEXT:   tail call i8* @objc_retain(i8* %x) [[NUW]]
2271; CHECK-NEXT:   call void @use_pointer(i8* %x)
2272; CHECK-NEXT:   call void @use_pointer(i8* %x)
2273; CHECK-NEXT:   tail call i8* @objc_retain(i8* %x) [[NUW]]
2274; CHECK-NEXT:   call void @use_pointer(i8* %x)
2275; CHECK-NEXT:   call void @use_pointer(i8* %x)
2276; CHECK-NEXT:   call void @objc_release(i8* %x) [[NUW]]
2277; CHECK-NEXT:   ret void
2278; CHECK-NEXT: }
2279define void @test57(i8* %x) nounwind {
2280entry:
2281  call i8* @objc_retain(i8* %x) nounwind
2282  call i8* @objc_retain(i8* %x) nounwind
2283  call void @use_pointer(i8* %x)
2284  call void @use_pointer(i8* %x)
2285  call void @objc_release(i8* %x) nounwind
2286  call i8* @objc_retain(i8* %x) nounwind
2287  call void @use_pointer(i8* %x)
2288  call void @use_pointer(i8* %x)
2289  call void @objc_release(i8* %x) nounwind
2290  ret void
2291}
2292
2293; An adjacent retain+release pair is sufficient even if it will be
2294; removed itself.
2295
2296; CHECK-LABEL:      define void @test58(
2297; CHECK-NEXT: entry:
2298; CHECK-NEXT:   @objc_retain
2299; CHECK-NEXT:   call void @use_pointer(i8* %x)
2300; CHECK-NEXT:   call void @use_pointer(i8* %x)
2301; CHECK-NEXT:   ret void
2302; CHECK-NEXT: }
2303define void @test58(i8* %x) nounwind {
2304entry:
2305  call i8* @objc_retain(i8* %x) nounwind
2306  call i8* @objc_retain(i8* %x) nounwind
2307  call void @use_pointer(i8* %x)
2308  call void @use_pointer(i8* %x)
2309  call void @objc_release(i8* %x) nounwind
2310  call i8* @objc_retain(i8* %x) nounwind
2311  call void @objc_release(i8* %x) nounwind
2312  ret void
2313}
2314
2315; Don't delete the second retain+release pair in an adjacent set.
2316
2317; CHECK-LABEL:      define void @test59(
2318; CHECK-NEXT: entry:
2319; CHECK-NEXT:   %0 = tail call i8* @objc_retain(i8* %x) [[NUW]]
2320; CHECK-NEXT:   call void @use_pointer(i8* %x)
2321; CHECK-NEXT:   call void @use_pointer(i8* %x)
2322; CHECK-NEXT:   call void @objc_release(i8* %x) [[NUW]]
2323; CHECK-NEXT:   ret void
2324; CHECK-NEXT: }
2325define void @test59(i8* %x) nounwind {
2326entry:
2327  %a = call i8* @objc_retain(i8* %x) nounwind
2328  call void @objc_release(i8* %x) nounwind
2329  %b = call i8* @objc_retain(i8* %x) nounwind
2330  call void @use_pointer(i8* %x)
2331  call void @use_pointer(i8* %x)
2332  call void @objc_release(i8* %x) nounwind
2333  ret void
2334}
2335
2336; Constant pointers to objects don't need reference counting.
2337
2338@constptr = external constant i8*
2339@something = external global i8*
2340
2341; We have a precise lifetime retain/release here. We can not remove them since
2342; @something is not constant.
2343
2344; CHECK-LABEL: define void @test60a(
2345; CHECK: call i8* @objc_retain
2346; CHECK: call void @objc_release
2347; CHECK: }
2348define void @test60a() {
2349  %t = load i8*, i8** @constptr
2350  %s = load i8*, i8** @something
2351  call i8* @objc_retain(i8* %s)
2352  call void @callee()
2353  call void @use_pointer(i8* %t)
2354  call void @objc_release(i8* %s)
2355  ret void
2356}
2357
2358; CHECK-LABEL: define void @test60b(
2359; CHECK: call i8* @objc_retain
2360; CHECK-NOT: call i8* @objc_retain
2361; CHECK-NOT: call i8* @objc_release
2362; CHECK: }
2363define void @test60b() {
2364  %t = load i8*, i8** @constptr
2365  %s = load i8*, i8** @something
2366  call i8* @objc_retain(i8* %t)
2367  call i8* @objc_retain(i8* %t)
2368  call void @callee()
2369  call void @use_pointer(i8* %s)
2370  call void @objc_release(i8* %t)
2371  ret void
2372}
2373
2374; CHECK-LABEL: define void @test60c(
2375; CHECK-NOT: @objc_
2376; CHECK: }
2377define void @test60c() {
2378  %t = load i8*, i8** @constptr
2379  %s = load i8*, i8** @something
2380  call i8* @objc_retain(i8* %t)
2381  call void @callee()
2382  call void @use_pointer(i8* %s)
2383  call void @objc_release(i8* %t), !clang.imprecise_release !0
2384  ret void
2385}
2386
2387; CHECK-LABEL: define void @test60d(
2388; CHECK-NOT: @objc_
2389; CHECK: }
2390define void @test60d() {
2391  %t = load i8*, i8** @constptr
2392  %s = load i8*, i8** @something
2393  call i8* @objc_retain(i8* %t)
2394  call void @callee()
2395  call void @use_pointer(i8* %s)
2396  call void @objc_release(i8* %t)
2397  ret void
2398}
2399
2400; CHECK-LABEL: define void @test60e(
2401; CHECK-NOT: @objc_
2402; CHECK: }
2403define void @test60e() {
2404  %t = load i8*, i8** @constptr
2405  %s = load i8*, i8** @something
2406  call i8* @objc_retain(i8* %t)
2407  call void @callee()
2408  call void @use_pointer(i8* %s)
2409  call void @objc_release(i8* %t), !clang.imprecise_release !0
2410  ret void
2411}
2412
2413; Constant pointers to objects don't need to be considered related to other
2414; pointers.
2415
2416; CHECK-LABEL: define void @test61(
2417; CHECK-NOT: @objc_
2418; CHECK: }
2419define void @test61() {
2420  %t = load i8*, i8** @constptr
2421  call i8* @objc_retain(i8* %t)
2422  call void @callee()
2423  call void @use_pointer(i8* %t)
2424  call void @objc_release(i8* %t)
2425  ret void
2426}
2427
2428; Delete a retain matched by releases when one is inside the loop and the
2429; other is outside the loop.
2430
2431; CHECK-LABEL: define void @test62(
2432; CHECK-NOT: @objc_
2433; CHECK: }
2434define void @test62(i8* %x, i1* %p) nounwind {
2435entry:
2436  br label %loop
2437
2438loop:
2439  call i8* @objc_retain(i8* %x)
2440  %q = load i1, i1* %p
2441  br i1 %q, label %loop.more, label %exit
2442
2443loop.more:
2444  call void @objc_release(i8* %x)
2445  br label %loop
2446
2447exit:
2448  call void @objc_release(i8* %x)
2449  ret void
2450}
2451
2452; Like test62 but with no release in exit.
2453; Don't delete anything!
2454
2455; CHECK-LABEL: define void @test63(
2456; CHECK: loop:
2457; CHECK:   tail call i8* @objc_retain(i8* %x)
2458; CHECK: loop.more:
2459; CHECK:   call void @objc_release(i8* %x)
2460; CHECK: }
2461define void @test63(i8* %x, i1* %p) nounwind {
2462entry:
2463  br label %loop
2464
2465loop:
2466  call i8* @objc_retain(i8* %x)
2467  %q = load i1, i1* %p
2468  br i1 %q, label %loop.more, label %exit
2469
2470loop.more:
2471  call void @objc_release(i8* %x)
2472  br label %loop
2473
2474exit:
2475  ret void
2476}
2477
2478; Like test62 but with no release in loop.more.
2479; Don't delete anything!
2480
2481; CHECK-LABEL: define void @test64(
2482; CHECK: loop:
2483; CHECK:   tail call i8* @objc_retain(i8* %x)
2484; CHECK: exit:
2485; CHECK:   call void @objc_release(i8* %x)
2486; CHECK: }
2487define void @test64(i8* %x, i1* %p) nounwind {
2488entry:
2489  br label %loop
2490
2491loop:
2492  call i8* @objc_retain(i8* %x)
2493  %q = load i1, i1* %p
2494  br i1 %q, label %loop.more, label %exit
2495
2496loop.more:
2497  br label %loop
2498
2499exit:
2500  call void @objc_release(i8* %x)
2501  ret void
2502}
2503
2504; Move an autorelease past a phi with a null.
2505
2506; CHECK-LABEL: define i8* @test65(
2507; CHECK: if.then:
2508; CHECK:   call i8* @objc_autorelease(
2509; CHECK: return:
2510; CHECK-NOT: @objc_autorelease
2511; CHECK: }
2512define i8* @test65(i1 %x) {
2513entry:
2514  br i1 %x, label %return, label %if.then
2515
2516if.then:                                          ; preds = %entry
2517  %c = call i8* @returner()
2518  %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
2519  br label %return
2520
2521return:                                           ; preds = %if.then, %entry
2522  %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2523  %q = call i8* @objc_autorelease(i8* %retval) nounwind
2524  ret i8* %retval
2525}
2526
2527; Don't move an autorelease past an autorelease pool boundary.
2528
2529; CHECK-LABEL: define i8* @test65b(
2530; CHECK: if.then:
2531; CHECK-NOT: @objc_autorelease
2532; CHECK: return:
2533; CHECK:   call i8* @objc_autorelease(
2534; CHECK: }
2535define i8* @test65b(i1 %x) {
2536entry:
2537  %t = call i8* @objc_autoreleasePoolPush()
2538  br i1 %x, label %return, label %if.then
2539
2540if.then:                                          ; preds = %entry
2541  %c = call i8* @returner()
2542  %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
2543  br label %return
2544
2545return:                                           ; preds = %if.then, %entry
2546  %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2547  call void @objc_autoreleasePoolPop(i8* %t)
2548  %q = call i8* @objc_autorelease(i8* %retval) nounwind
2549  ret i8* %retval
2550}
2551
2552; Don't move an autoreleaseReuturnValue, which would break
2553; the RV optimization.
2554
2555; CHECK-LABEL: define i8* @test65c(
2556; CHECK: if.then:
2557; CHECK-NOT: @objc_autorelease
2558; CHECK: return:
2559; CHECK:   call i8* @objc_autoreleaseReturnValue(
2560; CHECK: }
2561define i8* @test65c(i1 %x) {
2562entry:
2563  br i1 %x, label %return, label %if.then
2564
2565if.then:                                          ; preds = %entry
2566  %c = call i8* @returner()
2567  %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
2568  br label %return
2569
2570return:                                           ; preds = %if.then, %entry
2571  %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2572  %q = call i8* @objc_autoreleaseReturnValue(i8* %retval) nounwind
2573  ret i8* %retval
2574}
2575
2576; An objc_retain can serve as a may-use for a different pointer.
2577; rdar://11931823
2578
2579; CHECK-LABEL: define void @test66a(
2580; CHECK:   tail call i8* @objc_retain(i8* %cond) [[NUW]]
2581; CHECK:   tail call void @objc_release(i8* %call) [[NUW]]
2582; CHECK:   tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
2583; CHECK:   tail call void @objc_release(i8* %cond) [[NUW]]
2584; CHECK: }
2585define void @test66a(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2586entry:
2587  br i1 %tobool, label %cond.true, label %cond.end
2588
2589cond.true:
2590  br label %cond.end
2591
2592cond.end:                                         ; preds = %cond.true, %entry
2593  %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2594  %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind
2595  tail call void @objc_release(i8* %call) nounwind
2596  %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2597  %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind
2598  tail call void @objc_release(i8* %cond) nounwind
2599  ret void
2600}
2601
2602; CHECK-LABEL: define void @test66b(
2603; CHECK:   tail call i8* @objc_retain(i8* %cond) [[NUW]]
2604; CHECK:   tail call void @objc_release(i8* %call) [[NUW]]
2605; CHECK:   tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
2606; CHECK:   tail call void @objc_release(i8* %cond) [[NUW]]
2607; CHECK: }
2608define void @test66b(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2609entry:
2610  br i1 %tobool, label %cond.true, label %cond.end
2611
2612cond.true:
2613  br label %cond.end
2614
2615cond.end:                                         ; preds = %cond.true, %entry
2616  %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2617  %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind
2618  tail call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0
2619  %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2620  %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind
2621  tail call void @objc_release(i8* %cond) nounwind
2622  ret void
2623}
2624
2625; CHECK-LABEL: define void @test66c(
2626; CHECK:   tail call i8* @objc_retain(i8* %cond) [[NUW]]
2627; CHECK:   tail call void @objc_release(i8* %call) [[NUW]]
2628; CHECK:   tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
2629; CHECK:   tail call void @objc_release(i8* %cond) [[NUW]]
2630; CHECK: }
2631define void @test66c(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2632entry:
2633  br i1 %tobool, label %cond.true, label %cond.end
2634
2635cond.true:
2636  br label %cond.end
2637
2638cond.end:                                         ; preds = %cond.true, %entry
2639  %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2640  %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind
2641  tail call void @objc_release(i8* %call) nounwind
2642  %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2643  %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind, !clang.imprecise_release !0
2644  tail call void @objc_release(i8* %cond) nounwind
2645  ret void
2646}
2647
2648; CHECK-LABEL: define void @test66d(
2649; CHECK:   tail call i8* @objc_retain(i8* %cond) [[NUW]]
2650; CHECK:   tail call void @objc_release(i8* %call) [[NUW]]
2651; CHECK:   tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
2652; CHECK:   tail call void @objc_release(i8* %cond) [[NUW]]
2653; CHECK: }
2654define void @test66d(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2655entry:
2656  br i1 %tobool, label %cond.true, label %cond.end
2657
2658cond.true:
2659  br label %cond.end
2660
2661cond.end:                                         ; preds = %cond.true, %entry
2662  %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2663  %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind
2664  tail call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0
2665  %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2666  %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind
2667  tail call void @objc_release(i8* %cond) nounwind, !clang.imprecise_release !0
2668  ret void
2669}
2670
2671; A few real-world testcases.
2672
2673@.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
2674@"OBJC_IVAR_$_A.myZ" = global i64 20, section "__DATA, __objc_const", align 8
2675declare i32 @printf(i8* nocapture, ...) nounwind
2676declare i32 @puts(i8* nocapture) nounwind
2677@str = internal constant [16 x i8] c"-[ Top0 _getX ]\00"
2678
2679; CHECK: define { <2 x float>, <2 x float> } @"\01-[A z]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
2680; CHECK-NOT: @objc_
2681; CHECK: }
2682
2683define {<2 x float>, <2 x float>} @"\01-[A z]"({}* %self, i8* nocapture %_cmd) nounwind {
2684invoke.cont:
2685  %0 = bitcast {}* %self to i8*
2686  %1 = tail call i8* @objc_retain(i8* %0) nounwind
2687  tail call void @llvm.dbg.value(metadata {}* %self, i64 0, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2)
2688  tail call void @llvm.dbg.value(metadata {}* %self, i64 0, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2)
2689  %ivar = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8
2690  %add.ptr = getelementptr i8, i8* %0, i64 %ivar
2691  %tmp1 = bitcast i8* %add.ptr to float*
2692  %tmp2 = load float, float* %tmp1, align 4
2693  %conv = fpext float %tmp2 to double
2694  %add.ptr.sum = add i64 %ivar, 4
2695  %tmp6 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum
2696  %2 = bitcast i8* %tmp6 to float*
2697  %tmp7 = load float, float* %2, align 4
2698  %conv8 = fpext float %tmp7 to double
2699  %add.ptr.sum36 = add i64 %ivar, 8
2700  %tmp12 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum36
2701  %arrayidx = bitcast i8* %tmp12 to float*
2702  %tmp13 = load float, float* %arrayidx, align 4
2703  %conv14 = fpext float %tmp13 to double
2704  %tmp12.sum = add i64 %ivar, 12
2705  %arrayidx19 = getelementptr inbounds i8, i8* %0, i64 %tmp12.sum
2706  %3 = bitcast i8* %arrayidx19 to float*
2707  %tmp20 = load float, float* %3, align 4
2708  %conv21 = fpext float %tmp20 to double
2709  %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str4, i64 0, i64 0), double %conv, double %conv8, double %conv14, double %conv21)
2710  %ivar23 = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8
2711  %add.ptr24 = getelementptr i8, i8* %0, i64 %ivar23
2712  %4 = bitcast i8* %add.ptr24 to i128*
2713  %srcval = load i128, i128* %4, align 4
2714  tail call void @objc_release(i8* %0) nounwind
2715  %tmp29 = trunc i128 %srcval to i64
2716  %tmp30 = bitcast i64 %tmp29 to <2 x float>
2717  %tmp31 = insertvalue {<2 x float>, <2 x float>} undef, <2 x float> %tmp30, 0
2718  %tmp32 = lshr i128 %srcval, 64
2719  %tmp33 = trunc i128 %tmp32 to i64
2720  %tmp34 = bitcast i64 %tmp33 to <2 x float>
2721  %tmp35 = insertvalue {<2 x float>, <2 x float>} %tmp31, <2 x float> %tmp34, 1
2722  ret {<2 x float>, <2 x float>} %tmp35
2723}
2724
2725; CHECK: @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
2726; CHECK-NOT: @objc_
2727; CHECK: }
2728
2729define i32 @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) nounwind {
2730invoke.cont:
2731  %0 = bitcast {}* %self to i8*
2732  %1 = tail call i8* @objc_retain(i8* %0) nounwind
2733  %puts = tail call i32 @puts(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @str, i64 0, i64 0))
2734  tail call void @objc_release(i8* %0) nounwind
2735  ret i32 0
2736}
2737
2738@"\01L_OBJC_METH_VAR_NAME_" = internal global [5 x i8] c"frob\00", section "__TEXT,__cstring,cstring_literals", align 1@"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2739@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
2740@llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_" to i8*), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*)], section "llvm.metadata"
2741
2742; A simple loop. Eliminate the retain and release inside of it!
2743
2744; CHECK: define void @loop(i8* %x, i64 %n) {
2745; CHECK: for.body:
2746; CHECK-NOT: @objc_
2747; CHECK: @objc_msgSend
2748; CHECK-NOT: @objc_
2749; CHECK: for.end:
2750; CHECK: }
2751define void @loop(i8* %x, i64 %n) {
2752entry:
2753  %0 = tail call i8* @objc_retain(i8* %x) nounwind
2754  %cmp9 = icmp sgt i64 %n, 0
2755  br i1 %cmp9, label %for.body, label %for.end
2756
2757for.body:                                         ; preds = %entry, %for.body
2758  %i.010 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
2759  %1 = tail call i8* @objc_retain(i8* %x) nounwind
2760  %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
2761  %call = tail call i8* (i8*, i8*, ...) @objc_msgSend(i8* %1, i8* %tmp5)
2762  tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
2763  %inc = add nsw i64 %i.010, 1
2764  %exitcond = icmp eq i64 %inc, %n
2765  br i1 %exitcond, label %for.end, label %for.body
2766
2767for.end:                                          ; preds = %for.body, %entry
2768  tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
2769  ret void
2770}
2771
2772; ObjCARCOpt can delete the retain,release on self.
2773
2774; CHECK: define void @TextEditTest(%2* %self, %3* %pboard) {
2775; CHECK-NOT: call i8* @objc_retain(i8* %tmp7)
2776; CHECK: }
2777
2778%0 = type { i8* (i8*, %struct._message_ref_t*, ...)*, i8* }
2779%1 = type opaque
2780%2 = type opaque
2781%3 = type opaque
2782%4 = type opaque
2783%5 = type opaque
2784%struct.NSConstantString = type { i32*, i32, i8*, i64 }
2785%struct._NSRange = type { i64, i64 }
2786%struct.__CFString = type opaque
2787%struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] }
2788%struct._class_ro_t = type { i32, i32, i32, i8*, i8*, %struct.__method_list_t*, %struct._objc_protocol_list*, %struct._ivar_list_t*, i8*, %struct._prop_list_t* }
2789%struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* }
2790%struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] }
2791%struct._ivar_t = type { i64*, i8*, i8*, i32, i32 }
2792%struct._message_ref_t = type { i8*, i8* }
2793%struct._objc_cache = type opaque
2794%struct._objc_method = type { i8*, i8*, i8* }
2795%struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] }
2796%struct._prop_list_t = type { i32, i32, [0 x %struct._message_ref_t] }
2797%struct._protocol_t = type { i8*, i8*, %struct._objc_protocol_list*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct._prop_list_t*, i32, i32 }
2798
2799@"\01L_OBJC_CLASSLIST_REFERENCES_$_17" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2800@kUTTypePlainText = external constant %struct.__CFString*
2801@"\01L_OBJC_SELECTOR_REFERENCES_19" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2802@"\01L_OBJC_SELECTOR_REFERENCES_21" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2803@"\01L_OBJC_SELECTOR_REFERENCES_23" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2804@"\01L_OBJC_SELECTOR_REFERENCES_25" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2805@"\01L_OBJC_CLASSLIST_REFERENCES_$_26" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2806@"\01L_OBJC_SELECTOR_REFERENCES_28" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2807@"\01L_OBJC_CLASSLIST_REFERENCES_$_29" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2808@"\01L_OBJC_SELECTOR_REFERENCES_31" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2809@"\01L_OBJC_SELECTOR_REFERENCES_33" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2810@"\01L_OBJC_SELECTOR_REFERENCES_35" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2811@"\01L_OBJC_SELECTOR_REFERENCES_37" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2812@"\01L_OBJC_CLASSLIST_REFERENCES_$_38" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2813@"\01L_OBJC_SELECTOR_REFERENCES_40" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2814@"\01L_OBJC_SELECTOR_REFERENCES_42" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2815@_unnamed_cfstring_44 = external hidden constant %struct.NSConstantString, section "__DATA,__cfstring"
2816@"\01L_OBJC_SELECTOR_REFERENCES_46" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2817@"\01L_OBJC_SELECTOR_REFERENCES_48" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2818@"\01l_objc_msgSend_fixup_isEqual_" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16
2819@"\01L_OBJC_CLASSLIST_REFERENCES_$_50" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2820@NSCocoaErrorDomain = external constant %1*
2821@"\01L_OBJC_CLASSLIST_REFERENCES_$_51" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2822@NSFilePathErrorKey = external constant %1*
2823@"\01L_OBJC_SELECTOR_REFERENCES_53" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2824@"\01L_OBJC_SELECTOR_REFERENCES_55" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2825@"\01L_OBJC_CLASSLIST_REFERENCES_$_56" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2826@"\01L_OBJC_SELECTOR_REFERENCES_58" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2827@"\01L_OBJC_SELECTOR_REFERENCES_60" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2828
2829declare %1* @truncatedString(%1*, i64)
2830define void @TextEditTest(%2* %self, %3* %pboard) {
2831entry:
2832  %err = alloca %4*, align 8
2833  %tmp7 = bitcast %2* %self to i8*
2834  %tmp8 = call i8* @objc_retain(i8* %tmp7) nounwind
2835  store %4* null, %4** %err, align 8
2836  %tmp1 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_17", align 8
2837  %tmp2 = load %struct.__CFString*, %struct.__CFString** @kUTTypePlainText, align 8
2838  %tmp3 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_19", align 8
2839  %tmp4 = bitcast %struct._class_t* %tmp1 to i8*
2840  %call5 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp4, i8* %tmp3, %struct.__CFString* %tmp2)
2841  %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_21", align 8
2842  %tmp6 = bitcast %3* %pboard to i8*
2843  %call76 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp6, i8* %tmp5, i8* %call5)
2844  %tmp9 = call i8* @objc_retain(i8* %call76) nounwind
2845  %tobool = icmp eq i8* %tmp9, null
2846  br i1 %tobool, label %end, label %land.lhs.true
2847
2848land.lhs.true:                                    ; preds = %entry
2849  %tmp11 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_23", align 8
2850  %call137 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp6, i8* %tmp11, i8* %tmp9)
2851  %tmp = bitcast i8* %call137 to %1*
2852  %tmp10 = call i8* @objc_retain(i8* %call137) nounwind
2853  call void @objc_release(i8* null) nounwind
2854  %tmp12 = call i8* @objc_retain(i8* %call137) nounwind
2855  call void @objc_release(i8* null) nounwind
2856  %tobool16 = icmp eq i8* %call137, null
2857  br i1 %tobool16, label %end, label %if.then
2858
2859if.then:                                          ; preds = %land.lhs.true
2860  %tmp19 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2861  %call21 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %call137, i8* %tmp19)
2862  %tobool22 = icmp eq i8 %call21, 0
2863  br i1 %tobool22, label %if.then44, label %land.lhs.true23
2864
2865land.lhs.true23:                                  ; preds = %if.then
2866  %tmp24 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2867  %tmp26 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2868  %tmp27 = bitcast %struct._class_t* %tmp24 to i8*
2869  %call2822 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp27, i8* %tmp26, i8* %call137)
2870  %tmp13 = bitcast i8* %call2822 to %5*
2871  %tmp14 = call i8* @objc_retain(i8* %call2822) nounwind
2872  call void @objc_release(i8* null) nounwind
2873  %tobool30 = icmp eq i8* %call2822, null
2874  br i1 %tobool30, label %if.then44, label %if.end
2875
2876if.end:                                           ; preds = %land.lhs.true23
2877  %tmp32 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2878  %tmp33 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2879  %tmp34 = bitcast %struct._class_t* %tmp32 to i8*
2880  %call35 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp34, i8* %tmp33)
2881  %tmp37 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2882  %call3923 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call35, i8* %tmp37, i8* %call2822, i32 signext 1, %4** %err)
2883  %cmp = icmp eq i8* %call3923, null
2884  br i1 %cmp, label %if.then44, label %end
2885
2886if.then44:                                        ; preds = %if.end, %land.lhs.true23, %if.then
2887  %url.025 = phi %5* [ %tmp13, %if.end ], [ %tmp13, %land.lhs.true23 ], [ null, %if.then ]
2888  %tmp49 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_35", align 8
2889  %call51 = call %struct._NSRange bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct._NSRange (i8*, i8*, i64, i64)*)(i8* %call137, i8* %tmp49, i64 0, i64 0)
2890  %call513 = extractvalue %struct._NSRange %call51, 0
2891  %call514 = extractvalue %struct._NSRange %call51, 1
2892  %tmp52 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_37", align 8
2893  %call548 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call137, i8* %tmp52, i64 %call513, i64 %call514)
2894  %tmp55 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_38", align 8
2895  %tmp56 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_40", align 8
2896  %tmp57 = bitcast %struct._class_t* %tmp55 to i8*
2897  %call58 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp57, i8* %tmp56)
2898  %tmp59 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_42", align 8
2899  %call6110 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call548, i8* %tmp59, i8* %call58)
2900  %tmp15 = call i8* @objc_retain(i8* %call6110) nounwind
2901  call void @objc_release(i8* %call137) nounwind
2902  %tmp64 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_46", align 8
2903  %call66 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*, %1*)*)(i8* %call6110, i8* %tmp64, %1* bitcast (%struct.NSConstantString* @_unnamed_cfstring_44 to %1*))
2904  %tobool67 = icmp eq i8 %call66, 0
2905  br i1 %tobool67, label %if.end74, label %if.then68
2906
2907if.then68:                                        ; preds = %if.then44
2908  %tmp70 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_48", align 8
2909  %call7220 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call6110, i8* %tmp70)
2910  %tmp16 = call i8* @objc_retain(i8* %call7220) nounwind
2911  call void @objc_release(i8* %call6110) nounwind
2912  br label %if.end74
2913
2914if.end74:                                         ; preds = %if.then68, %if.then44
2915  %filename.0.in = phi i8* [ %call7220, %if.then68 ], [ %call6110, %if.then44 ]
2916  %filename.0 = bitcast i8* %filename.0.in to %1*
2917  %tmp17 = load i8*, i8** bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to i8**), align 16
2918  %tmp18 = bitcast i8* %tmp17 to i8 (i8*, %struct._message_ref_t*, i8*, ...)*
2919  %call78 = call signext i8 (i8*, %struct._message_ref_t*, i8*, ...) %tmp18(i8* %call137, %struct._message_ref_t* bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to %struct._message_ref_t*), i8* %filename.0.in)
2920  %tobool79 = icmp eq i8 %call78, 0
2921  br i1 %tobool79, label %land.lhs.true80, label %if.then109
2922
2923land.lhs.true80:                                  ; preds = %if.end74
2924  %tmp82 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2925  %call84 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %filename.0.in, i8* %tmp82)
2926  %tobool86 = icmp eq i8 %call84, 0
2927  br i1 %tobool86, label %if.then109, label %if.end106
2928
2929if.end106:                                        ; preds = %land.lhs.true80
2930  %tmp88 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2931  %tmp90 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2932  %tmp91 = bitcast %struct._class_t* %tmp88 to i8*
2933  %call9218 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp91, i8* %tmp90, i8* %filename.0.in)
2934  %tmp20 = bitcast i8* %call9218 to %5*
2935  %tmp21 = call i8* @objc_retain(i8* %call9218) nounwind
2936  %tmp22 = bitcast %5* %url.025 to i8*
2937  call void @objc_release(i8* %tmp22) nounwind
2938  %tmp94 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2939  %tmp95 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2940  %tmp96 = bitcast %struct._class_t* %tmp94 to i8*
2941  %call97 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp96, i8* %tmp95)
2942  %tmp99 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2943  %call10119 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call97, i8* %tmp99, i8* %call9218, i32 signext 1, %4** %err)
2944  %phitmp = icmp eq i8* %call10119, null
2945  br i1 %phitmp, label %if.then109, label %end
2946
2947if.then109:                                       ; preds = %if.end106, %land.lhs.true80, %if.end74
2948  %url.129 = phi %5* [ %tmp20, %if.end106 ], [ %url.025, %if.end74 ], [ %url.025, %land.lhs.true80 ]
2949  %tmp110 = load %4*, %4** %err, align 8
2950  %tobool111 = icmp eq %4* %tmp110, null
2951  br i1 %tobool111, label %if.then112, label %if.end125
2952
2953if.then112:                                       ; preds = %if.then109
2954  %tmp113 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_50", align 8
2955  %tmp114 = load %1*, %1** @NSCocoaErrorDomain, align 8
2956  %tmp115 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_51", align 8
2957  %call117 = call %1* @truncatedString(%1* %filename.0, i64 1034)
2958  %tmp118 = load %1*, %1** @NSFilePathErrorKey, align 8
2959  %tmp119 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_53", align 8
2960  %tmp120 = bitcast %struct._class_t* %tmp115 to i8*
2961  %call12113 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp120, i8* %tmp119, %1* %call117, %1* %tmp118, i8* null)
2962  %tmp122 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_55", align 8
2963  %tmp123 = bitcast %struct._class_t* %tmp113 to i8*
2964  %call12414 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp123, i8* %tmp122, %1* %tmp114, i64 258, i8* %call12113)
2965  %tmp23 = call i8* @objc_retain(i8* %call12414) nounwind
2966  %tmp25 = call i8* @objc_autorelease(i8* %tmp23) nounwind
2967  %tmp28 = bitcast i8* %tmp25 to %4*
2968  store %4* %tmp28, %4** %err, align 8
2969  br label %if.end125
2970
2971if.end125:                                        ; preds = %if.then112, %if.then109
2972  %tmp127 = phi %4* [ %tmp110, %if.then109 ], [ %tmp28, %if.then112 ]
2973  %tmp126 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_56", align 8
2974  %tmp128 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_58", align 8
2975  %tmp129 = bitcast %struct._class_t* %tmp126 to i8*
2976  %call13015 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp129, i8* %tmp128, %4* %tmp127)
2977  %tmp131 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_60", align 8
2978  %call13317 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call13015, i8* %tmp131)
2979  br label %end
2980
2981end:                                              ; preds = %if.end125, %if.end106, %if.end, %land.lhs.true, %entry
2982  %filename.2 = phi %1* [ %filename.0, %if.end106 ], [ %filename.0, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
2983  %origFilename.0 = phi %1* [ %tmp, %if.end106 ], [ %tmp, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
2984  %url.2 = phi %5* [ %tmp20, %if.end106 ], [ %url.129, %if.end125 ], [ null, %land.lhs.true ], [ null, %entry ], [ %tmp13, %if.end ]
2985  call void @objc_release(i8* %tmp9) nounwind, !clang.imprecise_release !0
2986  %tmp29 = bitcast %5* %url.2 to i8*
2987  call void @objc_release(i8* %tmp29) nounwind, !clang.imprecise_release !0
2988  %tmp30 = bitcast %1* %origFilename.0 to i8*
2989  call void @objc_release(i8* %tmp30) nounwind, !clang.imprecise_release !0
2990  %tmp31 = bitcast %1* %filename.2 to i8*
2991  call void @objc_release(i8* %tmp31) nounwind, !clang.imprecise_release !0
2992  call void @objc_release(i8* %tmp7) nounwind, !clang.imprecise_release !0
2993  ret void
2994}
2995
2996declare i32 @__gxx_personality_v0(...)
2997
2998declare i32 @objc_sync_enter(i8*)
2999declare i32 @objc_sync_exit(i8*)
3000
3001; Make sure that we understand that objc_sync_{enter,exit} are IC_User not
3002; IC_Call/IC_CallOrUser.
3003
3004; CHECK-LABEL:      define void @test67(
3005; CHECK-NEXT:   call i32 @objc_sync_enter(i8* %x)
3006; CHECK-NEXT:   call i32 @objc_sync_exit(i8* %x)
3007; CHECK-NEXT:   ret void
3008; CHECK-NEXT: }
3009define void @test67(i8* %x) {
3010  call i8* @objc_retain(i8* %x)
3011  call i32 @objc_sync_enter(i8* %x)
3012  call i32 @objc_sync_exit(i8* %x)
3013  call void @objc_release(i8* %x), !clang.imprecise_release !0
3014  ret void
3015}
3016
3017!llvm.module.flags = !{!1}
3018
3019!0 = !{}
3020!1 = !{i32 1, !"Debug Info Version", i32 3}
3021!2 = distinct !DISubprogram()
3022
3023; CHECK: attributes #0 = { nounwind readnone }
3024; CHECK: attributes [[NUW]] = { nounwind }
3025; CHECK: ![[RELEASE]] = !{}
3026