• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -objc-arc -S < %s | FileCheck %s
2
3target datalayout = "e-p:64:64:64"
4
5declare i8* @objc_retain(i8*)
6declare i8* @objc_retainAutoreleasedReturnValue(i8*)
7declare void @objc_release(i8*)
8declare i8* @objc_autorelease(i8*)
9declare i8* @objc_autoreleaseReturnValue(i8*)
10declare void @objc_autoreleasePoolPop(i8*)
11declare i8* @objc_autoreleasePoolPush()
12declare i8* @objc_retainBlock(i8*)
13
14declare i8* @objc_retainedObject(i8*)
15declare i8* @objc_unretainedObject(i8*)
16declare i8* @objc_unretainedPointer(i8*)
17
18declare void @use_pointer(i8*)
19declare void @callee()
20declare void @callee_fnptr(void ()*)
21declare void @invokee()
22declare i8* @returner()
23
24declare void @llvm.dbg.value(metadata, i64, metadata)
25
26declare i8* @objc_msgSend(i8*, i8*, ...)
27
28; Simple retain+release pair deletion, with some intervening control
29; flow and harmless instructions.
30
31; CHECK: define void @test0(
32; CHECK-NOT: @objc_
33; CHECK: }
34define void @test0(i32* %x, i1 %p) nounwind {
35entry:
36  %a = bitcast i32* %x to i8*
37  %0 = call i8* @objc_retain(i8* %a) nounwind
38  br i1 %p, label %t, label %f
39
40t:
41  store i8 3, i8* %a
42  %b = bitcast i32* %x to float*
43  store float 2.0, float* %b
44  br label %return
45
46f:
47  store i32 7, i32* %x
48  br label %return
49
50return:
51  %c = bitcast i32* %x to i8*
52  call void @objc_release(i8* %c) nounwind
53  ret void
54}
55
56; Like test0 but the release isn't always executed when the retain is,
57; so the optimization is not safe.
58
59; TODO: Make the objc_release's argument be %0.
60
61; CHECK: define void @test1(
62; CHECK: @objc_retain(i8* %a)
63; CHECK: @objc_release
64; CHECK: }
65define void @test1(i32* %x, i1 %p, i1 %q) nounwind {
66entry:
67  %a = bitcast i32* %x to i8*
68  %0 = call i8* @objc_retain(i8* %a) nounwind
69  br i1 %p, label %t, label %f
70
71t:
72  store i8 3, i8* %a
73  %b = bitcast i32* %x to float*
74  store float 2.0, float* %b
75  br label %return
76
77f:
78  store i32 7, i32* %x
79  call void @callee()
80  br i1 %q, label %return, label %alt_return
81
82return:
83  %c = bitcast i32* %x to i8*
84  call void @objc_release(i8* %c) nounwind
85  ret void
86
87alt_return:
88  ret void
89}
90
91; Don't do partial elimination into two different CFG diamonds.
92
93; CHECK: define void @test1b(
94; CHECK: entry:
95; CHECK:   tail call i8* @objc_retain(i8* %x) nounwind
96; CHECK-NOT: @objc_
97; CHECK: if.end5:
98; CHECK:   tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
99; CHECK-NOT: @objc_
100; CHECK: }
101define void @test1b(i8* %x, i1 %p, i1 %q) {
102entry:
103  tail call i8* @objc_retain(i8* %x) nounwind
104  br i1 %p, label %if.then, label %if.end
105
106if.then:                                          ; preds = %entry
107  tail call void @callee()
108  br label %if.end
109
110if.end:                                           ; preds = %if.then, %entry
111  br i1 %q, label %if.then3, label %if.end5
112
113if.then3:                                         ; preds = %if.end
114  tail call void @use_pointer(i8* %x)
115  br label %if.end5
116
117if.end5:                                          ; preds = %if.then3, %if.end
118  tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
119  ret void
120}
121
122; Like test0 but the pointer is passed to an intervening call,
123; so the optimization is not safe.
124
125; CHECK: define void @test2(
126; CHECK: @objc_retain(i8* %a)
127; CHECK: @objc_release
128; CHECK: }
129define void @test2(i32* %x, i1 %p) nounwind {
130entry:
131  %a = bitcast i32* %x to i8*
132  %0 = call i8* @objc_retain(i8* %a) nounwind
133  br i1 %p, label %t, label %f
134
135t:
136  store i8 3, i8* %a
137  %b = bitcast i32* %x to float*
138  store float 2.0, float* %b
139  br label %return
140
141f:
142  store i32 7, i32* %x
143  call void @use_pointer(i8* %0)
144  %d = bitcast i32* %x to float*
145  store float 3.0, float* %d
146  br label %return
147
148return:
149  %c = bitcast i32* %x to i8*
150  call void @objc_release(i8* %c) nounwind
151  ret void
152}
153
154; Like test0 but the release is in a loop,
155; so the optimization is not safe.
156
157; TODO: For now, assume this can't happen.
158
159; CHECK: define void @test3(
160; TODO: @objc_retain(i8* %a)
161; TODO: @objc_release
162; CHECK: }
163define void @test3(i32* %x, i1* %q) nounwind {
164entry:
165  %a = bitcast i32* %x to i8*
166  %0 = call i8* @objc_retain(i8* %a) nounwind
167  br label %loop
168
169loop:
170  %c = bitcast i32* %x to i8*
171  call void @objc_release(i8* %c) nounwind
172  %j = load volatile i1* %q
173  br i1 %j, label %loop, label %return
174
175return:
176  ret void
177}
178
179; TODO: For now, assume this can't happen.
180
181; Like test0 but the retain is in a loop,
182; so the optimization is not safe.
183
184; CHECK: define void @test4(
185; TODO: @objc_retain(i8* %a)
186; TODO: @objc_release
187; CHECK: }
188define void @test4(i32* %x, i1* %q) nounwind {
189entry:
190  br label %loop
191
192loop:
193  %a = bitcast i32* %x to i8*
194  %0 = call i8* @objc_retain(i8* %a) nounwind
195  %j = load volatile i1* %q
196  br i1 %j, label %loop, label %return
197
198return:
199  %c = bitcast i32* %x to i8*
200  call void @objc_release(i8* %c) nounwind
201  ret void
202}
203
204; Like test0 but the pointer is conditionally passed to an intervening call,
205; so the optimization is not safe.
206
207; CHECK: define void @test5(
208; CHECK: @objc_retain(i8*
209; CHECK: @objc_release
210; CHECK: }
211define void @test5(i32* %x, i1 %q, i8* %y) nounwind {
212entry:
213  %a = bitcast i32* %x to i8*
214  %0 = call i8* @objc_retain(i8* %a) nounwind
215  %s = select i1 %q, i8* %y, i8* %0
216  call void @use_pointer(i8* %s)
217  store i32 7, i32* %x
218  %c = bitcast i32* %x to i8*
219  call void @objc_release(i8* %c) nounwind
220  ret void
221}
222
223; retain+release pair deletion, where the release happens on two different
224; flow paths.
225
226; CHECK: define void @test6(
227; CHECK-NOT: @objc_
228; CHECK: }
229define void @test6(i32* %x, i1 %p) nounwind {
230entry:
231  %a = bitcast i32* %x to i8*
232  %0 = call i8* @objc_retain(i8* %a) nounwind
233  br i1 %p, label %t, label %f
234
235t:
236  store i8 3, i8* %a
237  %b = bitcast i32* %x to float*
238  store float 2.0, float* %b
239  %ct = bitcast i32* %x to i8*
240  call void @objc_release(i8* %ct) nounwind
241  br label %return
242
243f:
244  store i32 7, i32* %x
245  call void @callee()
246  %cf = bitcast i32* %x to i8*
247  call void @objc_release(i8* %cf) nounwind
248  br label %return
249
250return:
251  ret void
252}
253
254; retain+release pair deletion, where the retain happens on two different
255; flow paths.
256
257; CHECK: define void @test7(
258; CHECK-NOT: @objc_
259; CHECK: }
260define void @test7(i32* %x, i1 %p) nounwind {
261entry:
262  %a = bitcast i32* %x to i8*
263  br i1 %p, label %t, label %f
264
265t:
266  %0 = call i8* @objc_retain(i8* %a) nounwind
267  store i8 3, i8* %a
268  %b = bitcast i32* %x to float*
269  store float 2.0, float* %b
270  br label %return
271
272f:
273  %1 = call i8* @objc_retain(i8* %a) nounwind
274  store i32 7, i32* %x
275  call void @callee()
276  br label %return
277
278return:
279  %c = bitcast i32* %x to i8*
280  call void @objc_release(i8* %c) nounwind
281  ret void
282}
283
284; Like test7, but there's a retain/retainBlock mismatch. Don't delete!
285
286; CHECK: define void @test7b
287; CHECK: t:
288; CHECK: call i8* @objc_retainBlock
289; CHECK: f:
290; CHECK: call i8* @objc_retain
291; CHECK: return:
292; CHECK: call void @objc_release
293; CHECK: }
294define void @test7b(i32* %x, i1 %p) nounwind {
295entry:
296  %a = bitcast i32* %x to i8*
297  br i1 %p, label %t, label %f
298
299t:
300  %0 = call i8* @objc_retainBlock(i8* %a) nounwind
301  store i8 3, i8* %a
302  %b = bitcast i32* %x to float*
303  store float 2.0, float* %b
304  br label %return
305
306f:
307  %1 = call i8* @objc_retain(i8* %a) nounwind
308  store i32 7, i32* %x
309  call void @callee()
310  br label %return
311
312return:
313  %c = bitcast i32* %x to i8*
314  call void @objc_release(i8* %c) nounwind
315  ret void
316}
317
318; retain+release pair deletion, where the retain and release both happen on
319; different flow paths. Wild!
320
321; CHECK: define void @test8(
322; CHECK-NOT: @objc_
323; CHECK: }
324define void @test8(i32* %x, i1 %p, i1 %q) nounwind {
325entry:
326  %a = bitcast i32* %x to i8*
327  br i1 %p, label %t, label %f
328
329t:
330  %0 = call i8* @objc_retain(i8* %a) nounwind
331  store i8 3, i8* %a
332  %b = bitcast i32* %x to float*
333  store float 2.0, float* %b
334  br label %mid
335
336f:
337  %1 = call i8* @objc_retain(i8* %a) nounwind
338  store i32 7, i32* %x
339  br label %mid
340
341mid:
342  br i1 %q, label %u, label %g
343
344u:
345  call void @callee()
346  %cu = bitcast i32* %x to i8*
347  call void @objc_release(i8* %cu) nounwind
348  br label %return
349
350g:
351  %cg = bitcast i32* %x to i8*
352  call void @objc_release(i8* %cg) nounwind
353  br label %return
354
355return:
356  ret void
357}
358
359; Trivial retain+release pair deletion.
360
361; CHECK: define void @test9(
362; CHECK-NOT: @objc_
363; CHECK: }
364define void @test9(i8* %x) nounwind {
365entry:
366  %0 = call i8* @objc_retain(i8* %x) nounwind
367  call void @objc_release(i8* %0) nounwind
368  ret void
369}
370
371; Retain+release pair, but on an unknown pointer relationship. Don't delete!
372
373; CHECK: define void @test9b
374; CHECK: @objc_retain(i8* %x)
375; CHECK: @objc_release(i8* %s)
376; CHECK: }
377define void @test9b(i8* %x, i1 %j, i8* %p) nounwind {
378entry:
379  %0 = call i8* @objc_retain(i8* %x) nounwind
380  %s = select i1 %j, i8* %x, i8* %p
381  call void @objc_release(i8* %s) nounwind
382  ret void
383}
384
385; Trivial retain+release pair with intervening calls - don't delete!
386
387; CHECK: define void @test10(
388; CHECK: @objc_retain(i8* %x)
389; CHECK: @callee
390; CHECK: @use_pointer
391; CHECK: @objc_release
392; CHECK: }
393define void @test10(i8* %x) nounwind {
394entry:
395  %0 = call i8* @objc_retain(i8* %x) nounwind
396  call void @callee()
397  call void @use_pointer(i8* %x)
398  call void @objc_release(i8* %0) nounwind
399  ret void
400}
401
402; Trivial retain+autoreleaserelease pair. Don't delete!
403; Also, add a tail keyword, since objc_retain can never be passed
404; a stack argument.
405
406; CHECK: define void @test11(
407; CHECK: tail call i8* @objc_retain(i8* %x) nounwind
408; CHECK: tail call i8* @objc_autorelease(i8* %0) nounwind
409; CHECK: }
410define void @test11(i8* %x) nounwind {
411entry:
412  %0 = call i8* @objc_retain(i8* %x) nounwind
413  call i8* @objc_autorelease(i8* %0) nounwind
414  call void @use_pointer(i8* %x)
415  ret void
416}
417
418; Same as test11 but with no use_pointer call. Delete the pair!
419
420; CHECK: define void @test11a(
421; CHECK: entry:
422; CHECK-NEXT: ret void
423; CHECK: }
424define void @test11a(i8* %x) nounwind {
425entry:
426  %0 = call i8* @objc_retain(i8* %x) nounwind
427  call i8* @objc_autorelease(i8* %0) nounwind
428  ret void
429}
430
431; Same as test11 but the value is returned. Do an RV optimization.
432
433; CHECK: define i8* @test11b(
434; CHECK: tail call i8* @objc_retain(i8* %x) nounwind
435; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %0) nounwind
436; CHECK: }
437define i8* @test11b(i8* %x) nounwind {
438entry:
439  %0 = call i8* @objc_retain(i8* %x) nounwind
440  call i8* @objc_autorelease(i8* %0) nounwind
441  ret i8* %x
442}
443
444; Trivial retain,release pair with intervening call, but it's dominated
445; by another retain - delete!
446
447; CHECK: define void @test12(
448; CHECK-NEXT: entry:
449; CHECK-NEXT: @objc_retain(i8* %x)
450; CHECK-NOT: @objc_
451; CHECK: }
452define void @test12(i8* %x, i64 %n) {
453entry:
454  call i8* @objc_retain(i8* %x) nounwind
455  call i8* @objc_retain(i8* %x) nounwind
456  call void @use_pointer(i8* %x)
457  call void @use_pointer(i8* %x)
458  call void @objc_release(i8* %x) nounwind
459  ret void
460}
461
462; Trivial retain,autorelease pair. Don't delete!
463
464; CHECK: define void @test13(
465; CHECK: tail call i8* @objc_retain(i8* %x) nounwind
466; CHECK: tail call i8* @objc_retain(i8* %x) nounwind
467; CHECK: @use_pointer(i8* %x)
468; CHECK: tail call i8* @objc_autorelease(i8* %x) nounwind
469; CHECK: }
470define void @test13(i8* %x, i64 %n) {
471entry:
472  call i8* @objc_retain(i8* %x) nounwind
473  call i8* @objc_retain(i8* %x) nounwind
474  call void @use_pointer(i8* %x)
475  call i8* @objc_autorelease(i8* %x) nounwind
476  ret void
477}
478
479; Delete the retain+release pair.
480
481; CHECK: define void @test13b
482; CHECK-NEXT: entry:
483; CHECK-NEXT: @objc_retain(i8* %x)
484; CHECK-NEXT: @use_pointer
485; CHECK-NEXT: @use_pointer
486; CHECK-NEXT: ret void
487define void @test13b(i8* %x, i64 %n) {
488entry:
489  call i8* @objc_retain(i8* %x) nounwind
490  call i8* @objc_retain(i8* %x) nounwind
491  call void @use_pointer(i8* %x)
492  call void @use_pointer(i8* %x)
493  call void @objc_release(i8* %x) nounwind
494  ret void
495}
496
497; Don't delete the retain+release pair because there's an
498; autoreleasePoolPop in the way.
499
500; CHECK: define void @test13c
501; CHECK: @objc_retain(i8* %x)
502; CHECK: @objc_autoreleasePoolPop
503; CHECK: @objc_retain(i8* %x)
504; CHECK: @use_pointer
505; CHECK: @objc_release
506; CHECK: }
507define void @test13c(i8* %x, i64 %n) {
508entry:
509  call i8* @objc_retain(i8* %x) nounwind
510  call void @objc_autoreleasePoolPop(i8* undef)
511  call i8* @objc_retain(i8* %x) nounwind
512  call void @use_pointer(i8* %x)
513  call void @use_pointer(i8* %x)
514  call void @objc_release(i8* %x) nounwind
515  ret void
516}
517
518; Like test13c, but there's an autoreleasePoolPush in the way, but that
519; doesn't matter.
520
521; CHECK: define void @test13d
522; CHECK-NEXT: entry:
523; CHECK-NEXT: @objc_retain(i8* %x)
524; CHECK-NEXT: @objc_autoreleasePoolPush
525; CHECK-NEXT: @use_pointer
526; CHECK-NEXT: @use_pointer
527; CHECK-NEXT: ret void
528define void @test13d(i8* %x, i64 %n) {
529entry:
530  call i8* @objc_retain(i8* %x) nounwind
531  call i8* @objc_autoreleasePoolPush()
532  call i8* @objc_retain(i8* %x) nounwind
533  call void @use_pointer(i8* %x)
534  call void @use_pointer(i8* %x)
535  call void @objc_release(i8* %x) nounwind
536  ret void
537}
538
539; Trivial retain,release pair with intervening call, but it's post-dominated
540; by another release - delete!
541
542; CHECK: define void @test14(
543; CHECK-NEXT: entry:
544; CHECK-NEXT: @use_pointer
545; CHECK-NEXT: @use_pointer
546; CHECK-NEXT: @objc_release
547; CHECK-NEXT: ret void
548; CHECK-NEXT: }
549define void @test14(i8* %x, i64 %n) {
550entry:
551  call i8* @objc_retain(i8* %x) nounwind
552  call void @use_pointer(i8* %x)
553  call void @use_pointer(i8* %x)
554  call void @objc_release(i8* %x) nounwind
555  call void @objc_release(i8* %x) nounwind
556  ret void
557}
558
559; Trivial retain,autorelease pair with intervening call, but it's post-dominated
560; by another release. Don't delete anything.
561
562; CHECK: define void @test15(
563; CHECK-NEXT: entry:
564; CHECK-NEXT: @objc_retain(i8* %x)
565; CHECK-NEXT: @use_pointer
566; CHECK-NEXT: @objc_autorelease(i8* %x)
567; CHECK-NEXT: @objc_release
568; CHECK-NEXT: ret void
569; CHECK-NEXT: }
570define void @test15(i8* %x, i64 %n) {
571entry:
572  call i8* @objc_retain(i8* %x) nounwind
573  call void @use_pointer(i8* %x)
574  call i8* @objc_autorelease(i8* %x) nounwind
575  call void @objc_release(i8* %x) nounwind
576  ret void
577}
578
579; Trivial retain,autorelease pair, post-dominated
580; by another release. Delete the retain and release.
581
582; CHECK: define void @test15b
583; CHECK-NEXT: entry:
584; CHECK-NEXT: @objc_autorelease
585; CHECK-NEXT: ret void
586; CHECK-NEXT: }
587define void @test15b(i8* %x, i64 %n) {
588entry:
589  call i8* @objc_retain(i8* %x) nounwind
590  call i8* @objc_autorelease(i8* %x) nounwind
591  call void @objc_release(i8* %x) nounwind
592  ret void
593}
594
595; Retain+release pairs in diamonds, all dominated by a retain.
596
597; CHECK: define void @test16(
598; CHECK: @objc_retain(i8* %x)
599; CHECK-NOT: @objc
600; CHECK: }
601define void @test16(i1 %a, i1 %b, i8* %x) {
602entry:
603  call i8* @objc_retain(i8* %x) nounwind
604  br i1 %a, label %red, label %orange
605
606red:
607  call i8* @objc_retain(i8* %x) nounwind
608  br label %yellow
609
610orange:
611  call i8* @objc_retain(i8* %x) nounwind
612  br label %yellow
613
614yellow:
615  call void @use_pointer(i8* %x)
616  call void @use_pointer(i8* %x)
617  br i1 %b, label %green, label %blue
618
619green:
620  call void @objc_release(i8* %x) nounwind
621  br label %purple
622
623blue:
624  call void @objc_release(i8* %x) nounwind
625  br label %purple
626
627purple:
628  ret void
629}
630
631; Retain+release pairs in diamonds, all post-dominated by a release.
632
633; CHECK: define void @test17(
634; CHECK-NOT: @objc_
635; CHECK: purple:
636; CHECK: @objc_release
637; CHECK: }
638define void @test17(i1 %a, i1 %b, i8* %x) {
639entry:
640  br i1 %a, label %red, label %orange
641
642red:
643  call i8* @objc_retain(i8* %x) nounwind
644  br label %yellow
645
646orange:
647  call i8* @objc_retain(i8* %x) nounwind
648  br label %yellow
649
650yellow:
651  call void @use_pointer(i8* %x)
652  call void @use_pointer(i8* %x)
653  br i1 %b, label %green, label %blue
654
655green:
656  call void @objc_release(i8* %x) nounwind
657  br label %purple
658
659blue:
660  call void @objc_release(i8* %x) nounwind
661  br label %purple
662
663purple:
664  call void @objc_release(i8* %x) nounwind
665  ret void
666}
667
668; Delete no-ops.
669
670; CHECK: define void @test18(
671; CHECK-NOT: @objc_
672; CHECK: }
673define void @test18() {
674  call i8* @objc_retain(i8* null)
675  call void @objc_release(i8* null)
676  call i8* @objc_autorelease(i8* null)
677  ret void
678}
679
680; Delete no-ops where undef can be assumed to be null.
681
682; CHECK: define void @test18b
683; CHECK-NOT: @objc_
684; CHECK: }
685define void @test18b() {
686  call i8* @objc_retain(i8* undef)
687  call void @objc_release(i8* undef)
688  call i8* @objc_autorelease(i8* undef)
689  ret void
690}
691
692; Replace uses of arguments with uses of return values, to reduce
693; register pressure.
694
695; CHECK: define void @test19(i32* %y) {
696; CHECK:   %z = bitcast i32* %y to i8*
697; CHECK:   %0 = bitcast i32* %y to i8*
698; CHECK:   %1 = tail call i8* @objc_retain(i8* %0)
699; CHECK:   call void @use_pointer(i8* %z)
700; CHECK:   call void @use_pointer(i8* %z)
701; CHECK:   %2 = bitcast i32* %y to i8*
702; CHECK:   call void @objc_release(i8* %2)
703; CHECK:   ret void
704; CHECK: }
705define void @test19(i32* %y) {
706entry:
707  %x = bitcast i32* %y to i8*
708  %0 = call i8* @objc_retain(i8* %x) nounwind
709  %z = bitcast i32* %y to i8*
710  call void @use_pointer(i8* %z)
711  call void @use_pointer(i8* %z)
712  call void @objc_release(i8* %x)
713  ret void
714}
715
716; Bitcast insertion
717
718; CHECK: define void @test20(
719; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) nounwind
720; CHECK-NEXT: invoke
721define void @test20(double* %self) {
722if.then12:
723  %tmp = bitcast double* %self to i8*
724  %tmp1 = call i8* @objc_retain(i8* %tmp) nounwind
725  invoke void @invokee()
726          to label %invoke.cont23 unwind label %lpad20
727
728invoke.cont23:                                    ; preds = %if.then12
729  invoke void @invokee()
730          to label %if.end unwind label %lpad20
731
732lpad20:                                           ; preds = %invoke.cont23, %if.then12
733  %tmp502 = phi double* [ undef, %invoke.cont23 ], [ %self, %if.then12 ]
734  %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
735           cleanup
736  unreachable
737
738if.end:                                           ; preds = %invoke.cont23
739  ret void
740}
741
742; Delete a redundant retain,autorelease when forwaring a call result
743; directly to a return value.
744
745; CHECK: define i8* @test21(
746; CHECK: call i8* @returner()
747; CHECK-NEXT: ret i8* %call
748define i8* @test21() {
749entry:
750  %call = call i8* @returner()
751  %0 = call i8* @objc_retain(i8* %call) nounwind
752  %1 = call i8* @objc_autorelease(i8* %0) nounwind
753  ret i8* %1
754}
755
756; Move an objc call up through a phi that has null operands.
757
758; CHECK: define void @test22(
759; CHECK: B:
760; CHECK:   %1 = bitcast double* %p to i8*
761; CHECK:   call void @objc_release(i8* %1)
762; CHECK:   br label %C
763; CHECK: C:                                                ; preds = %B, %A
764; CHECK-NOT: @objc_release
765; CHECK: }
766define void @test22(double* %p, i1 %a) {
767  br i1 %a, label %A, label %B
768A:
769  br label %C
770B:
771  br label %C
772C:
773  %h = phi double* [ null, %A ], [ %p, %B ]
774  %c = bitcast double* %h to i8*
775  call void @objc_release(i8* %c)
776  ret void
777}
778
779; Optimize objc_retainBlock.
780
781; CHECK: define void @test23(
782; CHECK-NOT: @objc_
783; CHECK: }
784%block0 = type { i64, i64, i8*, i8* }
785%block1 = type { i8**, i32, i32, i32 (%struct.__block_literal_1*)*, %block0* }
786%struct.__block_descriptor = type { i64, i64 }
787%struct.__block_literal_1 = type { i8**, i32, i32, i8**, %struct.__block_descriptor* }
788@__block_holder_tmp_1 = external constant %block1
789define void @test23() {
790entry:
791  %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind, !clang.arc.copy_on_escape !0
792  call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
793  call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
794  call void @objc_release(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
795  ret void
796}
797
798; Don't optimize objc_retainBlock.
799
800; CHECK: define void @test23b
801; CHECK: @objc_retainBlock
802; CHECK: @objc_release
803; CHECK: }
804define void @test23b(i8* %p) {
805entry:
806  %0 = call i8* @objc_retainBlock(i8* %p) nounwind, !clang.arc.copy_on_escape !0
807  call void @callee()
808  call void @use_pointer(i8* %p)
809  call void @objc_release(i8* %p) nounwind
810  ret void
811}
812
813; Don't optimize objc_retainBlock, because there's no copy_on_escape metadata.
814
815; CHECK: define void @test23c(
816; CHECK: @objc_retainBlock
817; CHECK: @objc_release
818; CHECK: }
819define void @test23c() {
820entry:
821  %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
822  call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
823  call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
824  call void @objc_release(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
825  ret void
826}
827
828; Any call can decrement a retain count.
829
830; CHECK: define void @test24(
831; CHECK: @objc_retain(i8* %a)
832; CHECK: @objc_release
833; CHECK: }
834define void @test24(i8* %r, i8* %a) {
835  call i8* @objc_retain(i8* %a)
836  call void @use_pointer(i8* %r)
837  %q = load i8* %a
838  call void @objc_release(i8* %a)
839  ret void
840}
841
842; Don't move a retain/release pair if the release can be moved
843; but the retain can't be moved to balance it.
844
845; CHECK: define void @test25(
846; CHECK: entry:
847; CHECK:   call i8* @objc_retain(i8* %p)
848; CHECK: true:
849; CHECK: done:
850; CHECK:   call void @objc_release(i8* %p)
851; CHECK: }
852define void @test25(i8* %p, i1 %x) {
853entry:
854  %f0 = call i8* @objc_retain(i8* %p)
855  call void @callee()
856  br i1 %x, label %true, label %done
857
858true:
859  store i8 0, i8* %p
860  br label %done
861
862done:
863  call void @objc_release(i8* %p)
864  ret void
865}
866
867; Don't move a retain/release pair if the retain can be moved
868; but the release can't be moved to balance it.
869
870; CHECK: define void @test26(
871; CHECK: entry:
872; CHECK:   call i8* @objc_retain(i8* %p)
873; CHECK: true:
874; CHECK: done:
875; CHECK:   call void @objc_release(i8* %p)
876; CHECK: }
877define void @test26(i8* %p, i1 %x) {
878entry:
879  %f0 = call i8* @objc_retain(i8* %p)
880  br i1 %x, label %true, label %done
881
882true:
883  call void @callee()
884  br label %done
885
886done:
887  store i8 0, i8* %p
888  call void @objc_release(i8* %p)
889  ret void
890}
891
892; Don't sink the retain,release into the loop.
893
894; CHECK: define void @test27(
895; CHECK: entry:
896; CHECK: call i8* @objc_retain(i8* %p)
897; CHECK: loop:
898; CHECK-NOT: @objc_
899; CHECK: done:
900; CHECK: call void @objc_release
901; CHECK: }
902define void @test27(i8* %p, i1 %x, i1 %y) {
903entry:
904  %f0 = call i8* @objc_retain(i8* %p)
905  br i1 %x, label %loop, label %done
906
907loop:
908  call void @callee()
909  store i8 0, i8* %p
910  br i1 %y, label %done, label %loop
911
912done:
913  call void @objc_release(i8* %p)
914  ret void
915}
916
917; Trivial code motion case: Triangle.
918
919; CHECK: define void @test28(
920; CHECK-NOT: @objc_
921; CHECK: true:
922; CHECK: call i8* @objc_retain(
923; CHECK: call void @callee()
924; CHECK: store
925; CHECK: call void @objc_release
926; CHECK: done:
927; CHECK-NOT: @objc_
928; CHECK: }
929define void @test28(i8* %p, i1 %x) {
930entry:
931  %f0 = call i8* @objc_retain(i8* %p)
932  br i1 %x, label %true, label %done
933
934true:
935  call void @callee()
936  store i8 0, i8* %p
937  br label %done
938
939done:
940  call void @objc_release(i8* %p), !clang.imprecise_release !0
941  ret void
942}
943
944; Trivial code motion case: Triangle, but no metadata. Don't move past
945; unrelated memory references!
946
947; CHECK: define void @test28b
948; CHECK: call i8* @objc_retain(
949; CHECK: true:
950; CHECK-NOT: @objc_
951; CHECK: call void @callee()
952; CHECK-NOT: @objc_
953; CHECK: store
954; CHECK-NOT: @objc_
955; CHECK: done:
956; CHECK: @objc_release
957; CHECK: }
958define void @test28b(i8* %p, i1 %x, i8* noalias %t) {
959entry:
960  %f0 = call i8* @objc_retain(i8* %p)
961  br i1 %x, label %true, label %done
962
963true:
964  call void @callee()
965  store i8 0, i8* %p
966  br label %done
967
968done:
969  store i8 0, i8* %t
970  call void @objc_release(i8* %p)
971  ret void
972}
973
974; Trivial code motion case: Triangle, with metadata. Do move past
975; unrelated memory references! And preserve the metadata.
976
977; CHECK: define void @test28c
978; CHECK-NOT: @objc_
979; CHECK: true:
980; CHECK: call i8* @objc_retain(
981; CHECK: call void @callee()
982; CHECK: store
983; CHECK: call void @objc_release(i8* %p) nounwind, !clang.imprecise_release
984; CHECK: done:
985; CHECK-NOT: @objc_
986; CHECK: }
987define void @test28c(i8* %p, i1 %x, i8* noalias %t) {
988entry:
989  %f0 = call i8* @objc_retain(i8* %p)
990  br i1 %x, label %true, label %done
991
992true:
993  call void @callee()
994  store i8 0, i8* %p
995  br label %done
996
997done:
998  store i8 0, i8* %t
999  call void @objc_release(i8* %p), !clang.imprecise_release !0
1000  ret void
1001}
1002
1003; Like test28. but with two releases.
1004
1005; CHECK: define void @test29(
1006; CHECK-NOT: @objc_
1007; CHECK: true:
1008; CHECK: call i8* @objc_retain(
1009; CHECK: call void @callee()
1010; CHECK: store
1011; CHECK: call void @objc_release
1012; CHECK-NOT: @objc_release
1013; CHECK: done:
1014; CHECK-NOT: @objc_
1015; CHECK: ohno:
1016; CHECK-NOT: @objc_
1017; CHECK: }
1018define void @test29(i8* %p, i1 %x, i1 %y) {
1019entry:
1020  %f0 = call i8* @objc_retain(i8* %p)
1021  br i1 %x, label %true, label %done
1022
1023true:
1024  call void @callee()
1025  store i8 0, i8* %p
1026  br i1 %y, label %done, label %ohno
1027
1028done:
1029  call void @objc_release(i8* %p)
1030  ret void
1031
1032ohno:
1033  call void @objc_release(i8* %p)
1034  ret void
1035}
1036
1037; Basic case with the use and call in a diamond
1038; with an extra release.
1039
1040; CHECK: define void @test30(
1041; CHECK-NOT: @objc_
1042; CHECK: true:
1043; CHECK: call i8* @objc_retain(
1044; CHECK: call void @callee()
1045; CHECK: store
1046; CHECK: call void @objc_release
1047; CHECK-NOT: @objc_release
1048; CHECK: false:
1049; CHECK-NOT: @objc_
1050; CHECK: done:
1051; CHECK-NOT: @objc_
1052; CHECK: ohno:
1053; CHECK-NOT: @objc_
1054; CHECK: }
1055define void @test30(i8* %p, i1 %x, i1 %y, i1 %z) {
1056entry:
1057  %f0 = call i8* @objc_retain(i8* %p)
1058  br i1 %x, label %true, label %false
1059
1060true:
1061  call void @callee()
1062  store i8 0, i8* %p
1063  br i1 %y, label %done, label %ohno
1064
1065false:
1066  br i1 %z, label %done, label %ohno
1067
1068done:
1069  call void @objc_release(i8* %p)
1070  ret void
1071
1072ohno:
1073  call void @objc_release(i8* %p)
1074  ret void
1075}
1076
1077; Basic case with a mergeable release.
1078
1079; CHECK: define void @test31(
1080; CHECK: call i8* @objc_retain(i8* %p)
1081; CHECK: call void @callee()
1082; CHECK: store
1083; CHECK: call void @objc_release
1084; CHECK-NOT: @objc_release
1085; CHECK: true:
1086; CHECK-NOT: @objc_release
1087; CHECK: false:
1088; CHECK-NOT: @objc_release
1089; CHECK: ret void
1090; CHECK-NOT: @objc_release
1091; CHECK: }
1092define void @test31(i8* %p, i1 %x) {
1093entry:
1094  %f0 = call i8* @objc_retain(i8* %p)
1095  call void @callee()
1096  store i8 0, i8* %p
1097  br i1 %x, label %true, label %false
1098true:
1099  call void @objc_release(i8* %p)
1100  ret void
1101false:
1102  call void @objc_release(i8* %p)
1103  ret void
1104}
1105
1106; Don't consider bitcasts or getelementptrs direct uses.
1107
1108; CHECK: define void @test32(
1109; CHECK-NOT: @objc_
1110; CHECK: true:
1111; CHECK: call i8* @objc_retain(
1112; CHECK: call void @callee()
1113; CHECK: store
1114; CHECK: call void @objc_release
1115; CHECK: done:
1116; CHECK-NOT: @objc_
1117; CHECK: }
1118define void @test32(i8* %p, i1 %x) {
1119entry:
1120  %f0 = call i8* @objc_retain(i8* %p)
1121  br i1 %x, label %true, label %done
1122
1123true:
1124  call void @callee()
1125  store i8 0, i8* %p
1126  br label %done
1127
1128done:
1129  %g = bitcast i8* %p to i8*
1130  %h = getelementptr i8* %g, i64 0
1131  call void @objc_release(i8* %g)
1132  ret void
1133}
1134
1135; Do consider icmps to be direct uses.
1136
1137; CHECK: define void @test33(
1138; CHECK-NOT: @objc_
1139; CHECK: true:
1140; CHECK: call i8* @objc_retain(
1141; CHECK: call void @callee()
1142; CHECK: icmp
1143; CHECK: call void @objc_release
1144; CHECK: done:
1145; CHECK-NOT: @objc_
1146; CHECK: }
1147define void @test33(i8* %p, i1 %x, i8* %y) {
1148entry:
1149  %f0 = call i8* @objc_retain(i8* %p)
1150  br i1 %x, label %true, label %done
1151
1152true:
1153  call void @callee()
1154  %v = icmp eq i8* %p, %y
1155  br label %done
1156
1157done:
1158  %g = bitcast i8* %p to i8*
1159  %h = getelementptr i8* %g, i64 0
1160  call void @objc_release(i8* %g)
1161  ret void
1162}
1163
1164; Delete retain,release if there's just a possible dec.
1165
1166; CHECK: define void @test34(
1167; CHECK-NOT: @objc_
1168; CHECK: }
1169define void @test34(i8* %p, i1 %x, i8* %y) {
1170entry:
1171  %f0 = call i8* @objc_retain(i8* %p)
1172  br i1 %x, label %true, label %done
1173
1174true:
1175  call void @callee()
1176  br label %done
1177
1178done:
1179  %g = bitcast i8* %p to i8*
1180  %h = getelementptr i8* %g, i64 0
1181  call void @objc_release(i8* %g)
1182  ret void
1183}
1184
1185; Delete retain,release if there's just a use.
1186
1187; CHECK: define void @test35(
1188; CHECK-NOT: @objc_
1189; CHECK: }
1190define void @test35(i8* %p, i1 %x, i8* %y) {
1191entry:
1192  %f0 = call i8* @objc_retain(i8* %p)
1193  br i1 %x, label %true, label %done
1194
1195true:
1196  %v = icmp eq i8* %p, %y
1197  br label %done
1198
1199done:
1200  %g = bitcast i8* %p to i8*
1201  %h = getelementptr i8* %g, i64 0
1202  call void @objc_release(i8* %g)
1203  ret void
1204}
1205
1206; Delete a retain,release if there's no actual use.
1207
1208; CHECK: define void @test36(
1209; CHECK-NOT: @objc_
1210; CHECK: call void @callee()
1211; CHECK-NOT: @objc_
1212; CHECK: call void @callee()
1213; CHECK-NOT: @objc_
1214; CHECK: }
1215define void @test36(i8* %p) {
1216entry:
1217  call i8* @objc_retain(i8* %p)
1218  call void @callee()
1219  call void @callee()
1220  call void @objc_release(i8* %p)
1221  ret void
1222}
1223
1224; Like test36, but with metadata.
1225
1226; CHECK: define void @test37(
1227; CHECK-NOT: @objc_
1228; CHECK: }
1229define void @test37(i8* %p) {
1230entry:
1231  call i8* @objc_retain(i8* %p)
1232  call void @callee()
1233  call void @callee()
1234  call void @objc_release(i8* %p), !clang.imprecise_release !0
1235  ret void
1236}
1237
1238; Be aggressive about analyzing phis to eliminate possible uses.
1239
1240; CHECK: define void @test38(
1241; CHECK-NOT: @objc_
1242; CHECK: }
1243define void @test38(i8* %p, i1 %u, i1 %m, i8* %z, i8* %y, i8* %x, i8* %w) {
1244entry:
1245  call i8* @objc_retain(i8* %p)
1246  br i1 %u, label %true, label %false
1247true:
1248  br i1 %m, label %a, label %b
1249false:
1250  br i1 %m, label %c, label %d
1251a:
1252  br label %e
1253b:
1254  br label %e
1255c:
1256  br label %f
1257d:
1258  br label %f
1259e:
1260  %j = phi i8* [ %z, %a ], [ %y, %b ]
1261  br label %g
1262f:
1263  %k = phi i8* [ %w, %c ], [ %x, %d ]
1264  br label %g
1265g:
1266  %h = phi i8* [ %j, %e ], [ %k, %f ]
1267  call void @use_pointer(i8* %h)
1268  call void @objc_release(i8* %p), !clang.imprecise_release !0
1269  ret void
1270}
1271
1272; Delete retain,release pairs around loops.
1273
1274; CHECK: define void @test39(
1275; CHECK_NOT: @objc_
1276; CHECK: }
1277define void @test39(i8* %p) {
1278entry:
1279  %0 = call i8* @objc_retain(i8* %p)
1280  br label %loop
1281
1282loop:                                             ; preds = %loop, %entry
1283  br i1 undef, label %loop, label %exit
1284
1285exit:                                             ; preds = %loop
1286  call void @objc_release(i8* %0), !clang.imprecise_release !0
1287  ret void
1288}
1289
1290; Delete retain,release pairs around loops containing uses.
1291
1292; CHECK: define void @test39b(
1293; CHECK_NOT: @objc_
1294; CHECK: }
1295define void @test39b(i8* %p) {
1296entry:
1297  %0 = call i8* @objc_retain(i8* %p)
1298  br label %loop
1299
1300loop:                                             ; preds = %loop, %entry
1301  store i8 0, i8* %0
1302  br i1 undef, label %loop, label %exit
1303
1304exit:                                             ; preds = %loop
1305  call void @objc_release(i8* %0), !clang.imprecise_release !0
1306  ret void
1307}
1308
1309; Delete retain,release pairs around loops containing potential decrements.
1310
1311; CHECK: define void @test39c(
1312; CHECK_NOT: @objc_
1313; CHECK: }
1314define void @test39c(i8* %p) {
1315entry:
1316  %0 = call i8* @objc_retain(i8* %p)
1317  br label %loop
1318
1319loop:                                             ; preds = %loop, %entry
1320  call void @use_pointer(i8* %0)
1321  br i1 undef, label %loop, label %exit
1322
1323exit:                                             ; preds = %loop
1324  call void @objc_release(i8* %0), !clang.imprecise_release !0
1325  ret void
1326}
1327
1328; Delete retain,release pairs around loops even if
1329; the successors are in a different order.
1330
1331; CHECK: define void @test40(
1332; CHECK_NOT: @objc_
1333; CHECK: }
1334define void @test40(i8* %p) {
1335entry:
1336  %0 = call i8* @objc_retain(i8* %p)
1337  br label %loop
1338
1339loop:                                             ; preds = %loop, %entry
1340  call void @use_pointer(i8* %0)
1341  br i1 undef, label %exit, label %loop
1342
1343exit:                                             ; preds = %loop
1344  call void @objc_release(i8* %0), !clang.imprecise_release !0
1345  ret void
1346}
1347
1348; Do the known-incremented retain+release elimination even if the pointer
1349; is also autoreleased.
1350
1351; CHECK: define void @test42(
1352; CHECK-NEXT: entry:
1353; CHECK-NEXT: call i8* @objc_retain(i8* %p)
1354; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
1355; CHECK-NEXT: call void @use_pointer(i8* %p)
1356; CHECK-NEXT: call void @use_pointer(i8* %p)
1357; CHECK-NEXT: ret void
1358; CHECK-NEXT: }
1359define void @test42(i8* %p) {
1360entry:
1361  call i8* @objc_retain(i8* %p)
1362  call i8* @objc_autorelease(i8* %p)
1363  call i8* @objc_retain(i8* %p)
1364  call void @use_pointer(i8* %p)
1365  call void @use_pointer(i8* %p)
1366  call void @objc_release(i8* %p)
1367  ret void
1368}
1369
1370; Don't the known-incremented retain+release elimination if the pointer is
1371; autoreleased and there's an autoreleasePoolPop.
1372
1373; CHECK: define void @test43(
1374; CHECK-NEXT: entry:
1375; CHECK-NEXT: call i8* @objc_retain(i8* %p)
1376; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
1377; CHECK-NEXT: call i8* @objc_retain
1378; CHECK-NEXT: call void @use_pointer(i8* %p)
1379; CHECK-NEXT: call void @use_pointer(i8* %p)
1380; CHECK-NEXT: call void @objc_autoreleasePoolPop(i8* undef)
1381; CHECK-NEXT: call void @objc_release
1382; CHECK-NEXT: ret void
1383; CHECK-NEXT: }
1384define void @test43(i8* %p) {
1385entry:
1386  call i8* @objc_retain(i8* %p)
1387  call i8* @objc_autorelease(i8* %p)
1388  call i8* @objc_retain(i8* %p)
1389  call void @use_pointer(i8* %p)
1390  call void @use_pointer(i8* %p)
1391  call void @objc_autoreleasePoolPop(i8* undef)
1392  call void @objc_release(i8* %p)
1393  ret void
1394}
1395
1396; Do the known-incremented retain+release elimination if the pointer is
1397; autoreleased and there's an autoreleasePoolPush.
1398
1399; CHECK: define void @test43b
1400; CHECK-NEXT: entry:
1401; CHECK-NEXT: call i8* @objc_retain(i8* %p)
1402; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
1403; CHECK-NEXT: call void @use_pointer(i8* %p)
1404; CHECK-NEXT: call void @use_pointer(i8* %p)
1405; CHECK-NEXT: call i8* @objc_autoreleasePoolPush()
1406; CHECK-NEXT: ret void
1407; CHECK-NEXT: }
1408define void @test43b(i8* %p) {
1409entry:
1410  call i8* @objc_retain(i8* %p)
1411  call i8* @objc_autorelease(i8* %p)
1412  call i8* @objc_retain(i8* %p)
1413  call void @use_pointer(i8* %p)
1414  call void @use_pointer(i8* %p)
1415  call i8* @objc_autoreleasePoolPush()
1416  call void @objc_release(i8* %p)
1417  ret void
1418}
1419
1420; Do retain+release elimination for non-provenance pointers.
1421
1422; CHECK: define void @test44(
1423; CHECK-NOT: objc_
1424; CHECK: }
1425define void @test44(i8** %pp) {
1426  %p = load i8** %pp
1427  %q = call i8* @objc_retain(i8* %p)
1428  call void @objc_release(i8* %q)
1429  ret void
1430}
1431
1432; Don't delete retain+release with an unknown-provenance
1433; may-alias objc_release between them.
1434
1435; CHECK: define void @test45(
1436; CHECK: call i8* @objc_retain(i8* %p)
1437; CHECK: call void @objc_release(i8* %q)
1438; CHECK: call void @use_pointer(i8* %p)
1439; CHECK: call void @objc_release(i8* %p)
1440define void @test45(i8** %pp, i8** %qq) {
1441  %p = load i8** %pp
1442  %q = load i8** %qq
1443  call i8* @objc_retain(i8* %p)
1444  call void @objc_release(i8* %q)
1445  call void @use_pointer(i8* %p)
1446  call void @objc_release(i8* %p)
1447  ret void
1448}
1449
1450; Don't delete retain and autorelease here.
1451
1452; CHECK: define void @test46(
1453; CHECK: tail call i8* @objc_retain(i8* %p) nounwind
1454; CHECK: true:
1455; CHECK: tail call i8* @objc_autorelease(i8* %p) nounwind
1456define void @test46(i8* %p, i1 %a) {
1457entry:
1458  call i8* @objc_retain(i8* %p)
1459  br i1 %a, label %true, label %false
1460
1461true:
1462  call i8* @objc_autorelease(i8* %p)
1463  call void @use_pointer(i8* %p)
1464  ret void
1465
1466false:
1467  ret void
1468}
1469
1470; Delete no-op cast calls.
1471
1472; CHECK: define i8* @test47(
1473; CHECK-NOT: call
1474; CHECK: ret i8* %p
1475define i8* @test47(i8* %p) nounwind {
1476  %x = call i8* @objc_retainedObject(i8* %p)
1477  ret i8* %x
1478}
1479
1480; Delete no-op cast calls.
1481
1482; CHECK: define i8* @test48(
1483; CHECK-NOT: call
1484; CHECK: ret i8* %p
1485define i8* @test48(i8* %p) nounwind {
1486  %x = call i8* @objc_unretainedObject(i8* %p)
1487  ret i8* %x
1488}
1489
1490; Delete no-op cast calls.
1491
1492; CHECK: define i8* @test49(
1493; CHECK-NOT: call
1494; CHECK: ret i8* %p
1495define i8* @test49(i8* %p) nounwind {
1496  %x = call i8* @objc_unretainedPointer(i8* %p)
1497  ret i8* %x
1498}
1499
1500; Do delete retain+release with intervening stores of the
1501; address value;
1502
1503; CHECK: define void @test50(
1504; CHECK-NOT: @objc_
1505; CHECK: }
1506define void @test50(i8* %p, i8** %pp) {
1507  call i8* @objc_retain(i8* %p)
1508  call void @callee()
1509  store i8* %p, i8** %pp
1510  call void @objc_release(i8* %p)
1511  ret void
1512}
1513
1514; Don't delete retain+release with intervening stores through the
1515; address value.
1516
1517; CHECK: define void @test51(
1518; CHECK: call i8* @objc_retain(i8* %p)
1519; CHECK: call void @objc_release(i8* %p)
1520define void @test51(i8* %p) {
1521  call i8* @objc_retain(i8* %p)
1522  call void @callee()
1523  store i8 0, i8* %p
1524  call void @objc_release(i8* %p)
1525  ret void
1526}
1527
1528; Don't delete retain+release with intervening use of a pointer of
1529; unknown provenance.
1530
1531; CHECK: define void @test52(
1532; CHECK: call i8* @objc_retain
1533; CHECK: call void @callee()
1534; CHECK: call void @use_pointer(i8* %z)
1535; CHECK: call void @objc_release
1536define void @test52(i8** %zz, i8** %pp) {
1537  %p = load i8** %pp
1538  %1 = call i8* @objc_retain(i8* %p)
1539  call void @callee()
1540  %z = load i8** %zz
1541  call void @use_pointer(i8* %z)
1542  call void @objc_release(i8* %p)
1543  ret void
1544}
1545
1546; Like test52, but the pointer has function type, so it's assumed to
1547; be not reference counted.
1548; Oops. That's wrong. Clang sometimes uses function types gratuitously.
1549; See rdar://10551239.
1550
1551; CHECK: define void @test53(
1552; CHECK: @objc_
1553; CHECK: }
1554define void @test53(void ()** %zz, i8** %pp) {
1555  %p = load i8** %pp
1556  %1 = call i8* @objc_retain(i8* %p)
1557  call void @callee()
1558  %z = load void ()** %zz
1559  call void @callee_fnptr(void ()* %z)
1560  call void @objc_release(i8* %p)
1561  ret void
1562}
1563
1564; Convert autorelease to release if the value is unused.
1565
1566; CHECK: define void @test54(
1567; CHECK: call i8* @returner()
1568; CHECK-NEXT: call void @objc_release(i8* %t) nounwind, !clang.imprecise_release !0
1569; CHECK-NEXT: ret void
1570define void @test54() {
1571  %t = call i8* @returner()
1572  call i8* @objc_autorelease(i8* %t)
1573  ret void
1574}
1575
1576; Nested retain+release pairs. Delete them both.
1577
1578; CHECK: define void @test55(
1579; CHECK-NOT: @objc
1580; CHECK: }
1581define void @test55(i8* %x) {
1582entry:
1583  %0 = call i8* @objc_retain(i8* %x) nounwind
1584  %1 = call i8* @objc_retain(i8* %x) nounwind
1585  call void @objc_release(i8* %x) nounwind
1586  call void @objc_release(i8* %x) nounwind
1587  ret void
1588}
1589
1590; Nested retain+release pairs where the inner pair depends
1591; on the outer pair to be removed, and then the outer pair
1592; can be partially eliminated. Plus an extra outer pair to
1593; eliminate, for fun.
1594
1595; CHECK: define void @test56(
1596; CHECK-NOT: @objc
1597; CHECK: if.then:
1598; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind
1599; CHECK-NEXT: tail call void @use_pointer(i8* %x)
1600; CHECK-NEXT: tail call void @use_pointer(i8* %x)
1601; CHECK-NEXT: tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1602; CHECK-NEXT: br label %if.end
1603; CHECK-NOT: @objc
1604; CHECK: }
1605define void @test56(i8* %x, i32 %n) {
1606entry:
1607  %0 = tail call i8* @objc_retain(i8* %x) nounwind
1608  %1 = tail call i8* @objc_retain(i8* %0) nounwind
1609  %tobool = icmp eq i32 %n, 0
1610  br i1 %tobool, label %if.end, label %if.then
1611
1612if.then:                                          ; preds = %entry
1613  %2 = tail call i8* @objc_retain(i8* %1) nounwind
1614  tail call void @use_pointer(i8* %2)
1615  tail call void @use_pointer(i8* %2)
1616  tail call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0
1617  br label %if.end
1618
1619if.end:                                           ; preds = %entry, %if.then
1620  tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
1621  tail call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0
1622  ret void
1623}
1624
1625; When there are adjacent retain+release pairs, the first one is
1626; known unnecessary because the presence of the second one means that
1627; the first one won't be deleting the object.
1628
1629; CHECK:      define void @test57(
1630; CHECK-NEXT: entry:
1631; CHECK-NEXT:   call void @use_pointer(i8* %x)
1632; CHECK-NEXT:   call void @use_pointer(i8* %x)
1633; CHECK-NEXT:   %0 = tail call i8* @objc_retain(i8* %x) nounwind
1634; CHECK-NEXT:   call void @use_pointer(i8* %x)
1635; CHECK-NEXT:   call void @use_pointer(i8* %x)
1636; CHECK-NEXT:   call void @objc_release(i8* %x) nounwind
1637; CHECK-NEXT:   ret void
1638; CHECK-NEXT: }
1639define void @test57(i8* %x) nounwind {
1640entry:
1641  call i8* @objc_retain(i8* %x) nounwind
1642  call void @use_pointer(i8* %x)
1643  call void @use_pointer(i8* %x)
1644  call void @objc_release(i8* %x) nounwind
1645  call i8* @objc_retain(i8* %x) nounwind
1646  call void @use_pointer(i8* %x)
1647  call void @use_pointer(i8* %x)
1648  call void @objc_release(i8* %x) nounwind
1649  ret void
1650}
1651
1652; An adjacent retain+release pair is sufficient even if it will be
1653; removed itself.
1654
1655; CHECK:      define void @test58(
1656; CHECK-NEXT: entry:
1657; CHECK-NEXT:   call void @use_pointer(i8* %x)
1658; CHECK-NEXT:   call void @use_pointer(i8* %x)
1659; CHECK-NEXT:   ret void
1660; CHECK-NEXT: }
1661define void @test58(i8* %x) nounwind {
1662entry:
1663  call i8* @objc_retain(i8* %x) nounwind
1664  call void @use_pointer(i8* %x)
1665  call void @use_pointer(i8* %x)
1666  call void @objc_release(i8* %x) nounwind
1667  call i8* @objc_retain(i8* %x) nounwind
1668  call void @objc_release(i8* %x) nounwind
1669  ret void
1670}
1671
1672; Don't delete the second retain+release pair in an adjacent set.
1673
1674; CHECK:      define void @test59(
1675; CHECK-NEXT: entry:
1676; CHECK-NEXT:   %0 = tail call i8* @objc_retain(i8* %x) nounwind
1677; CHECK-NEXT:   call void @use_pointer(i8* %x)
1678; CHECK-NEXT:   call void @use_pointer(i8* %x)
1679; CHECK-NEXT:   call void @objc_release(i8* %x) nounwind
1680; CHECK-NEXT:   ret void
1681; CHECK-NEXT: }
1682define void @test59(i8* %x) nounwind {
1683entry:
1684  %a = call i8* @objc_retain(i8* %x) nounwind
1685  call void @objc_release(i8* %x) nounwind
1686  %b = call i8* @objc_retain(i8* %x) nounwind
1687  call void @use_pointer(i8* %x)
1688  call void @use_pointer(i8* %x)
1689  call void @objc_release(i8* %x) nounwind
1690  ret void
1691}
1692
1693; Constant pointers to objects don't need reference counting.
1694
1695@constptr = external constant i8*
1696@something = external global i8*
1697
1698; CHECK: define void @test60(
1699; CHECK-NOT: @objc_
1700; CHECK: }
1701define void @test60() {
1702  %t = load i8** @constptr
1703  %s = load i8** @something
1704  call i8* @objc_retain(i8* %s)
1705  call void @callee()
1706  call void @use_pointer(i8* %t)
1707  call void @objc_release(i8* %s)
1708  ret void
1709}
1710
1711; Constant pointers to objects don't need to be considered related to other
1712; pointers.
1713
1714; CHECK: define void @test61(
1715; CHECK-NOT: @objc_
1716; CHECK: }
1717define void @test61() {
1718  %t = load i8** @constptr
1719  call i8* @objc_retain(i8* %t)
1720  call void @callee()
1721  call void @use_pointer(i8* %t)
1722  call void @objc_release(i8* %t)
1723  ret void
1724}
1725
1726; Delete a retain matched by releases when one is inside the loop and the
1727; other is outside the loop.
1728
1729; CHECK: define void @test62(
1730; CHECK-NOT: @objc_
1731; CHECK: }
1732define void @test62(i8* %x, i1* %p) nounwind {
1733entry:
1734  br label %loop
1735
1736loop:
1737  call i8* @objc_retain(i8* %x)
1738  %q = load i1* %p
1739  br i1 %q, label %loop.more, label %exit
1740
1741loop.more:
1742  call void @objc_release(i8* %x)
1743  br label %loop
1744
1745exit:
1746  call void @objc_release(i8* %x)
1747  ret void
1748}
1749
1750; Like test62 but with no release in exit.
1751; Don't delete anything!
1752
1753; CHECK: define void @test63(
1754; CHECK: loop:
1755; CHECK:   tail call i8* @objc_retain(i8* %x)
1756; CHECK: loop.more:
1757; CHECK:   call void @objc_release(i8* %x)
1758; CHECK: }
1759define void @test63(i8* %x, i1* %p) nounwind {
1760entry:
1761  br label %loop
1762
1763loop:
1764  call i8* @objc_retain(i8* %x)
1765  %q = load i1* %p
1766  br i1 %q, label %loop.more, label %exit
1767
1768loop.more:
1769  call void @objc_release(i8* %x)
1770  br label %loop
1771
1772exit:
1773  ret void
1774}
1775
1776; Like test62 but with no release in loop.more.
1777; Don't delete anything!
1778
1779; CHECK: define void @test64(
1780; CHECK: loop:
1781; CHECK:   tail call i8* @objc_retain(i8* %x)
1782; CHECK: exit:
1783; CHECK:   call void @objc_release(i8* %x)
1784; CHECK: }
1785define void @test64(i8* %x, i1* %p) nounwind {
1786entry:
1787  br label %loop
1788
1789loop:
1790  call i8* @objc_retain(i8* %x)
1791  %q = load i1* %p
1792  br i1 %q, label %loop.more, label %exit
1793
1794loop.more:
1795  br label %loop
1796
1797exit:
1798  call void @objc_release(i8* %x)
1799  ret void
1800}
1801
1802; Move an autorelease past a phi with a null.
1803
1804; CHECK: define i8* @test65(
1805; CHECK: if.then:
1806; CHECK:   call i8* @objc_autorelease(
1807; CHECK: return:
1808; CHECK-NOT: @objc_autorelease
1809; CHECK: }
1810define i8* @test65(i1 %x) {
1811entry:
1812  br i1 %x, label %return, label %if.then
1813
1814if.then:                                          ; preds = %entry
1815  %c = call i8* @returner()
1816  %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
1817  br label %return
1818
1819return:                                           ; preds = %if.then, %entry
1820  %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
1821  %q = call i8* @objc_autorelease(i8* %retval) nounwind
1822  ret i8* %retval
1823}
1824
1825; Don't move an autorelease past an autorelease pool boundary.
1826
1827; CHECK: define i8* @test65b(
1828; CHECK: if.then:
1829; CHECK-NOT: @objc_autorelease
1830; CHECK: return:
1831; CHECK:   call i8* @objc_autorelease(
1832; CHECK: }
1833define i8* @test65b(i1 %x) {
1834entry:
1835  %t = call i8* @objc_autoreleasePoolPush()
1836  br i1 %x, label %return, label %if.then
1837
1838if.then:                                          ; preds = %entry
1839  %c = call i8* @returner()
1840  %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
1841  br label %return
1842
1843return:                                           ; preds = %if.then, %entry
1844  %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
1845  call void @objc_autoreleasePoolPop(i8* %t)
1846  %q = call i8* @objc_autorelease(i8* %retval) nounwind
1847  ret i8* %retval
1848}
1849
1850; Don't move an autoreleaseReuturnValue, which would break
1851; the RV optimization.
1852
1853; CHECK: define i8* @test65c(
1854; CHECK: if.then:
1855; CHECK-NOT: @objc_autorelease
1856; CHECK: return:
1857; CHECK:   call i8* @objc_autoreleaseReturnValue(
1858; CHECK: }
1859define i8* @test65c(i1 %x) {
1860entry:
1861  br i1 %x, label %return, label %if.then
1862
1863if.then:                                          ; preds = %entry
1864  %c = call i8* @returner()
1865  %s = call i8* @objc_retainAutoreleasedReturnValue(i8* %c) nounwind
1866  br label %return
1867
1868return:                                           ; preds = %if.then, %entry
1869  %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
1870  %q = call i8* @objc_autoreleaseReturnValue(i8* %retval) nounwind
1871  ret i8* %retval
1872}
1873
1874declare void @bar(i32 ()*)
1875
1876; A few real-world testcases.
1877
1878@.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
1879@"OBJC_IVAR_$_A.myZ" = global i64 20, section "__DATA, __objc_const", align 8
1880declare i32 @printf(i8* nocapture, ...) nounwind
1881declare i32 @puts(i8* nocapture) nounwind
1882@str = internal constant [16 x i8] c"-[ Top0 _getX ]\00"
1883
1884; CHECK: @"\01-[A z]"
1885; CHECK-NOT: @objc_
1886; CHECK: }
1887
1888define {<2 x float>, <2 x float>} @"\01-[A z]"({}* %self, i8* nocapture %_cmd) nounwind {
1889invoke.cont:
1890  %0 = bitcast {}* %self to i8*
1891  %1 = tail call i8* @objc_retain(i8* %0) nounwind
1892  tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0)
1893  tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0)
1894  %ivar = load i64* @"OBJC_IVAR_$_A.myZ", align 8
1895  %add.ptr = getelementptr i8* %0, i64 %ivar
1896  %tmp1 = bitcast i8* %add.ptr to float*
1897  %tmp2 = load float* %tmp1, align 4
1898  %conv = fpext float %tmp2 to double
1899  %add.ptr.sum = add i64 %ivar, 4
1900  %tmp6 = getelementptr inbounds i8* %0, i64 %add.ptr.sum
1901  %2 = bitcast i8* %tmp6 to float*
1902  %tmp7 = load float* %2, align 4
1903  %conv8 = fpext float %tmp7 to double
1904  %add.ptr.sum36 = add i64 %ivar, 8
1905  %tmp12 = getelementptr inbounds i8* %0, i64 %add.ptr.sum36
1906  %arrayidx = bitcast i8* %tmp12 to float*
1907  %tmp13 = load float* %arrayidx, align 4
1908  %conv14 = fpext float %tmp13 to double
1909  %tmp12.sum = add i64 %ivar, 12
1910  %arrayidx19 = getelementptr inbounds i8* %0, i64 %tmp12.sum
1911  %3 = bitcast i8* %arrayidx19 to float*
1912  %tmp20 = load float* %3, align 4
1913  %conv21 = fpext float %tmp20 to double
1914  %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @.str4, i64 0, i64 0), double %conv, double %conv8, double %conv14, double %conv21)
1915  %ivar23 = load i64* @"OBJC_IVAR_$_A.myZ", align 8
1916  %add.ptr24 = getelementptr i8* %0, i64 %ivar23
1917  %4 = bitcast i8* %add.ptr24 to i128*
1918  %srcval = load i128* %4, align 4
1919  tail call void @objc_release(i8* %0) nounwind
1920  %tmp29 = trunc i128 %srcval to i64
1921  %tmp30 = bitcast i64 %tmp29 to <2 x float>
1922  %tmp31 = insertvalue {<2 x float>, <2 x float>} undef, <2 x float> %tmp30, 0
1923  %tmp32 = lshr i128 %srcval, 64
1924  %tmp33 = trunc i128 %tmp32 to i64
1925  %tmp34 = bitcast i64 %tmp33 to <2 x float>
1926  %tmp35 = insertvalue {<2 x float>, <2 x float>} %tmp31, <2 x float> %tmp34, 1
1927  ret {<2 x float>, <2 x float>} %tmp35
1928}
1929
1930; CHECK: @"\01-[Top0 _getX]"
1931; CHECK-NOT: @objc_
1932; CHECK: }
1933
1934define i32 @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) nounwind {
1935invoke.cont:
1936  %0 = bitcast {}* %self to i8*
1937  %1 = tail call i8* @objc_retain(i8* %0) nounwind
1938  %puts = tail call i32 @puts(i8* getelementptr inbounds ([16 x i8]* @str, i64 0, i64 0))
1939  tail call void @objc_release(i8* %0) nounwind
1940  ret i32 0
1941}
1942
1943@"\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]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
1944@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
1945@llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([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"
1946
1947; A simple loop. Eliminate the retain and release inside of it!
1948
1949; CHECK: define void @loop
1950; CHECK: for.body:
1951; CHECK-NOT: @objc_
1952; CHECK: @objc_msgSend
1953; CHECK-NOT: @objc_
1954; CHECK: for.end:
1955define void @loop(i8* %x, i64 %n) {
1956entry:
1957  %0 = tail call i8* @objc_retain(i8* %x) nounwind
1958  %cmp9 = icmp sgt i64 %n, 0
1959  br i1 %cmp9, label %for.body, label %for.end
1960
1961for.body:                                         ; preds = %entry, %for.body
1962  %i.010 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
1963  %1 = tail call i8* @objc_retain(i8* %x) nounwind
1964  %tmp5 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
1965  %call = tail call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %1, i8* %tmp5)
1966  tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0
1967  %inc = add nsw i64 %i.010, 1
1968  %exitcond = icmp eq i64 %inc, %n
1969  br i1 %exitcond, label %for.end, label %for.body
1970
1971for.end:                                          ; preds = %for.body, %entry
1972  tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
1973  ret void
1974}
1975
1976; ObjCARCOpt can delete the retain,release on self.
1977
1978; CHECK: define void @TextEditTest
1979; CHECK-NOT: call i8* @objc_retain(i8* %tmp7)
1980; CHECK: }
1981
1982%0 = type { i8* (i8*, %struct._message_ref_t*, ...)*, i8* }
1983%1 = type opaque
1984%2 = type opaque
1985%3 = type opaque
1986%4 = type opaque
1987%5 = type opaque
1988%struct.NSConstantString = type { i32*, i32, i8*, i64 }
1989%struct._NSRange = type { i64, i64 }
1990%struct.__CFString = type opaque
1991%struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] }
1992%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* }
1993%struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* }
1994%struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] }
1995%struct._ivar_t = type { i64*, i8*, i8*, i32, i32 }
1996%struct._message_ref_t = type { i8*, i8* }
1997%struct._objc_cache = type opaque
1998%struct._objc_method = type { i8*, i8*, i8* }
1999%struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] }
2000%struct._prop_list_t = type { i32, i32, [0 x %struct._message_ref_t] }
2001%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 }
2002
2003@"\01L_OBJC_CLASSLIST_REFERENCES_$_17" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2004@kUTTypePlainText = external constant %struct.__CFString*
2005@"\01L_OBJC_SELECTOR_REFERENCES_19" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2006@"\01L_OBJC_SELECTOR_REFERENCES_21" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2007@"\01L_OBJC_SELECTOR_REFERENCES_23" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2008@"\01L_OBJC_SELECTOR_REFERENCES_25" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2009@"\01L_OBJC_CLASSLIST_REFERENCES_$_26" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2010@"\01L_OBJC_SELECTOR_REFERENCES_28" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2011@"\01L_OBJC_CLASSLIST_REFERENCES_$_29" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2012@"\01L_OBJC_SELECTOR_REFERENCES_31" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2013@"\01L_OBJC_SELECTOR_REFERENCES_33" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2014@"\01L_OBJC_SELECTOR_REFERENCES_35" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2015@"\01L_OBJC_SELECTOR_REFERENCES_37" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2016@"\01L_OBJC_CLASSLIST_REFERENCES_$_38" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2017@"\01L_OBJC_SELECTOR_REFERENCES_40" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2018@"\01L_OBJC_SELECTOR_REFERENCES_42" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2019@_unnamed_cfstring_44 = external hidden constant %struct.NSConstantString, section "__DATA,__cfstring"
2020@"\01L_OBJC_SELECTOR_REFERENCES_46" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2021@"\01L_OBJC_SELECTOR_REFERENCES_48" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2022@"\01l_objc_msgSend_fixup_isEqual_" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16
2023@"\01L_OBJC_CLASSLIST_REFERENCES_$_50" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2024@NSCocoaErrorDomain = external constant %1*
2025@"\01L_OBJC_CLASSLIST_REFERENCES_$_51" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2026@NSFilePathErrorKey = external constant %1*
2027@"\01L_OBJC_SELECTOR_REFERENCES_53" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2028@"\01L_OBJC_SELECTOR_REFERENCES_55" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2029@"\01L_OBJC_CLASSLIST_REFERENCES_$_56" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2030@"\01L_OBJC_SELECTOR_REFERENCES_58" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2031@"\01L_OBJC_SELECTOR_REFERENCES_60" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2032
2033declare %1* @truncatedString(%1*, i64)
2034define void @TextEditTest(%2* %self, %3* %pboard) {
2035entry:
2036  %err = alloca %4*, align 8
2037  %tmp7 = bitcast %2* %self to i8*
2038  %tmp8 = call i8* @objc_retain(i8* %tmp7) nounwind
2039  store %4* null, %4** %err, align 8
2040  %tmp1 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_17", align 8
2041  %tmp2 = load %struct.__CFString** @kUTTypePlainText, align 8
2042  %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_19", align 8
2043  %tmp4 = bitcast %struct._class_t* %tmp1 to i8*
2044  %call5 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp4, i8* %tmp3, %struct.__CFString* %tmp2)
2045  %tmp5 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_21", align 8
2046  %tmp6 = bitcast %3* %pboard to i8*
2047  %call76 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp6, i8* %tmp5, i8* %call5)
2048  %tmp9 = call i8* @objc_retain(i8* %call76) nounwind
2049  %tobool = icmp eq i8* %tmp9, null
2050  br i1 %tobool, label %end, label %land.lhs.true
2051
2052land.lhs.true:                                    ; preds = %entry
2053  %tmp11 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_23", align 8
2054  %call137 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp6, i8* %tmp11, i8* %tmp9)
2055  %tmp = bitcast i8* %call137 to %1*
2056  %tmp10 = call i8* @objc_retain(i8* %call137) nounwind
2057  call void @objc_release(i8* null) nounwind
2058  %tmp12 = call i8* @objc_retain(i8* %call137) nounwind
2059  call void @objc_release(i8* null) nounwind
2060  %tobool16 = icmp eq i8* %call137, null
2061  br i1 %tobool16, label %end, label %if.then
2062
2063if.then:                                          ; preds = %land.lhs.true
2064  %tmp19 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2065  %call21 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %call137, i8* %tmp19)
2066  %tobool22 = icmp eq i8 %call21, 0
2067  br i1 %tobool22, label %if.then44, label %land.lhs.true23
2068
2069land.lhs.true23:                                  ; preds = %if.then
2070  %tmp24 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2071  %tmp26 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2072  %tmp27 = bitcast %struct._class_t* %tmp24 to i8*
2073  %call2822 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp27, i8* %tmp26, i8* %call137)
2074  %tmp13 = bitcast i8* %call2822 to %5*
2075  %tmp14 = call i8* @objc_retain(i8* %call2822) nounwind
2076  call void @objc_release(i8* null) nounwind
2077  %tobool30 = icmp eq i8* %call2822, null
2078  br i1 %tobool30, label %if.then44, label %if.end
2079
2080if.end:                                           ; preds = %land.lhs.true23
2081  %tmp32 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2082  %tmp33 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2083  %tmp34 = bitcast %struct._class_t* %tmp32 to i8*
2084  %call35 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp34, i8* %tmp33)
2085  %tmp37 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2086  %call3923 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call35, i8* %tmp37, i8* %call2822, i32 signext 1, %4** %err)
2087  %cmp = icmp eq i8* %call3923, null
2088  br i1 %cmp, label %if.then44, label %end
2089
2090if.then44:                                        ; preds = %if.end, %land.lhs.true23, %if.then
2091  %url.025 = phi %5* [ %tmp13, %if.end ], [ %tmp13, %land.lhs.true23 ], [ null, %if.then ]
2092  %tmp49 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_35", align 8
2093  %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)
2094  %call513 = extractvalue %struct._NSRange %call51, 0
2095  %call514 = extractvalue %struct._NSRange %call51, 1
2096  %tmp52 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_37", align 8
2097  %call548 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call137, i8* %tmp52, i64 %call513, i64 %call514)
2098  %tmp55 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_38", align 8
2099  %tmp56 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_40", align 8
2100  %tmp57 = bitcast %struct._class_t* %tmp55 to i8*
2101  %call58 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp57, i8* %tmp56)
2102  %tmp59 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_42", align 8
2103  %call6110 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call548, i8* %tmp59, i8* %call58)
2104  %tmp15 = call i8* @objc_retain(i8* %call6110) nounwind
2105  call void @objc_release(i8* %call137) nounwind
2106  %tmp64 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_46", align 8
2107  %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*))
2108  %tobool67 = icmp eq i8 %call66, 0
2109  br i1 %tobool67, label %if.end74, label %if.then68
2110
2111if.then68:                                        ; preds = %if.then44
2112  %tmp70 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_48", align 8
2113  %call7220 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call6110, i8* %tmp70)
2114  %tmp16 = call i8* @objc_retain(i8* %call7220) nounwind
2115  call void @objc_release(i8* %call6110) nounwind
2116  br label %if.end74
2117
2118if.end74:                                         ; preds = %if.then68, %if.then44
2119  %filename.0.in = phi i8* [ %call7220, %if.then68 ], [ %call6110, %if.then44 ]
2120  %filename.0 = bitcast i8* %filename.0.in to %1*
2121  %tmp17 = load i8** bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to i8**), align 16
2122  %tmp18 = bitcast i8* %tmp17 to i8 (i8*, %struct._message_ref_t*, i8*, ...)*
2123  %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)
2124  %tobool79 = icmp eq i8 %call78, 0
2125  br i1 %tobool79, label %land.lhs.true80, label %if.then109
2126
2127land.lhs.true80:                                  ; preds = %if.end74
2128  %tmp82 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2129  %call84 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %filename.0.in, i8* %tmp82)
2130  %tobool86 = icmp eq i8 %call84, 0
2131  br i1 %tobool86, label %if.then109, label %if.end106
2132
2133if.end106:                                        ; preds = %land.lhs.true80
2134  %tmp88 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2135  %tmp90 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2136  %tmp91 = bitcast %struct._class_t* %tmp88 to i8*
2137  %call9218 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp91, i8* %tmp90, i8* %filename.0.in)
2138  %tmp20 = bitcast i8* %call9218 to %5*
2139  %tmp21 = call i8* @objc_retain(i8* %call9218) nounwind
2140  %tmp22 = bitcast %5* %url.025 to i8*
2141  call void @objc_release(i8* %tmp22) nounwind
2142  %tmp94 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2143  %tmp95 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2144  %tmp96 = bitcast %struct._class_t* %tmp94 to i8*
2145  %call97 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp96, i8* %tmp95)
2146  %tmp99 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2147  %call10119 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call97, i8* %tmp99, i8* %call9218, i32 signext 1, %4** %err)
2148  %phitmp = icmp eq i8* %call10119, null
2149  br i1 %phitmp, label %if.then109, label %end
2150
2151if.then109:                                       ; preds = %if.end106, %land.lhs.true80, %if.end74
2152  %url.129 = phi %5* [ %tmp20, %if.end106 ], [ %url.025, %if.end74 ], [ %url.025, %land.lhs.true80 ]
2153  %tmp110 = load %4** %err, align 8
2154  %tobool111 = icmp eq %4* %tmp110, null
2155  br i1 %tobool111, label %if.then112, label %if.end125
2156
2157if.then112:                                       ; preds = %if.then109
2158  %tmp113 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_50", align 8
2159  %tmp114 = load %1** @NSCocoaErrorDomain, align 8
2160  %tmp115 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_51", align 8
2161  %call117 = call %1* @truncatedString(%1* %filename.0, i64 1034)
2162  %tmp118 = load %1** @NSFilePathErrorKey, align 8
2163  %tmp119 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_53", align 8
2164  %tmp120 = bitcast %struct._class_t* %tmp115 to i8*
2165  %call12113 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp120, i8* %tmp119, %1* %call117, %1* %tmp118, i8* null)
2166  %tmp122 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_55", align 8
2167  %tmp123 = bitcast %struct._class_t* %tmp113 to i8*
2168  %call12414 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp123, i8* %tmp122, %1* %tmp114, i64 258, i8* %call12113)
2169  %tmp23 = call i8* @objc_retain(i8* %call12414) nounwind
2170  %tmp25 = call i8* @objc_autorelease(i8* %tmp23) nounwind
2171  %tmp28 = bitcast i8* %tmp25 to %4*
2172  store %4* %tmp28, %4** %err, align 8
2173  br label %if.end125
2174
2175if.end125:                                        ; preds = %if.then112, %if.then109
2176  %tmp127 = phi %4* [ %tmp110, %if.then109 ], [ %tmp28, %if.then112 ]
2177  %tmp126 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_56", align 8
2178  %tmp128 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_58", align 8
2179  %tmp129 = bitcast %struct._class_t* %tmp126 to i8*
2180  %call13015 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp129, i8* %tmp128, %4* %tmp127)
2181  %tmp131 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_60", align 8
2182  %call13317 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call13015, i8* %tmp131)
2183  br label %end
2184
2185end:                                              ; preds = %if.end125, %if.end106, %if.end, %land.lhs.true, %entry
2186  %filename.2 = phi %1* [ %filename.0, %if.end106 ], [ %filename.0, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
2187  %origFilename.0 = phi %1* [ %tmp, %if.end106 ], [ %tmp, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
2188  %url.2 = phi %5* [ %tmp20, %if.end106 ], [ %url.129, %if.end125 ], [ null, %land.lhs.true ], [ null, %entry ], [ %tmp13, %if.end ]
2189  call void @objc_release(i8* %tmp9) nounwind, !clang.imprecise_release !0
2190  %tmp29 = bitcast %5* %url.2 to i8*
2191  call void @objc_release(i8* %tmp29) nounwind, !clang.imprecise_release !0
2192  %tmp30 = bitcast %1* %origFilename.0 to i8*
2193  call void @objc_release(i8* %tmp30) nounwind, !clang.imprecise_release !0
2194  %tmp31 = bitcast %1* %filename.2 to i8*
2195  call void @objc_release(i8* %tmp31) nounwind, !clang.imprecise_release !0
2196  call void @objc_release(i8* %tmp7) nounwind, !clang.imprecise_release !0
2197  ret void
2198}
2199
2200!0 = metadata !{}
2201
2202declare i32 @__gxx_personality_v0(...)
2203