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