1 ; RUN: opt -basicaa -objc-arc -S < %s | FileCheck %s
3 target datalayout = "e-p:64:64:64"
5 declare i8* @llvm.objc.retain(i8*)
6 declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
7 declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)
8 declare void @llvm.objc.release(i8*)
9 declare i8* @llvm.objc.autorelease(i8*)
10 declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
11 declare void @llvm.objc.autoreleasePoolPop(i8*)
12 declare i8* @llvm.objc.autoreleasePoolPush()
13 declare i8* @llvm.objc.retainBlock(i8*)
15 declare i8* @llvm.objc.retainedObject(i8*)
16 declare i8* @llvm.objc.unretainedObject(i8*)
17 declare i8* @llvm.objc.unretainedPointer(i8*)
19 declare void @use_pointer(i8*)
20 declare void @callee()
21 declare void @callee_fnptr(void ()*)
22 declare void @invokee()
23 declare i8* @returner()
24 declare void @bar(i32 ()*)
26 declare void @llvm.dbg.value(metadata, metadata, metadata)
28 declare i8* @llvm.objc.msgSend(i8*, i8*, ...)
30 ; Simple retain+release pair deletion, with some intervening control
31 ; flow and harmless instructions.
33 ; CHECK: define void @test0_precise(i32* %x, i1 %p) [[NUW:#[0-9]+]] {
34 ; CHECK: @llvm.objc.retain
35 ; CHECK: @llvm.objc.release
37 define void @test0_precise(i32* %x, i1 %p) nounwind {
39 %a = bitcast i32* %x to i8*
40 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
41 br i1 %p, label %t, label %f
45 %b = bitcast i32* %x to float*
46 store float 2.0, float* %b
54 %c = bitcast i32* %x to i8*
55 call void @llvm.objc.release(i8* %c) nounwind
59 ; CHECK: define void @test0_imprecise(i32* %x, i1 %p) [[NUW]] {
60 ; CHECK-NOT: @llvm.objc.
62 define void @test0_imprecise(i32* %x, i1 %p) nounwind {
64 %a = bitcast i32* %x to i8*
65 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
66 br i1 %p, label %t, label %f
70 %b = bitcast i32* %x to float*
71 store float 2.0, float* %b
79 %c = bitcast i32* %x to i8*
80 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
84 ; Like test0 but the release isn't always executed when the retain is,
85 ; so the optimization is not safe.
87 ; TODO: Make the llvm.objc.release's argument be %0.
89 ; CHECK: define void @test1_precise(i32* %x, i1 %p, i1 %q) [[NUW]] {
90 ; CHECK: @llvm.objc.retain(i8* %a)
91 ; CHECK: @llvm.objc.release
93 define void @test1_precise(i32* %x, i1 %p, i1 %q) nounwind {
95 %a = bitcast i32* %x to i8*
96 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
97 br i1 %p, label %t, label %f
101 %b = bitcast i32* %x to float*
102 store float 2.0, float* %b
108 br i1 %q, label %return, label %alt_return
111 %c = bitcast i32* %x to i8*
112 call void @llvm.objc.release(i8* %c) nounwind
119 ; CHECK: define void @test1_imprecise(i32* %x, i1 %p, i1 %q) [[NUW]] {
120 ; CHECK: @llvm.objc.retain(i8* %a)
121 ; CHECK: @llvm.objc.release
123 define void @test1_imprecise(i32* %x, i1 %p, i1 %q) nounwind {
125 %a = bitcast i32* %x to i8*
126 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
127 br i1 %p, label %t, label %f
131 %b = bitcast i32* %x to float*
132 store float 2.0, float* %b
138 br i1 %q, label %return, label %alt_return
141 %c = bitcast i32* %x to i8*
142 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
150 ; Don't do partial elimination into two different CFG diamonds.
152 ; CHECK: define void @test1b_precise(i8* %x, i1 %p, i1 %q) {
154 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
155 ; CHECK-NOT: @llvm.objc.
157 ; CHECK: tail call void @llvm.objc.release(i8* %x) [[NUW]]
158 ; CHECK-NOT: @llvm.objc.
160 define void @test1b_precise(i8* %x, i1 %p, i1 %q) {
162 tail call i8* @llvm.objc.retain(i8* %x) nounwind
163 br i1 %p, label %if.then, label %if.end
165 if.then: ; preds = %entry
166 tail call void @callee()
169 if.end: ; preds = %if.then, %entry
170 br i1 %q, label %if.then3, label %if.end5
172 if.then3: ; preds = %if.end
173 tail call void @use_pointer(i8* %x)
176 if.end5: ; preds = %if.then3, %if.end
177 tail call void @llvm.objc.release(i8* %x) nounwind
181 ; CHECK-LABEL: define void @test1b_imprecise(
183 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW:#[0-9]+]]
184 ; CHECK-NOT: @llvm.objc.
186 ; CHECK: tail call void @llvm.objc.release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE:[0-9]+]]
187 ; CHECK-NOT: @llvm.objc.
189 define void @test1b_imprecise(i8* %x, i1 %p, i1 %q) {
191 tail call i8* @llvm.objc.retain(i8* %x) nounwind
192 br i1 %p, label %if.then, label %if.end
194 if.then: ; preds = %entry
195 tail call void @callee()
198 if.end: ; preds = %if.then, %entry
199 br i1 %q, label %if.then3, label %if.end5
201 if.then3: ; preds = %if.end
202 tail call void @use_pointer(i8* %x)
205 if.end5: ; preds = %if.then3, %if.end
206 tail call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
211 ; Like test0 but the pointer is passed to an intervening call,
212 ; so the optimization is not safe.
214 ; CHECK-LABEL: define void @test2_precise(
215 ; CHECK: @llvm.objc.retain(i8* %a)
216 ; CHECK: @llvm.objc.release
218 define void @test2_precise(i32* %x, i1 %p) nounwind {
220 %a = bitcast i32* %x to i8*
221 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
222 br i1 %p, label %t, label %f
226 %b = bitcast i32* %x to float*
227 store float 2.0, float* %b
232 call void @use_pointer(i8* %0)
233 %d = bitcast i32* %x to float*
234 store float 3.0, float* %d
238 %c = bitcast i32* %x to i8*
239 call void @llvm.objc.release(i8* %c) nounwind
243 ; CHECK-LABEL: define void @test2_imprecise(
244 ; CHECK: @llvm.objc.retain(i8* %a)
245 ; CHECK: @llvm.objc.release
247 define void @test2_imprecise(i32* %x, i1 %p) nounwind {
249 %a = bitcast i32* %x to i8*
250 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
251 br i1 %p, label %t, label %f
255 %b = bitcast i32* %x to float*
256 store float 2.0, float* %b
261 call void @use_pointer(i8* %0)
262 %d = bitcast i32* %x to float*
263 store float 3.0, float* %d
267 %c = bitcast i32* %x to i8*
268 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
272 ; Like test0 but the release is in a loop,
273 ; so the optimization is not safe.
275 ; TODO: For now, assume this can't happen.
277 ; CHECK-LABEL: define void @test3_precise(
278 ; TODO: @llvm.objc.retain(i8* %a)
279 ; TODO: @llvm.objc.release
281 define void @test3_precise(i32* %x, i1* %q) nounwind {
283 %a = bitcast i32* %x to i8*
284 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
288 %c = bitcast i32* %x to i8*
289 call void @llvm.objc.release(i8* %c) nounwind
290 %j = load volatile i1, i1* %q
291 br i1 %j, label %loop, label %return
297 ; CHECK-LABEL: define void @test3_imprecise(
298 ; TODO: @llvm.objc.retain(i8* %a)
299 ; TODO: @llvm.objc.release
301 define void @test3_imprecise(i32* %x, i1* %q) nounwind {
303 %a = bitcast i32* %x to i8*
304 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
308 %c = bitcast i32* %x to i8*
309 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
310 %j = load volatile i1, i1* %q
311 br i1 %j, label %loop, label %return
318 ; TODO: For now, assume this can't happen.
320 ; Like test0 but the retain is in a loop,
321 ; so the optimization is not safe.
323 ; CHECK-LABEL: define void @test4_precise(
324 ; TODO: @llvm.objc.retain(i8* %a)
325 ; TODO: @llvm.objc.release
327 define void @test4_precise(i32* %x, i1* %q) nounwind {
332 %a = bitcast i32* %x to i8*
333 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
334 %j = load volatile i1, i1* %q
335 br i1 %j, label %loop, label %return
338 %c = bitcast i32* %x to i8*
339 call void @llvm.objc.release(i8* %c) nounwind
343 ; CHECK-LABEL: define void @test4_imprecise(
344 ; TODO: @llvm.objc.retain(i8* %a)
345 ; TODO: @llvm.objc.release
347 define void @test4_imprecise(i32* %x, i1* %q) nounwind {
352 %a = bitcast i32* %x to i8*
353 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
354 %j = load volatile i1, i1* %q
355 br i1 %j, label %loop, label %return
358 %c = bitcast i32* %x to i8*
359 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
364 ; Like test0 but the pointer is conditionally passed to an intervening call,
365 ; so the optimization is not safe.
367 ; CHECK-LABEL: define void @test5a(
368 ; CHECK: @llvm.objc.retain(i8*
369 ; CHECK: @llvm.objc.release
371 define void @test5a(i32* %x, i1 %q, i8* %y) nounwind {
373 %a = bitcast i32* %x to i8*
374 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
375 %s = select i1 %q, i8* %y, i8* %0
376 call void @use_pointer(i8* %s)
378 %c = bitcast i32* %x to i8*
379 call void @llvm.objc.release(i8* %c) nounwind
383 ; CHECK-LABEL: define void @test5b(
384 ; CHECK: @llvm.objc.retain(i8*
385 ; CHECK: @llvm.objc.release
387 define void @test5b(i32* %x, i1 %q, i8* %y) nounwind {
389 %a = bitcast i32* %x to i8*
390 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
391 %s = select i1 %q, i8* %y, i8* %0
392 call void @use_pointer(i8* %s)
394 %c = bitcast i32* %x to i8*
395 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
400 ; retain+release pair deletion, where the release happens on two different
403 ; CHECK-LABEL: define void @test6a(
405 ; CHECK: tail call i8* @llvm.objc.retain
407 ; CHECK: call void @llvm.objc.release
409 ; CHECK: call void @llvm.objc.release
412 define void @test6a(i32* %x, i1 %p) nounwind {
414 %a = bitcast i32* %x to i8*
415 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
416 br i1 %p, label %t, label %f
420 %b = bitcast i32* %x to float*
421 store float 2.0, float* %b
422 %ct = bitcast i32* %x to i8*
423 call void @llvm.objc.release(i8* %ct) nounwind
429 %cf = bitcast i32* %x to i8*
430 call void @llvm.objc.release(i8* %cf) nounwind
437 ; CHECK-LABEL: define void @test6b(
438 ; CHECK-NOT: @llvm.objc.
440 define void @test6b(i32* %x, i1 %p) nounwind {
442 %a = bitcast i32* %x to i8*
443 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
444 br i1 %p, label %t, label %f
448 %b = bitcast i32* %x to float*
449 store float 2.0, float* %b
450 %ct = bitcast i32* %x to i8*
451 call void @llvm.objc.release(i8* %ct) nounwind, !clang.imprecise_release !0
457 %cf = bitcast i32* %x to i8*
458 call void @llvm.objc.release(i8* %cf) nounwind, !clang.imprecise_release !0
465 ; CHECK-LABEL: define void @test6c(
467 ; CHECK: tail call i8* @llvm.objc.retain
469 ; CHECK: call void @llvm.objc.release
471 ; CHECK: call void @llvm.objc.release
474 define void @test6c(i32* %x, i1 %p) nounwind {
476 %a = bitcast i32* %x to i8*
477 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
478 br i1 %p, label %t, label %f
482 %b = bitcast i32* %x to float*
483 store float 2.0, float* %b
484 %ct = bitcast i32* %x to i8*
485 call void @llvm.objc.release(i8* %ct) nounwind
491 %cf = bitcast i32* %x to i8*
492 call void @llvm.objc.release(i8* %cf) nounwind, !clang.imprecise_release !0
499 ; CHECK-LABEL: define void @test6d(
501 ; CHECK: tail call i8* @llvm.objc.retain
503 ; CHECK: call void @llvm.objc.release
505 ; CHECK: call void @llvm.objc.release
508 define void @test6d(i32* %x, i1 %p) nounwind {
510 %a = bitcast i32* %x to i8*
511 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
512 br i1 %p, label %t, label %f
516 %b = bitcast i32* %x to float*
517 store float 2.0, float* %b
518 %ct = bitcast i32* %x to i8*
519 call void @llvm.objc.release(i8* %ct) nounwind, !clang.imprecise_release !0
525 %cf = bitcast i32* %x to i8*
526 call void @llvm.objc.release(i8* %cf) nounwind
534 ; retain+release pair deletion, where the retain happens on two different
537 ; CHECK-LABEL: define void @test7(
539 ; CHECK-NOT: llvm.objc.
541 ; CHECK: call i8* @llvm.objc.retain
543 ; CHECK: call i8* @llvm.objc.retain
545 ; CHECK: call void @llvm.objc.release
547 define void @test7(i32* %x, i1 %p) nounwind {
549 %a = bitcast i32* %x to i8*
550 br i1 %p, label %t, label %f
553 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
555 %b = bitcast i32* %x to float*
556 store float 2.0, float* %b
560 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
566 %c = bitcast i32* %x to i8*
567 call void @llvm.objc.release(i8* %c) nounwind
571 ; CHECK-LABEL: define void @test7b(
572 ; CHECK-NOT: @llvm.objc.
574 define void @test7b(i32* %x, i1 %p) nounwind {
576 %a = bitcast i32* %x to i8*
577 br i1 %p, label %t, label %f
580 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
582 %b = bitcast i32* %x to float*
583 store float 2.0, float* %b
587 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
593 %c = bitcast i32* %x to i8*
594 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
598 ; Like test7, but there's a retain/retainBlock mismatch. Don't delete!
600 ; CHECK-LABEL: define void @test7c(
602 ; CHECK: call i8* @llvm.objc.retainBlock
604 ; CHECK: call i8* @llvm.objc.retain
606 ; CHECK: call void @llvm.objc.release
608 define void @test7c(i32* %x, i1 %p) nounwind {
610 %a = bitcast i32* %x to i8*
611 br i1 %p, label %t, label %f
614 %0 = call i8* @llvm.objc.retainBlock(i8* %a) nounwind
616 %b = bitcast i32* %x to float*
617 store float 2.0, float* %b
621 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
627 %c = bitcast i32* %x to i8*
628 call void @llvm.objc.release(i8* %c) nounwind
632 ; retain+release pair deletion, where the retain and release both happen on
633 ; different flow paths. Wild!
635 ; CHECK-LABEL: define void @test8a(
638 ; CHECK: @llvm.objc.retain
640 ; CHECK: @llvm.objc.retain
643 ; CHECK: @llvm.objc.release
645 ; CHECK: @llvm.objc.release
648 define void @test8a(i32* %x, i1 %p, i1 %q) nounwind {
650 %a = bitcast i32* %x to i8*
651 br i1 %p, label %t, label %f
654 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
656 %b = bitcast i32* %x to float*
657 store float 2.0, float* %b
661 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
666 br i1 %q, label %u, label %g
670 %cu = bitcast i32* %x to i8*
671 call void @llvm.objc.release(i8* %cu) nounwind
675 %cg = bitcast i32* %x to i8*
676 call void @llvm.objc.release(i8* %cg) nounwind
683 ; CHECK-LABEL: define void @test8b(
684 ; CHECK-NOT: @llvm.objc.
686 define void @test8b(i32* %x, i1 %p, i1 %q) nounwind {
688 %a = bitcast i32* %x to i8*
689 br i1 %p, label %t, label %f
692 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
694 %b = bitcast i32* %x to float*
695 store float 2.0, float* %b
699 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
704 br i1 %q, label %u, label %g
708 %cu = bitcast i32* %x to i8*
709 call void @llvm.objc.release(i8* %cu) nounwind, !clang.imprecise_release !0
713 %cg = bitcast i32* %x to i8*
714 call void @llvm.objc.release(i8* %cg) nounwind, !clang.imprecise_release !0
721 ; CHECK-LABEL: define void @test8c(
724 ; CHECK: @llvm.objc.retain
726 ; CHECK: @llvm.objc.retain
729 ; CHECK: @llvm.objc.release
731 ; CHECK: @llvm.objc.release
734 define void @test8c(i32* %x, i1 %p, i1 %q) nounwind {
736 %a = bitcast i32* %x to i8*
737 br i1 %p, label %t, label %f
740 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
742 %b = bitcast i32* %x to float*
743 store float 2.0, float* %b
747 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
752 br i1 %q, label %u, label %g
756 %cu = bitcast i32* %x to i8*
757 call void @llvm.objc.release(i8* %cu) nounwind
761 %cg = bitcast i32* %x to i8*
762 call void @llvm.objc.release(i8* %cg) nounwind, !clang.imprecise_release !0
769 ; CHECK-LABEL: define void @test8d(
772 ; CHECK: @llvm.objc.retain
774 ; CHECK: @llvm.objc.retain
777 ; CHECK: @llvm.objc.release
779 ; CHECK: @llvm.objc.release
782 define void @test8d(i32* %x, i1 %p, i1 %q) nounwind {
784 %a = bitcast i32* %x to i8*
785 br i1 %p, label %t, label %f
788 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
790 %b = bitcast i32* %x to float*
791 store float 2.0, float* %b
795 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
800 br i1 %q, label %u, label %g
804 %cu = bitcast i32* %x to i8*
805 call void @llvm.objc.release(i8* %cu) nounwind, !clang.imprecise_release !0
809 %cg = bitcast i32* %x to i8*
810 call void @llvm.objc.release(i8* %cg) nounwind
817 ; Trivial retain+release pair deletion.
819 ; CHECK-LABEL: define void @test9(
820 ; CHECK-NOT: @llvm.objc.
822 define void @test9(i8* %x) nounwind {
824 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
825 call void @llvm.objc.release(i8* %0) nounwind
829 ; Retain+release pair, but on an unknown pointer relationship. Don't delete!
831 ; CHECK-LABEL: define void @test9b(
832 ; CHECK: @llvm.objc.retain(i8* %x)
833 ; CHECK: @llvm.objc.release(i8* %s)
835 define void @test9b(i8* %x, i1 %j, i8* %p) nounwind {
837 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
838 %s = select i1 %j, i8* %x, i8* %p
839 call void @llvm.objc.release(i8* %s) nounwind
843 ; Trivial retain+release pair with intervening calls - don't delete!
845 ; CHECK-LABEL: define void @test10(
846 ; CHECK: @llvm.objc.retain(i8* %x)
848 ; CHECK: @use_pointer
849 ; CHECK: @llvm.objc.release
851 define void @test10(i8* %x) nounwind {
853 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
855 call void @use_pointer(i8* %x)
856 call void @llvm.objc.release(i8* %0) nounwind
860 ; Trivial retain+autoreleaserelease pair. Don't delete!
861 ; Also, add a tail keyword, since llvm.objc.retain can never be passed
864 ; CHECK-LABEL: define void @test11(
865 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
866 ; CHECK: call i8* @llvm.objc.autorelease(i8* %0) [[NUW]]
868 define void @test11(i8* %x) nounwind {
870 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
871 call i8* @llvm.objc.autorelease(i8* %0) nounwind
872 call void @use_pointer(i8* %x)
876 ; Same as test11 but with no use_pointer call. Delete the pair!
878 ; CHECK-LABEL: define void @test11a(
880 ; CHECK-NEXT: ret void
882 define void @test11a(i8* %x) nounwind {
884 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
885 call i8* @llvm.objc.autorelease(i8* %0) nounwind
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.
893 ; CHECK-LABEL: define i8* @test11b(
894 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
895 ; CHECK: call i8* @llvm.objc.autorelease(i8* %0) [[NUW]]
897 define i8* @test11b(i8* %x) nounwind {
899 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
900 call i8* @llvm.objc.autorelease(i8* %0) nounwind
904 ; We can not delete this retain, release since we do not have a post-dominating
905 ; use of the release.
907 ; CHECK-LABEL: define void @test12(
909 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
910 ; CHECK-NEXT: @llvm.objc.retain
911 ; CHECK: @llvm.objc.release
913 define void @test12(i8* %x, i64 %n) {
915 call i8* @llvm.objc.retain(i8* %x) nounwind
916 call i8* @llvm.objc.retain(i8* %x) nounwind
917 call void @use_pointer(i8* %x)
918 call void @use_pointer(i8* %x)
919 call void @llvm.objc.release(i8* %x) nounwind
923 ; Trivial retain,autorelease pair. Don't delete!
925 ; CHECK-LABEL: define void @test13(
926 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
927 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
928 ; CHECK: @use_pointer(i8* %x)
929 ; CHECK: call i8* @llvm.objc.autorelease(i8* %x) [[NUW]]
931 define void @test13(i8* %x, i64 %n) {
933 call i8* @llvm.objc.retain(i8* %x) nounwind
934 call i8* @llvm.objc.retain(i8* %x) nounwind
935 call void @use_pointer(i8* %x)
936 call i8* @llvm.objc.autorelease(i8* %x) nounwind
940 ; Delete the retain+release pair.
942 ; CHECK-LABEL: define void @test13b(
944 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
945 ; CHECK-NEXT: @use_pointer
946 ; CHECK-NEXT: @use_pointer
947 ; CHECK-NEXT: @use_pointer
948 ; CHECK-NEXT: @llvm.objc.release
949 ; CHECK-NEXT: ret void
951 define void @test13b(i8* %x, i64 %n) {
953 call i8* @llvm.objc.retain(i8* %x) nounwind
954 call i8* @llvm.objc.retain(i8* %x) nounwind
955 call void @use_pointer(i8* %x)
956 call void @use_pointer(i8* %x)
957 call void @llvm.objc.release(i8* %x) nounwind
958 call void @use_pointer(i8* %x)
959 call void @llvm.objc.release(i8* %x) nounwind
963 ; Don't delete the retain+release pair because there's an
964 ; autoreleasePoolPop in the way.
966 ; CHECK-LABEL: define void @test13c(
967 ; CHECK: @llvm.objc.retain(i8* %x)
968 ; CHECK: @llvm.objc.autoreleasePoolPop
969 ; CHECK: @llvm.objc.retain(i8* %x)
970 ; CHECK: @use_pointer
971 ; CHECK: @llvm.objc.release
973 define void @test13c(i8* %x, i64 %n) {
975 call i8* @llvm.objc.retain(i8* %x) nounwind
976 call void @llvm.objc.autoreleasePoolPop(i8* undef)
977 call i8* @llvm.objc.retain(i8* %x) nounwind
978 call void @use_pointer(i8* %x)
979 call void @use_pointer(i8* %x)
980 call void @llvm.objc.release(i8* %x) nounwind
984 ; Like test13c, but there's an autoreleasePoolPush in the way, but that
987 ; CHECK-LABEL: define void @test13d(
989 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
990 ; CHECK-NEXT: @llvm.objc.autoreleasePoolPush
991 ; CHECK-NEXT: @use_pointer
992 ; CHECK-NEXT: @use_pointer
993 ; CHECK-NEXT: @use_pointer
994 ; CHECK-NEXT: @llvm.objc.release
995 ; CHECK-NEXT: ret void
997 define void @test13d(i8* %x, i64 %n) {
999 call i8* @llvm.objc.retain(i8* %x) nounwind
1000 call i8* @llvm.objc.autoreleasePoolPush()
1001 call i8* @llvm.objc.retain(i8* %x) nounwind
1002 call void @use_pointer(i8* %x)
1003 call void @use_pointer(i8* %x)
1004 call void @llvm.objc.release(i8* %x) nounwind
1005 call void @use_pointer(i8* %x)
1006 call void @llvm.objc.release(i8* %x) nounwind
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
1014 ; CHECK-LABEL: define void @test14(
1015 ; CHECK-NEXT: entry:
1016 ; CHECK-NEXT: @llvm.objc.retain
1017 ; CHECK-NEXT: @use_pointer
1018 ; CHECK-NEXT: @use_pointer
1019 ; CHECK-NEXT: @llvm.objc.release
1020 ; CHECK-NEXT: @llvm.objc.release
1021 ; CHECK-NEXT: ret void
1023 define void @test14(i8* %x, i64 %n) {
1025 call i8* @llvm.objc.retain(i8* %x) nounwind
1026 call void @use_pointer(i8* %x)
1027 call void @use_pointer(i8* %x)
1028 call void @llvm.objc.release(i8* %x) nounwind
1029 call void @llvm.objc.release(i8* %x) nounwind
1033 ; Trivial retain,autorelease pair with intervening call, but it's post-dominated
1034 ; by another release. Don't delete anything.
1036 ; CHECK-LABEL: define void @test15(
1037 ; CHECK-NEXT: entry:
1038 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
1039 ; CHECK-NEXT: @use_pointer
1040 ; CHECK-NEXT: @llvm.objc.autorelease(i8* %x)
1041 ; CHECK-NEXT: @llvm.objc.release
1042 ; CHECK-NEXT: ret void
1044 define void @test15(i8* %x, i64 %n) {
1046 call i8* @llvm.objc.retain(i8* %x) nounwind
1047 call void @use_pointer(i8* %x)
1048 call i8* @llvm.objc.autorelease(i8* %x) nounwind
1049 call void @llvm.objc.release(i8* %x) nounwind
1053 ; Trivial retain,autorelease pair, post-dominated
1054 ; by another release. Delete the retain and release.
1056 ; CHECK-LABEL: define void @test15b(
1057 ; CHECK-NEXT: entry:
1058 ; CHECK-NEXT: @llvm.objc.retain
1059 ; CHECK-NEXT: @llvm.objc.autorelease
1060 ; CHECK-NEXT: @llvm.objc.release
1061 ; CHECK-NEXT: ret void
1063 define void @test15b(i8* %x, i64 %n) {
1065 call i8* @llvm.objc.retain(i8* %x) nounwind
1066 call i8* @llvm.objc.autorelease(i8* %x) nounwind
1067 call void @llvm.objc.release(i8* %x) nounwind
1071 ; CHECK-LABEL: define void @test15c(
1072 ; CHECK-NEXT: entry:
1073 ; CHECK-NEXT: @llvm.objc.autorelease
1074 ; CHECK-NEXT: ret void
1076 define void @test15c(i8* %x, i64 %n) {
1078 call i8* @llvm.objc.retain(i8* %x) nounwind
1079 call i8* @llvm.objc.autorelease(i8* %x) nounwind
1080 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1084 ; Retain+release pairs in diamonds, all dominated by a retain.
1086 ; CHECK-LABEL: define void @test16a(
1087 ; CHECK: @llvm.objc.retain(i8* %x)
1090 ; CHECK: @use_pointer
1091 ; CHECK: @llvm.objc.release
1093 define void @test16a(i1 %a, i1 %b, i8* %x) {
1095 call i8* @llvm.objc.retain(i8* %x) nounwind
1096 br i1 %a, label %red, label %orange
1099 call i8* @llvm.objc.retain(i8* %x) nounwind
1103 call i8* @llvm.objc.retain(i8* %x) nounwind
1107 call void @use_pointer(i8* %x)
1108 call void @use_pointer(i8* %x)
1109 br i1 %b, label %green, label %blue
1112 call void @llvm.objc.release(i8* %x) nounwind
1116 call void @llvm.objc.release(i8* %x) nounwind
1120 call void @use_pointer(i8* %x)
1121 call void @llvm.objc.release(i8* %x) nounwind
1125 ; CHECK-LABEL: define void @test16b(
1126 ; CHECK: @llvm.objc.retain(i8* %x)
1129 ; CHECK-NEXT: @use_pointer
1130 ; CHECK-NEXT: @use_pointer
1131 ; CHECK-NEXT: @llvm.objc.release
1133 define void @test16b(i1 %a, i1 %b, i8* %x) {
1135 call i8* @llvm.objc.retain(i8* %x) nounwind
1136 br i1 %a, label %red, label %orange
1139 call i8* @llvm.objc.retain(i8* %x) nounwind
1143 call i8* @llvm.objc.retain(i8* %x) nounwind
1147 call void @use_pointer(i8* %x)
1148 call void @use_pointer(i8* %x)
1149 br i1 %b, label %green, label %blue
1152 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1156 call void @llvm.objc.release(i8* %x) nounwind
1160 call void @use_pointer(i8* %x)
1161 call void @use_pointer(i8* %x)
1162 call void @llvm.objc.release(i8* %x) nounwind
1166 ; CHECK-LABEL: define void @test16c(
1167 ; CHECK: @llvm.objc.retain(i8* %x)
1170 ; CHECK: @use_pointer
1171 ; CHECK: @llvm.objc.release
1173 define void @test16c(i1 %a, i1 %b, i8* %x) {
1175 call i8* @llvm.objc.retain(i8* %x) nounwind
1176 br i1 %a, label %red, label %orange
1179 call i8* @llvm.objc.retain(i8* %x) nounwind
1183 call i8* @llvm.objc.retain(i8* %x) nounwind
1187 call void @use_pointer(i8* %x)
1188 call void @use_pointer(i8* %x)
1189 br i1 %b, label %green, label %blue
1192 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1196 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1200 call void @use_pointer(i8* %x)
1201 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1205 ; CHECK-LABEL: define void @test16d(
1206 ; CHECK: @llvm.objc.retain(i8* %x)
1209 define void @test16d(i1 %a, i1 %b, i8* %x) {
1211 call i8* @llvm.objc.retain(i8* %x) nounwind
1212 br i1 %a, label %red, label %orange
1215 call i8* @llvm.objc.retain(i8* %x) nounwind
1219 call i8* @llvm.objc.retain(i8* %x) nounwind
1223 call void @use_pointer(i8* %x)
1224 call void @use_pointer(i8* %x)
1225 br i1 %b, label %green, label %blue
1228 call void @llvm.objc.release(i8* %x) nounwind
1232 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1241 ; CHECK-LABEL: define void @test18(
1242 ; CHECK-NOT: @llvm.objc.
1244 define void @test18() {
1245 call i8* @llvm.objc.retain(i8* null)
1246 call void @llvm.objc.release(i8* null)
1247 call i8* @llvm.objc.autorelease(i8* null)
1251 ; Delete no-ops where undef can be assumed to be null.
1253 ; CHECK-LABEL: define void @test18b(
1254 ; CHECK-NOT: @llvm.objc.
1256 define void @test18b() {
1257 call i8* @llvm.objc.retain(i8* undef)
1258 call void @llvm.objc.release(i8* undef)
1259 call i8* @llvm.objc.autorelease(i8* undef)
1263 ; Replace uses of arguments with uses of return values, to reduce
1264 ; register pressure.
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* @llvm.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 @llvm.objc.release(i8* %2)
1276 define void @test19(i32* %y) {
1278 %x = bitcast i32* %y to i8*
1279 %0 = call i8* @llvm.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 @llvm.objc.release(i8* %x)
1289 ; CHECK-LABEL: define void @test20(
1290 ; CHECK: %tmp1 = tail call i8* @llvm.objc.retain(i8* %tmp) [[NUW]]
1291 ; CHECK-NEXT: invoke
1293 define void @test20(double* %self) personality i32 (...)* @__gxx_personality_v0 {
1295 %tmp = bitcast double* %self to i8*
1296 %tmp1 = call i8* @llvm.objc.retain(i8* %tmp) nounwind
1297 invoke void @invokee()
1298 to label %invoke.cont23 unwind label %lpad20
1300 invoke.cont23: ; preds = %if.then12
1301 invoke void @invokee()
1302 to label %if.end unwind label %lpad20
1304 lpad20: ; preds = %invoke.cont23, %if.then12
1305 %tmp502 = phi double* [ undef, %invoke.cont23 ], [ %self, %if.then12 ]
1306 %exn = landingpad {i8*, i32}
1310 if.end: ; preds = %invoke.cont23
1314 ; Delete a redundant retain,autorelease when forwaring a call result
1315 ; directly to a return value.
1317 ; CHECK-LABEL: define i8* @test21(
1318 ; CHECK: call i8* @returner()
1319 ; CHECK-NEXT: ret i8* %call
1321 define i8* @test21() {
1323 %call = call i8* @returner()
1324 %0 = call i8* @llvm.objc.retain(i8* %call) nounwind
1325 %1 = call i8* @llvm.objc.autorelease(i8* %0) nounwind
1329 ; Move an objc call up through a phi that has null operands.
1331 ; CHECK-LABEL: define void @test22(
1333 ; CHECK: %1 = bitcast double* %p to i8*
1334 ; CHECK: call void @llvm.objc.release(i8* %1)
1335 ; CHECK: br label %C
1336 ; CHECK: C: ; preds = %B, %A
1337 ; CHECK-NOT: @llvm.objc.release
1339 define void @test22(double* %p, i1 %a) {
1340 br i1 %a, label %A, label %B
1346 %h = phi double* [ null, %A ], [ %p, %B ]
1347 %c = bitcast double* %h to i8*
1348 call void @llvm.objc.release(i8* %c), !clang.imprecise_release !0
1352 ; Do not move an llvm.objc.release that doesn't have the clang.imprecise_release tag.
1354 ; CHECK-LABEL: define void @test22_precise(
1355 ; CHECK: %[[P0:.*]] = phi double*
1356 ; CHECK: %[[V0:.*]] = bitcast double* %[[P0]] to i8*
1357 ; CHECK: call void @llvm.objc.release(i8* %[[V0]])
1359 define void @test22_precise(double* %p, i1 %a) {
1360 br i1 %a, label %A, label %B
1366 %h = phi double* [ null, %A ], [ %p, %B ]
1367 %c = bitcast double* %h to i8*
1368 call void @llvm.objc.release(i8* %c)
1372 ; Any call can decrement a retain count.
1374 ; CHECK-LABEL: define void @test24(
1375 ; CHECK: @llvm.objc.retain(i8* %a)
1376 ; CHECK: @llvm.objc.release
1378 define void @test24(i8* %r, i8* %a) {
1379 call i8* @llvm.objc.retain(i8* %a)
1380 call void @use_pointer(i8* %r)
1381 %q = load i8, i8* %a
1382 call void @llvm.objc.release(i8* %a)
1386 ; Don't move a retain/release pair if the release can be moved
1387 ; but the retain can't be moved to balance it.
1389 ; CHECK-LABEL: define void @test25(
1391 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1394 ; CHECK: call void @llvm.objc.release(i8* %p)
1396 define void @test25(i8* %p, i1 %x) {
1398 %f0 = call i8* @llvm.objc.retain(i8* %p)
1400 br i1 %x, label %true, label %done
1407 call void @llvm.objc.release(i8* %p)
1411 ; Don't move a retain/release pair if the retain can be moved
1412 ; but the release can't be moved to balance it.
1414 ; CHECK-LABEL: define void @test26(
1416 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1419 ; CHECK: call void @llvm.objc.release(i8* %p)
1421 define void @test26(i8* %p, i1 %x) {
1423 %f0 = call i8* @llvm.objc.retain(i8* %p)
1424 br i1 %x, label %true, label %done
1432 call void @llvm.objc.release(i8* %p)
1436 ; Don't sink the retain,release into the loop.
1438 ; CHECK-LABEL: define void @test27(
1440 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1442 ; CHECK-NOT: @llvm.objc.
1444 ; CHECK: call void @llvm.objc.release
1446 define void @test27(i8* %p, i1 %x, i1 %y) {
1448 %f0 = call i8* @llvm.objc.retain(i8* %p)
1449 br i1 %x, label %loop, label %done
1454 br i1 %y, label %done, label %loop
1457 call void @llvm.objc.release(i8* %p)
1461 ; Trivial code motion case: Triangle.
1463 ; CHECK-LABEL: define void @test28(
1464 ; CHECK-NOT: @llvm.objc.
1466 ; CHECK: call i8* @llvm.objc.retain
1467 ; CHECK: call void @callee()
1469 ; CHECK: call void @llvm.objc.release
1471 ; CHECK-NOT: @llvm.objc.
1473 define void @test28(i8* %p, i1 %x) {
1475 %f0 = call i8* @llvm.objc.retain(i8* %p)
1476 br i1 %x, label %true, label %done
1484 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1488 ; Trivial code motion case: Triangle, but no metadata. Don't move past
1489 ; unrelated memory references!
1491 ; CHECK-LABEL: define void @test28b(
1492 ; CHECK: call i8* @llvm.objc.retain
1494 ; CHECK-NOT: @llvm.objc.
1495 ; CHECK: call void @callee()
1496 ; CHECK-NOT: @llvm.objc.
1498 ; CHECK-NOT: @llvm.objc.
1500 ; CHECK: @llvm.objc.release
1502 define void @test28b(i8* %p, i1 %x, i8* noalias %t) {
1504 %f0 = call i8* @llvm.objc.retain(i8* %p)
1505 br i1 %x, label %true, label %done
1514 call void @llvm.objc.release(i8* %p)
1518 ; Trivial code motion case: Triangle, with metadata. Do move past
1519 ; unrelated memory references! And preserve the metadata.
1521 ; CHECK-LABEL: define void @test28c(
1522 ; CHECK-NOT: @llvm.objc.
1524 ; CHECK: call i8* @llvm.objc.retain
1525 ; CHECK: call void @callee()
1527 ; CHECK: call void @llvm.objc.release(i8* %p) [[NUW]], !clang.imprecise_release
1529 ; CHECK-NOT: @llvm.objc.
1531 define void @test28c(i8* %p, i1 %x, i8* noalias %t) {
1533 %f0 = call i8* @llvm.objc.retain(i8* %p)
1534 br i1 %x, label %true, label %done
1543 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1547 ; Like test28. but with two releases.
1549 ; CHECK-LABEL: define void @test29(
1550 ; CHECK-NOT: @llvm.objc.
1552 ; CHECK: call i8* @llvm.objc.retain
1553 ; CHECK: call void @callee()
1555 ; CHECK: call void @llvm.objc.release
1556 ; CHECK-NOT: @llvm.objc.release
1558 ; CHECK-NOT: @llvm.objc.
1560 ; CHECK-NOT: @llvm.objc.
1562 define void @test29(i8* %p, i1 %x, i1 %y) {
1564 %f0 = call i8* @llvm.objc.retain(i8* %p)
1565 br i1 %x, label %true, label %done
1570 br i1 %y, label %done, label %ohno
1573 call void @llvm.objc.release(i8* %p)
1577 call void @llvm.objc.release(i8* %p)
1581 ; Basic case with the use and call in a diamond
1582 ; with an extra release.
1584 ; CHECK-LABEL: define void @test30(
1585 ; CHECK-NOT: @llvm.objc.
1587 ; CHECK: call i8* @llvm.objc.retain
1588 ; CHECK: call void @callee()
1590 ; CHECK: call void @llvm.objc.release
1591 ; CHECK-NOT: @llvm.objc.release
1593 ; CHECK-NOT: @llvm.objc.
1595 ; CHECK-NOT: @llvm.objc.
1597 ; CHECK-NOT: @llvm.objc.
1599 define void @test30(i8* %p, i1 %x, i1 %y, i1 %z) {
1601 %f0 = call i8* @llvm.objc.retain(i8* %p)
1602 br i1 %x, label %true, label %false
1607 br i1 %y, label %done, label %ohno
1610 br i1 %z, label %done, label %ohno
1613 call void @llvm.objc.release(i8* %p)
1617 call void @llvm.objc.release(i8* %p)
1621 ; Basic case with a mergeable release.
1623 ; CHECK-LABEL: define void @test31(
1624 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1625 ; CHECK: call void @callee()
1627 ; CHECK: call void @llvm.objc.release
1628 ; CHECK-NOT: @llvm.objc.release
1630 ; CHECK-NOT: @llvm.objc.release
1632 ; CHECK-NOT: @llvm.objc.release
1634 ; CHECK-NOT: @llvm.objc.release
1636 define void @test31(i8* %p, i1 %x) {
1638 %f0 = call i8* @llvm.objc.retain(i8* %p)
1641 br i1 %x, label %true, label %false
1643 call void @llvm.objc.release(i8* %p)
1646 call void @llvm.objc.release(i8* %p)
1650 ; Don't consider bitcasts or getelementptrs direct uses.
1652 ; CHECK-LABEL: define void @test32(
1653 ; CHECK-NOT: @llvm.objc.
1655 ; CHECK: call i8* @llvm.objc.retain
1656 ; CHECK: call void @callee()
1658 ; CHECK: call void @llvm.objc.release
1660 ; CHECK-NOT: @llvm.objc.
1662 define void @test32(i8* %p, i1 %x) {
1664 %f0 = call i8* @llvm.objc.retain(i8* %p)
1665 br i1 %x, label %true, label %done
1673 %g = bitcast i8* %p to i8*
1674 %h = getelementptr i8, i8* %g, i64 0
1675 call void @llvm.objc.release(i8* %g)
1679 ; Do consider icmps to be direct uses.
1681 ; CHECK-LABEL: define void @test33(
1682 ; CHECK-NOT: @llvm.objc.
1684 ; CHECK: call i8* @llvm.objc.retain
1685 ; CHECK: call void @callee()
1687 ; CHECK: call void @llvm.objc.release
1689 ; CHECK-NOT: @llvm.objc.
1691 define void @test33(i8* %p, i1 %x, i8* %y) {
1693 %f0 = call i8* @llvm.objc.retain(i8* %p)
1694 br i1 %x, label %true, label %done
1698 %v = icmp eq i8* %p, %y
1702 %g = bitcast i8* %p to i8*
1703 %h = getelementptr i8, i8* %g, i64 0
1704 call void @llvm.objc.release(i8* %g)
1708 ; Delete retain,release if there's just a possible dec and we have imprecise
1711 ; CHECK-LABEL: define void @test34a(
1712 ; CHECK: call i8* @llvm.objc.retain
1715 ; CHECK: call void @llvm.objc.release
1717 define void @test34a(i8* %p, i1 %x, i8* %y) {
1719 %f0 = call i8* @llvm.objc.retain(i8* %p)
1720 br i1 %x, label %true, label %done
1727 %g = bitcast i8* %p to i8*
1728 %h = getelementptr i8, i8* %g, i64 0
1729 call void @llvm.objc.release(i8* %g)
1733 ; CHECK-LABEL: define void @test34b(
1734 ; CHECK-NOT: @llvm.objc.
1736 define void @test34b(i8* %p, i1 %x, i8* %y) {
1738 %f0 = call i8* @llvm.objc.retain(i8* %p)
1739 br i1 %x, label %true, label %done
1746 %g = bitcast i8* %p to i8*
1747 %h = getelementptr i8, i8* %g, i64 0
1748 call void @llvm.objc.release(i8* %g), !clang.imprecise_release !0
1753 ; Delete retain,release if there's just a use and we do not have a precise
1757 ; CHECK-LABEL: define void @test35a(
1759 ; CHECK: call i8* @llvm.objc.retain
1762 ; CHECK: call void @llvm.objc.release
1764 define void @test35a(i8* %p, i1 %x, i8* %y) {
1766 %f0 = call i8* @llvm.objc.retain(i8* %p)
1767 br i1 %x, label %true, label %done
1770 %v = icmp eq i8* %p, %y
1774 %g = bitcast i8* %p to i8*
1775 %h = getelementptr i8, i8* %g, i64 0
1776 call void @llvm.objc.release(i8* %g)
1781 ; CHECK-LABEL: define void @test35b(
1782 ; CHECK-NOT: @llvm.objc.
1784 define void @test35b(i8* %p, i1 %x, i8* %y) {
1786 %f0 = call i8* @llvm.objc.retain(i8* %p)
1787 br i1 %x, label %true, label %done
1790 %v = icmp eq i8* %p, %y
1794 %g = bitcast i8* %p to i8*
1795 %h = getelementptr i8, i8* %g, i64 0
1796 call void @llvm.objc.release(i8* %g), !clang.imprecise_release !0
1800 ; Delete a retain,release if there's no actual use and we have precise release.
1802 ; CHECK-LABEL: define void @test36a(
1803 ; CHECK: @llvm.objc.retain
1804 ; CHECK: call void @callee()
1805 ; CHECK-NOT: @llvm.objc.
1806 ; CHECK: call void @callee()
1807 ; CHECK: @llvm.objc.release
1809 define void @test36a(i8* %p) {
1811 call i8* @llvm.objc.retain(i8* %p)
1814 call void @llvm.objc.release(i8* %p)
1818 ; Like test36, but with metadata.
1820 ; CHECK-LABEL: define void @test36b(
1821 ; CHECK-NOT: @llvm.objc.
1823 define void @test36b(i8* %p) {
1825 call i8* @llvm.objc.retain(i8* %p)
1828 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1832 ; Be aggressive about analyzing phis to eliminate possible uses.
1834 ; CHECK-LABEL: define void @test38(
1835 ; CHECK-NOT: @llvm.objc.
1837 define void @test38(i8* %p, i1 %u, i1 %m, i8* %z, i8* %y, i8* %x, i8* %w) {
1839 call i8* @llvm.objc.retain(i8* %p)
1840 br i1 %u, label %true, label %false
1842 br i1 %m, label %a, label %b
1844 br i1 %m, label %c, label %d
1854 %j = phi i8* [ %z, %a ], [ %y, %b ]
1857 %k = phi i8* [ %w, %c ], [ %x, %d ]
1860 %h = phi i8* [ %j, %e ], [ %k, %f ]
1861 call void @use_pointer(i8* %h)
1862 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1866 ; Delete retain,release pairs around loops.
1868 ; CHECK-LABEL: define void @test39(
1869 ; CHECK-NOT: @llvm.objc.
1871 define void @test39(i8* %p) {
1873 %0 = call i8* @llvm.objc.retain(i8* %p)
1876 loop: ; preds = %loop, %entry
1877 br i1 undef, label %loop, label %exit
1879 exit: ; preds = %loop
1880 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1884 ; Delete retain,release pairs around loops containing uses.
1886 ; CHECK-LABEL: define void @test39b(
1887 ; CHECK-NOT: @llvm.objc.
1889 define void @test39b(i8* %p) {
1891 %0 = call i8* @llvm.objc.retain(i8* %p)
1894 loop: ; preds = %loop, %entry
1896 br i1 undef, label %loop, label %exit
1898 exit: ; preds = %loop
1899 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1903 ; Delete retain,release pairs around loops containing potential decrements.
1905 ; CHECK-LABEL: define void @test39c(
1906 ; CHECK-NOT: @llvm.objc.
1908 define void @test39c(i8* %p) {
1910 %0 = call i8* @llvm.objc.retain(i8* %p)
1913 loop: ; preds = %loop, %entry
1914 call void @use_pointer(i8* %0)
1915 br i1 undef, label %loop, label %exit
1917 exit: ; preds = %loop
1918 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1922 ; Delete retain,release pairs around loops even if
1923 ; the successors are in a different order.
1925 ; CHECK-LABEL: define void @test40(
1926 ; CHECK-NOT: @llvm.objc.
1928 define void @test40(i8* %p) {
1930 %0 = call i8* @llvm.objc.retain(i8* %p)
1933 loop: ; preds = %loop, %entry
1934 call void @use_pointer(i8* %0)
1935 br i1 undef, label %exit, label %loop
1937 exit: ; preds = %loop
1938 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1942 ; Do the known-incremented retain+release elimination even if the pointer
1943 ; is also autoreleased.
1945 ; CHECK-LABEL: define void @test42(
1946 ; CHECK-NEXT: entry:
1947 ; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %p)
1948 ; CHECK-NEXT: call i8* @llvm.objc.autorelease(i8* %p)
1949 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1950 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1951 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1952 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1953 ; CHECK-NEXT: call void @llvm.objc.release(i8* %p)
1954 ; CHECK-NEXT: ret void
1956 define void @test42(i8* %p) {
1958 call i8* @llvm.objc.retain(i8* %p)
1959 call i8* @llvm.objc.autorelease(i8* %p)
1960 call i8* @llvm.objc.retain(i8* %p)
1961 call void @use_pointer(i8* %p)
1962 call void @use_pointer(i8* %p)
1963 call void @llvm.objc.release(i8* %p)
1964 call void @use_pointer(i8* %p)
1965 call void @use_pointer(i8* %p)
1966 call void @llvm.objc.release(i8* %p)
1970 ; Don't the known-incremented retain+release elimination if the pointer is
1971 ; autoreleased and there's an autoreleasePoolPop.
1973 ; CHECK-LABEL: define void @test43(
1974 ; CHECK-NEXT: entry:
1975 ; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %p)
1976 ; CHECK-NEXT: call i8* @llvm.objc.autorelease(i8* %p)
1977 ; CHECK-NEXT: call i8* @llvm.objc.retain
1978 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1979 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1980 ; CHECK-NEXT: call void @llvm.objc.autoreleasePoolPop(i8* undef)
1981 ; CHECK-NEXT: call void @llvm.objc.release
1982 ; CHECK-NEXT: ret void
1984 define void @test43(i8* %p) {
1986 call i8* @llvm.objc.retain(i8* %p)
1987 call i8* @llvm.objc.autorelease(i8* %p)
1988 call i8* @llvm.objc.retain(i8* %p)
1989 call void @use_pointer(i8* %p)
1990 call void @use_pointer(i8* %p)
1991 call void @llvm.objc.autoreleasePoolPop(i8* undef)
1992 call void @llvm.objc.release(i8* %p)
1996 ; Do the known-incremented retain+release elimination if the pointer is
1997 ; autoreleased and there's an autoreleasePoolPush.
1999 ; CHECK-LABEL: define void @test43b(
2000 ; CHECK-NEXT: entry:
2001 ; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %p)
2002 ; CHECK-NEXT: call i8* @llvm.objc.autorelease(i8* %p)
2003 ; CHECK-NEXT: call void @use_pointer(i8* %p)
2004 ; CHECK-NEXT: call void @use_pointer(i8* %p)
2005 ; CHECK-NEXT: call i8* @llvm.objc.autoreleasePoolPush()
2006 ; CHECK-NEXT: call void @use_pointer(i8* %p)
2007 ; CHECK-NEXT: call void @llvm.objc.release
2008 ; CHECK-NEXT: ret void
2010 define void @test43b(i8* %p) {
2012 call i8* @llvm.objc.retain(i8* %p)
2013 call i8* @llvm.objc.autorelease(i8* %p)
2014 call i8* @llvm.objc.retain(i8* %p)
2015 call void @use_pointer(i8* %p)
2016 call void @use_pointer(i8* %p)
2017 call i8* @llvm.objc.autoreleasePoolPush()
2018 call void @llvm.objc.release(i8* %p)
2019 call void @use_pointer(i8* %p)
2020 call void @llvm.objc.release(i8* %p)
2024 ; Do retain+release elimination for non-provenance pointers.
2026 ; CHECK-LABEL: define void @test44(
2027 ; CHECK-NOT: llvm.objc.
2029 define void @test44(i8** %pp) {
2030 %p = load i8*, i8** %pp
2031 %q = call i8* @llvm.objc.retain(i8* %p)
2032 call void @llvm.objc.release(i8* %q)
2036 ; Don't delete retain+release with an unknown-provenance
2037 ; may-alias llvm.objc.release between them.
2039 ; CHECK-LABEL: define void @test45(
2040 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
2041 ; CHECK: call void @llvm.objc.release(i8* %q)
2042 ; CHECK: call void @use_pointer(i8* %p)
2043 ; CHECK: call void @llvm.objc.release(i8* %p)
2045 define void @test45(i8** %pp, i8** %qq) {
2046 %p = load i8*, i8** %pp
2047 %q = load i8*, i8** %qq
2048 call i8* @llvm.objc.retain(i8* %p)
2049 call void @llvm.objc.release(i8* %q)
2050 call void @use_pointer(i8* %p)
2051 call void @llvm.objc.release(i8* %p)
2055 ; Don't delete retain and autorelease here.
2057 ; CHECK-LABEL: define void @test46(
2058 ; CHECK: tail call i8* @llvm.objc.retain(i8* %p) [[NUW]]
2060 ; CHECK: call i8* @llvm.objc.autorelease(i8* %p) [[NUW]]
2062 define void @test46(i8* %p, i1 %a) {
2064 call i8* @llvm.objc.retain(i8* %p)
2065 br i1 %a, label %true, label %false
2068 call i8* @llvm.objc.autorelease(i8* %p)
2069 call void @use_pointer(i8* %p)
2076 ; Delete no-op cast calls.
2078 ; CHECK-LABEL: define i8* @test47(
2082 define i8* @test47(i8* %p) nounwind {
2083 %x = call i8* @llvm.objc.retainedObject(i8* %p)
2087 ; Delete no-op cast calls.
2089 ; CHECK-LABEL: define i8* @test48(
2093 define i8* @test48(i8* %p) nounwind {
2094 %x = call i8* @llvm.objc.unretainedObject(i8* %p)
2098 ; Delete no-op cast calls.
2100 ; CHECK-LABEL: define i8* @test49(
2104 define i8* @test49(i8* %p) nounwind {
2105 %x = call i8* @llvm.objc.unretainedPointer(i8* %p)
2109 ; Do delete retain+release with intervening stores of the address value if we
2110 ; have imprecise release attached to llvm.objc.release.
2112 ; CHECK-LABEL: define void @test50a(
2113 ; CHECK-NEXT: call i8* @llvm.objc.retain
2114 ; CHECK-NEXT: call void @callee
2116 ; CHECK-NEXT: call void @llvm.objc.release
2117 ; CHECK-NEXT: ret void
2119 define void @test50a(i8* %p, i8** %pp) {
2120 call i8* @llvm.objc.retain(i8* %p)
2122 store i8* %p, i8** %pp
2123 call void @llvm.objc.release(i8* %p)
2127 ; CHECK-LABEL: define void @test50b(
2128 ; CHECK-NOT: @llvm.objc.
2130 define void @test50b(i8* %p, i8** %pp) {
2131 call i8* @llvm.objc.retain(i8* %p)
2133 store i8* %p, i8** %pp
2134 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
2139 ; Don't delete retain+release with intervening stores through the
2142 ; CHECK-LABEL: define void @test51a(
2143 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
2144 ; CHECK: call void @llvm.objc.release(i8* %p)
2147 define void @test51a(i8* %p) {
2148 call i8* @llvm.objc.retain(i8* %p)
2151 call void @llvm.objc.release(i8* %p)
2155 ; CHECK-LABEL: define void @test51b(
2156 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
2157 ; CHECK: call void @llvm.objc.release(i8* %p)
2160 define void @test51b(i8* %p) {
2161 call i8* @llvm.objc.retain(i8* %p)
2164 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
2168 ; Don't delete retain+release with intervening use of a pointer of
2169 ; unknown provenance.
2171 ; CHECK-LABEL: define void @test52a(
2172 ; CHECK: call i8* @llvm.objc.retain
2173 ; CHECK: call void @callee()
2174 ; CHECK: call void @use_pointer(i8* %z)
2175 ; CHECK: call void @llvm.objc.release
2178 define void @test52a(i8** %zz, i8** %pp) {
2179 %p = load i8*, i8** %pp
2180 %1 = call i8* @llvm.objc.retain(i8* %p)
2182 %z = load i8*, i8** %zz
2183 call void @use_pointer(i8* %z)
2184 call void @llvm.objc.release(i8* %p)
2188 ; CHECK-LABEL: define void @test52b(
2189 ; CHECK: call i8* @llvm.objc.retain
2190 ; CHECK: call void @callee()
2191 ; CHECK: call void @use_pointer(i8* %z)
2192 ; CHECK: call void @llvm.objc.release
2195 define void @test52b(i8** %zz, i8** %pp) {
2196 %p = load i8*, i8** %pp
2197 %1 = call i8* @llvm.objc.retain(i8* %p)
2199 %z = load i8*, i8** %zz
2200 call void @use_pointer(i8* %z)
2201 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
2205 ; Like test52, but the pointer has function type, so it's assumed to
2206 ; be not reference counted.
2207 ; Oops. That's wrong. Clang sometimes uses function types gratuitously.
2208 ; See rdar://10551239.
2210 ; CHECK-LABEL: define void @test53(
2211 ; CHECK: @llvm.objc.
2213 define void @test53(void ()** %zz, i8** %pp) {
2214 %p = load i8*, i8** %pp
2215 %1 = call i8* @llvm.objc.retain(i8* %p)
2217 %z = load void ()*, void ()** %zz
2218 call void @callee_fnptr(void ()* %z)
2219 call void @llvm.objc.release(i8* %p)
2223 ; Convert autorelease to release if the value is unused.
2225 ; CHECK-LABEL: define void @test54(
2226 ; CHECK: call i8* @returner()
2227 ; CHECK-NEXT: call void @llvm.objc.release(i8* %t) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2228 ; CHECK-NEXT: ret void
2230 define void @test54() {
2231 %t = call i8* @returner()
2232 call i8* @llvm.objc.autorelease(i8* %t)
2236 ; Nested retain+release pairs. Delete them both.
2238 ; CHECK-LABEL: define void @test55(
2241 define void @test55(i8* %x) {
2243 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
2244 %1 = call i8* @llvm.objc.retain(i8* %x) nounwind
2245 call void @llvm.objc.release(i8* %x) nounwind
2246 call void @llvm.objc.release(i8* %x) nounwind
2250 ; Nested retain+release pairs where the inner pair depends
2251 ; on the outer pair to be removed, and then the outer pair
2252 ; can be partially eliminated. Plus an extra outer pair to
2253 ; eliminate, for fun.
2255 ; CHECK-LABEL: define void @test56(
2258 ; CHECK-NEXT: %0 = tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2259 ; CHECK-NEXT: tail call void @use_pointer(i8* %x)
2260 ; CHECK-NEXT: tail call void @use_pointer(i8* %x)
2261 ; CHECK-NEXT: tail call void @llvm.objc.release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2262 ; CHECK-NEXT: br label %if.end
2265 define void @test56(i8* %x, i32 %n) {
2267 %0 = tail call i8* @llvm.objc.retain(i8* %x) nounwind
2268 %1 = tail call i8* @llvm.objc.retain(i8* %0) nounwind
2269 %tobool = icmp eq i32 %n, 0
2270 br i1 %tobool, label %if.end, label %if.then
2272 if.then: ; preds = %entry
2273 %2 = tail call i8* @llvm.objc.retain(i8* %1) nounwind
2274 tail call void @use_pointer(i8* %2)
2275 tail call void @use_pointer(i8* %2)
2276 tail call void @llvm.objc.release(i8* %2) nounwind, !clang.imprecise_release !0
2279 if.end: ; preds = %entry, %if.then
2280 tail call void @llvm.objc.release(i8* %1) nounwind, !clang.imprecise_release !0
2281 tail call void @llvm.objc.release(i8* %0) nounwind, !clang.imprecise_release !0
2285 ; When there are adjacent retain+release pairs, the first one is known
2286 ; unnecessary because the presence of the second one means that the first one
2287 ; won't be deleting the object.
2289 ; CHECK-LABEL: define void @test57(
2290 ; CHECK-NEXT: entry:
2291 ; CHECK-NEXT: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2292 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2293 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2294 ; CHECK-NEXT: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2295 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2296 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2297 ; CHECK-NEXT: call void @llvm.objc.release(i8* %x) [[NUW]]
2298 ; CHECK-NEXT: ret void
2300 define void @test57(i8* %x) nounwind {
2302 call i8* @llvm.objc.retain(i8* %x) nounwind
2303 call i8* @llvm.objc.retain(i8* %x) nounwind
2304 call void @use_pointer(i8* %x)
2305 call void @use_pointer(i8* %x)
2306 call void @llvm.objc.release(i8* %x) nounwind
2307 call i8* @llvm.objc.retain(i8* %x) nounwind
2308 call void @use_pointer(i8* %x)
2309 call void @use_pointer(i8* %x)
2310 call void @llvm.objc.release(i8* %x) nounwind
2314 ; An adjacent retain+release pair is sufficient even if it will be
2317 ; CHECK-LABEL: define void @test58(
2318 ; CHECK-NEXT: entry:
2319 ; CHECK-NEXT: @llvm.objc.retain
2320 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2321 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2322 ; CHECK-NEXT: ret void
2324 define void @test58(i8* %x) nounwind {
2326 call i8* @llvm.objc.retain(i8* %x) nounwind
2327 call i8* @llvm.objc.retain(i8* %x) nounwind
2328 call void @use_pointer(i8* %x)
2329 call void @use_pointer(i8* %x)
2330 call void @llvm.objc.release(i8* %x) nounwind
2331 call i8* @llvm.objc.retain(i8* %x) nounwind
2332 call void @llvm.objc.release(i8* %x) nounwind
2336 ; Don't delete the second retain+release pair in an adjacent set.
2338 ; CHECK-LABEL: define void @test59(
2339 ; CHECK-NEXT: entry:
2340 ; CHECK-NEXT: %0 = tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2341 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2342 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2343 ; CHECK-NEXT: call void @llvm.objc.release(i8* %x) [[NUW]]
2344 ; CHECK-NEXT: ret void
2346 define void @test59(i8* %x) nounwind {
2348 %a = call i8* @llvm.objc.retain(i8* %x) nounwind
2349 call void @llvm.objc.release(i8* %x) nounwind
2350 %b = call i8* @llvm.objc.retain(i8* %x) nounwind
2351 call void @use_pointer(i8* %x)
2352 call void @use_pointer(i8* %x)
2353 call void @llvm.objc.release(i8* %x) nounwind
2357 ; Constant pointers to objects don't need reference counting.
2359 @constptr = external constant i8*
2360 @something = external global i8*
2362 ; We have a precise lifetime retain/release here. We can not remove them since
2363 ; @something is not constant.
2365 ; CHECK-LABEL: define void @test60a(
2366 ; CHECK: call i8* @llvm.objc.retain
2367 ; CHECK: call void @llvm.objc.release
2369 define void @test60a() {
2370 %t = load i8*, i8** @constptr
2371 %s = load i8*, i8** @something
2372 call i8* @llvm.objc.retain(i8* %s)
2374 call void @use_pointer(i8* %t)
2375 call void @llvm.objc.release(i8* %s)
2379 ; CHECK-LABEL: define void @test60b(
2380 ; CHECK: call i8* @llvm.objc.retain
2381 ; CHECK-NOT: call i8* @llvm.objc.retain
2382 ; CHECK-NOT: call i8* @llvm.objc.release
2384 define void @test60b() {
2385 %t = load i8*, i8** @constptr
2386 %s = load i8*, i8** @something
2387 call i8* @llvm.objc.retain(i8* %t)
2388 call i8* @llvm.objc.retain(i8* %t)
2390 call void @use_pointer(i8* %s)
2391 call void @llvm.objc.release(i8* %t)
2395 ; CHECK-LABEL: define void @test60c(
2396 ; CHECK-NOT: @llvm.objc.
2398 define void @test60c() {
2399 %t = load i8*, i8** @constptr
2400 %s = load i8*, i8** @something
2401 call i8* @llvm.objc.retain(i8* %t)
2403 call void @use_pointer(i8* %s)
2404 call void @llvm.objc.release(i8* %t), !clang.imprecise_release !0
2408 ; CHECK-LABEL: define void @test60d(
2409 ; CHECK-NOT: @llvm.objc.
2411 define void @test60d() {
2412 %t = load i8*, i8** @constptr
2413 %s = load i8*, i8** @something
2414 call i8* @llvm.objc.retain(i8* %t)
2416 call void @use_pointer(i8* %s)
2417 call void @llvm.objc.release(i8* %t)
2421 ; CHECK-LABEL: define void @test60e(
2422 ; CHECK-NOT: @llvm.objc.
2424 define void @test60e() {
2425 %t = load i8*, i8** @constptr
2426 %s = load i8*, i8** @something
2427 call i8* @llvm.objc.retain(i8* %t)
2429 call void @use_pointer(i8* %s)
2430 call void @llvm.objc.release(i8* %t), !clang.imprecise_release !0
2434 ; Constant pointers to objects don't need to be considered related to other
2437 ; CHECK-LABEL: define void @test61(
2438 ; CHECK-NOT: @llvm.objc.
2440 define void @test61() {
2441 %t = load i8*, i8** @constptr
2442 call i8* @llvm.objc.retain(i8* %t)
2444 call void @use_pointer(i8* %t)
2445 call void @llvm.objc.release(i8* %t)
2449 ; Delete a retain matched by releases when one is inside the loop and the
2450 ; other is outside the loop.
2452 ; CHECK-LABEL: define void @test62(
2453 ; CHECK-NOT: @llvm.objc.
2455 define void @test62(i8* %x, i1* %p) nounwind {
2460 call i8* @llvm.objc.retain(i8* %x)
2461 %q = load i1, i1* %p
2462 br i1 %q, label %loop.more, label %exit
2465 call void @llvm.objc.release(i8* %x)
2469 call void @llvm.objc.release(i8* %x)
2473 ; Like test62 but with no release in exit.
2474 ; Don't delete anything!
2476 ; CHECK-LABEL: define void @test63(
2478 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x)
2480 ; CHECK: call void @llvm.objc.release(i8* %x)
2482 define void @test63(i8* %x, i1* %p) nounwind {
2487 call i8* @llvm.objc.retain(i8* %x)
2488 %q = load i1, i1* %p
2489 br i1 %q, label %loop.more, label %exit
2492 call void @llvm.objc.release(i8* %x)
2499 ; Like test62 but with no release in loop.more.
2500 ; Don't delete anything!
2502 ; CHECK-LABEL: define void @test64(
2504 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x)
2506 ; CHECK: call void @llvm.objc.release(i8* %x)
2508 define void @test64(i8* %x, i1* %p) nounwind {
2513 call i8* @llvm.objc.retain(i8* %x)
2514 %q = load i1, i1* %p
2515 br i1 %q, label %loop.more, label %exit
2521 call void @llvm.objc.release(i8* %x)
2525 ; Move an autorelease past a phi with a null.
2527 ; CHECK-LABEL: define i8* @test65(
2529 ; CHECK: call i8* @llvm.objc.autorelease(
2531 ; CHECK-NOT: @llvm.objc.autorelease
2533 define i8* @test65(i1 %x) {
2535 br i1 %x, label %return, label %if.then
2537 if.then: ; preds = %entry
2538 %c = call i8* @returner()
2539 %s = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %c) nounwind
2542 return: ; preds = %if.then, %entry
2543 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2544 %q = call i8* @llvm.objc.autorelease(i8* %retval) nounwind
2548 ; Don't move an autorelease past an autorelease pool boundary.
2550 ; CHECK-LABEL: define i8* @test65b(
2552 ; CHECK-NOT: @llvm.objc.autorelease
2554 ; CHECK: call i8* @llvm.objc.autorelease(
2556 define i8* @test65b(i1 %x) {
2558 %t = call i8* @llvm.objc.autoreleasePoolPush()
2559 br i1 %x, label %return, label %if.then
2561 if.then: ; preds = %entry
2562 %c = call i8* @returner()
2563 %s = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %c) nounwind
2566 return: ; preds = %if.then, %entry
2567 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2568 call void @llvm.objc.autoreleasePoolPop(i8* %t)
2569 %q = call i8* @llvm.objc.autorelease(i8* %retval) nounwind
2573 ; Don't move an autoreleaseReuturnValue, which would break
2574 ; the RV optimization.
2576 ; CHECK-LABEL: define i8* @test65c(
2578 ; CHECK-NOT: @llvm.objc.autorelease
2580 ; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(
2582 define i8* @test65c(i1 %x) {
2584 br i1 %x, label %return, label %if.then
2586 if.then: ; preds = %entry
2587 %c = call i8* @returner()
2588 %s = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %c) nounwind
2591 return: ; preds = %if.then, %entry
2592 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2593 %q = call i8* @llvm.objc.autoreleaseReturnValue(i8* %retval) nounwind
2597 ; CHECK-LABEL: define i8* @test65d(
2599 ; CHECK-NOT: @llvm.objc.autorelease
2601 ; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(
2603 define i8* @test65d(i1 %x) {
2605 br i1 %x, label %return, label %if.then
2607 if.then: ; preds = %entry
2608 %c = call i8* @returner()
2609 %s = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %c) nounwind
2612 return: ; preds = %if.then, %entry
2613 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2614 %q = call i8* @llvm.objc.autoreleaseReturnValue(i8* %retval) nounwind
2618 ; An llvm.objc.retain can serve as a may-use for a different pointer.
2621 ; CHECK-LABEL: define void @test66a(
2622 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2623 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2624 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2625 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2627 define void @test66a(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2629 br i1 %tobool, label %cond.true, label %cond.end
2634 cond.end: ; preds = %cond.true, %entry
2635 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2636 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2637 tail call void @llvm.objc.release(i8* %call) nounwind
2638 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2639 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind
2640 tail call void @llvm.objc.release(i8* %cond) nounwind
2644 ; CHECK-LABEL: define void @test66b(
2645 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2646 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2647 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2648 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2650 define void @test66b(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2652 br i1 %tobool, label %cond.true, label %cond.end
2657 cond.end: ; preds = %cond.true, %entry
2658 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2659 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2660 tail call void @llvm.objc.release(i8* %call) nounwind, !clang.imprecise_release !0
2661 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2662 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind
2663 tail call void @llvm.objc.release(i8* %cond) nounwind
2667 ; CHECK-LABEL: define void @test66c(
2668 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2669 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2670 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2671 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2673 define void @test66c(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2675 br i1 %tobool, label %cond.true, label %cond.end
2680 cond.end: ; preds = %cond.true, %entry
2681 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2682 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2683 tail call void @llvm.objc.release(i8* %call) nounwind
2684 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2685 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind, !clang.imprecise_release !0
2686 tail call void @llvm.objc.release(i8* %cond) nounwind
2690 ; CHECK-LABEL: define void @test66d(
2691 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2692 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2693 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2694 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2696 define void @test66d(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2698 br i1 %tobool, label %cond.true, label %cond.end
2703 cond.end: ; preds = %cond.true, %entry
2704 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2705 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2706 tail call void @llvm.objc.release(i8* %call) nounwind, !clang.imprecise_release !0
2707 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2708 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind
2709 tail call void @llvm.objc.release(i8* %cond) nounwind, !clang.imprecise_release !0
2713 ; A few real-world testcases.
2715 @.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
2716 @"OBJC_IVAR_$_A.myZ" = global i64 20, section "__DATA, __objc_const", align 8
2717 declare i32 @printf(i8* nocapture, ...) nounwind
2718 declare i32 @puts(i8* nocapture) nounwind
2719 @str = internal constant [16 x i8] c"-[ Top0 _getX ]\00"
2721 ; CHECK: define { <2 x float>, <2 x float> } @"\01-[A z]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
2722 ; CHECK-NOT: @llvm.objc.
2725 define {<2 x float>, <2 x float>} @"\01-[A z]"({}* %self, i8* nocapture %_cmd) nounwind {
2727 %0 = bitcast {}* %self to i8*
2728 %1 = tail call i8* @llvm.objc.retain(i8* %0) nounwind
2729 tail call void @llvm.dbg.value(metadata {}* %self, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2)
2730 tail call void @llvm.dbg.value(metadata {}* %self, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2)
2731 %ivar = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8
2732 %add.ptr = getelementptr i8, i8* %0, i64 %ivar
2733 %tmp1 = bitcast i8* %add.ptr to float*
2734 %tmp2 = load float, float* %tmp1, align 4
2735 %conv = fpext float %tmp2 to double
2736 %add.ptr.sum = add i64 %ivar, 4
2737 %tmp6 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum
2738 %2 = bitcast i8* %tmp6 to float*
2739 %tmp7 = load float, float* %2, align 4
2740 %conv8 = fpext float %tmp7 to double
2741 %add.ptr.sum36 = add i64 %ivar, 8
2742 %tmp12 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum36
2743 %arrayidx = bitcast i8* %tmp12 to float*
2744 %tmp13 = load float, float* %arrayidx, align 4
2745 %conv14 = fpext float %tmp13 to double
2746 %tmp12.sum = add i64 %ivar, 12
2747 %arrayidx19 = getelementptr inbounds i8, i8* %0, i64 %tmp12.sum
2748 %3 = bitcast i8* %arrayidx19 to float*
2749 %tmp20 = load float, float* %3, align 4
2750 %conv21 = fpext float %tmp20 to double
2751 %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)
2752 %ivar23 = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8
2753 %add.ptr24 = getelementptr i8, i8* %0, i64 %ivar23
2754 %4 = bitcast i8* %add.ptr24 to i128*
2755 %srcval = load i128, i128* %4, align 4
2756 tail call void @llvm.objc.release(i8* %0) nounwind
2757 %tmp29 = trunc i128 %srcval to i64
2758 %tmp30 = bitcast i64 %tmp29 to <2 x float>
2759 %tmp31 = insertvalue {<2 x float>, <2 x float>} undef, <2 x float> %tmp30, 0
2760 %tmp32 = lshr i128 %srcval, 64
2761 %tmp33 = trunc i128 %tmp32 to i64
2762 %tmp34 = bitcast i64 %tmp33 to <2 x float>
2763 %tmp35 = insertvalue {<2 x float>, <2 x float>} %tmp31, <2 x float> %tmp34, 1
2764 ret {<2 x float>, <2 x float>} %tmp35
2767 ; CHECK: @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
2768 ; CHECK-NOT: @llvm.objc.
2771 define i32 @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) nounwind {
2773 %0 = bitcast {}* %self to i8*
2774 %1 = tail call i8* @llvm.objc.retain(i8* %0) nounwind
2775 %puts = tail call i32 @puts(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @str, i64 0, i64 0))
2776 tail call void @llvm.objc.release(i8* %0) nounwind
2780 @"\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"
2781 @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
2782 @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"
2784 ; A simple loop. Eliminate the retain and release inside of it!
2786 ; CHECK: define void @loop(i8* %x, i64 %n) {
2788 ; CHECK-NOT: @llvm.objc.
2789 ; CHECK: @llvm.objc.msgSend
2790 ; CHECK-NOT: @llvm.objc.
2793 define void @loop(i8* %x, i64 %n) {
2795 %0 = tail call i8* @llvm.objc.retain(i8* %x) nounwind
2796 %cmp9 = icmp sgt i64 %n, 0
2797 br i1 %cmp9, label %for.body, label %for.end
2799 for.body: ; preds = %entry, %for.body
2800 %i.010 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
2801 %1 = tail call i8* @llvm.objc.retain(i8* %x) nounwind
2802 %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
2803 %call = tail call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %1, i8* %tmp5)
2804 tail call void @llvm.objc.release(i8* %1) nounwind, !clang.imprecise_release !0
2805 %inc = add nsw i64 %i.010, 1
2806 %exitcond = icmp eq i64 %inc, %n
2807 br i1 %exitcond, label %for.end, label %for.body
2809 for.end: ; preds = %for.body, %entry
2810 tail call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
2814 ; ObjCARCOpt can delete the retain,release on self.
2816 ; CHECK: define void @TextEditTest(%2* %self, %3* %pboard) {
2817 ; CHECK-NOT: call i8* @llvm.objc.retain(i8* %tmp7)
2820 %0 = type { i8* (i8*, %struct._message_ref_t*, ...)*, i8* }
2826 %struct.NSConstantString = type { i32*, i32, i8*, i64 }
2827 %struct._NSRange = type { i64, i64 }
2828 %struct.__CFString = type opaque
2829 %struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] }
2830 %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* }
2831 %struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* }
2832 %struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] }
2833 %struct._ivar_t = type { i64*, i8*, i8*, i32, i32 }
2834 %struct._message_ref_t = type { i8*, i8* }
2835 %struct._objc_cache = type opaque
2836 %struct._objc_method = type { i8*, i8*, i8* }
2837 %struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] }
2838 %struct._prop_list_t = type { i32, i32, [0 x %struct._message_ref_t] }
2839 %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 }
2841 @"\01L_OBJC_CLASSLIST_REFERENCES_$_17" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2842 @kUTTypePlainText = external constant %struct.__CFString*
2843 @"\01L_OBJC_SELECTOR_REFERENCES_19" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2844 @"\01L_OBJC_SELECTOR_REFERENCES_21" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2845 @"\01L_OBJC_SELECTOR_REFERENCES_23" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2846 @"\01L_OBJC_SELECTOR_REFERENCES_25" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2847 @"\01L_OBJC_CLASSLIST_REFERENCES_$_26" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2848 @"\01L_OBJC_SELECTOR_REFERENCES_28" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2849 @"\01L_OBJC_CLASSLIST_REFERENCES_$_29" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2850 @"\01L_OBJC_SELECTOR_REFERENCES_31" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2851 @"\01L_OBJC_SELECTOR_REFERENCES_33" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2852 @"\01L_OBJC_SELECTOR_REFERENCES_35" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2853 @"\01L_OBJC_SELECTOR_REFERENCES_37" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2854 @"\01L_OBJC_CLASSLIST_REFERENCES_$_38" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2855 @"\01L_OBJC_SELECTOR_REFERENCES_40" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2856 @"\01L_OBJC_SELECTOR_REFERENCES_42" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2857 @_unnamed_cfstring_44 = external hidden constant %struct.NSConstantString, section "__DATA,__cfstring"
2858 @"\01L_OBJC_SELECTOR_REFERENCES_46" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2859 @"\01L_OBJC_SELECTOR_REFERENCES_48" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2860 @"\01l_objc_msgSend_fixup_isEqual_" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16
2861 @"\01L_OBJC_CLASSLIST_REFERENCES_$_50" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2862 @NSCocoaErrorDomain = external constant %1*
2863 @"\01L_OBJC_CLASSLIST_REFERENCES_$_51" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2864 @NSFilePathErrorKey = external constant %1*
2865 @"\01L_OBJC_SELECTOR_REFERENCES_53" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2866 @"\01L_OBJC_SELECTOR_REFERENCES_55" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2867 @"\01L_OBJC_CLASSLIST_REFERENCES_$_56" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2868 @"\01L_OBJC_SELECTOR_REFERENCES_58" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2869 @"\01L_OBJC_SELECTOR_REFERENCES_60" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2871 declare %1* @truncatedString(%1*, i64)
2872 define void @TextEditTest(%2* %self, %3* %pboard) {
2874 %err = alloca %4*, align 8
2875 %tmp7 = bitcast %2* %self to i8*
2876 %tmp8 = call i8* @llvm.objc.retain(i8* %tmp7) nounwind
2877 store %4* null, %4** %err, align 8
2878 %tmp1 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_17", align 8
2879 %tmp2 = load %struct.__CFString*, %struct.__CFString** @kUTTypePlainText, align 8
2880 %tmp3 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_19", align 8
2881 %tmp4 = bitcast %struct._class_t* %tmp1 to i8*
2882 %call5 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp4, i8* %tmp3, %struct.__CFString* %tmp2)
2883 %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_21", align 8
2884 %tmp6 = bitcast %3* %pboard to i8*
2885 %call76 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp6, i8* %tmp5, i8* %call5)
2886 %tmp9 = call i8* @llvm.objc.retain(i8* %call76) nounwind
2887 %tobool = icmp eq i8* %tmp9, null
2888 br i1 %tobool, label %end, label %land.lhs.true
2890 land.lhs.true: ; preds = %entry
2891 %tmp11 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_23", align 8
2892 %call137 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp6, i8* %tmp11, i8* %tmp9)
2893 %tmp = bitcast i8* %call137 to %1*
2894 %tmp10 = call i8* @llvm.objc.retain(i8* %call137) nounwind
2895 call void @llvm.objc.release(i8* null) nounwind
2896 %tmp12 = call i8* @llvm.objc.retain(i8* %call137) nounwind
2897 call void @llvm.objc.release(i8* null) nounwind
2898 %tobool16 = icmp eq i8* %call137, null
2899 br i1 %tobool16, label %end, label %if.then
2901 if.then: ; preds = %land.lhs.true
2902 %tmp19 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2903 %call21 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @llvm.objc.msgSend to i8 (i8*, i8*)*)(i8* %call137, i8* %tmp19)
2904 %tobool22 = icmp eq i8 %call21, 0
2905 br i1 %tobool22, label %if.then44, label %land.lhs.true23
2907 land.lhs.true23: ; preds = %if.then
2908 %tmp24 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2909 %tmp26 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2910 %tmp27 = bitcast %struct._class_t* %tmp24 to i8*
2911 %call2822 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp27, i8* %tmp26, i8* %call137)
2912 %tmp13 = bitcast i8* %call2822 to %5*
2913 %tmp14 = call i8* @llvm.objc.retain(i8* %call2822) nounwind
2914 call void @llvm.objc.release(i8* null) nounwind
2915 %tobool30 = icmp eq i8* %call2822, null
2916 br i1 %tobool30, label %if.then44, label %if.end
2918 if.end: ; preds = %land.lhs.true23
2919 %tmp32 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2920 %tmp33 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2921 %tmp34 = bitcast %struct._class_t* %tmp32 to i8*
2922 %call35 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp34, i8* %tmp33)
2923 %tmp37 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2924 %call3923 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %call35, i8* %tmp37, i8* %call2822, i32 signext 1, %4** %err)
2925 %cmp = icmp eq i8* %call3923, null
2926 br i1 %cmp, label %if.then44, label %end
2928 if.then44: ; preds = %if.end, %land.lhs.true23, %if.then
2929 %url.025 = phi %5* [ %tmp13, %if.end ], [ %tmp13, %land.lhs.true23 ], [ null, %if.then ]
2930 %tmp49 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_35", align 8
2931 %call51 = call %struct._NSRange bitcast (i8* (i8*, i8*, ...)* @llvm.objc.msgSend to %struct._NSRange (i8*, i8*, i64, i64)*)(i8* %call137, i8* %tmp49, i64 0, i64 0)
2932 %call513 = extractvalue %struct._NSRange %call51, 0
2933 %call514 = extractvalue %struct._NSRange %call51, 1
2934 %tmp52 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_37", align 8
2935 %call548 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %call137, i8* %tmp52, i64 %call513, i64 %call514)
2936 %tmp55 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_38", align 8
2937 %tmp56 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_40", align 8
2938 %tmp57 = bitcast %struct._class_t* %tmp55 to i8*
2939 %call58 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp57, i8* %tmp56)
2940 %tmp59 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_42", align 8
2941 %call6110 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %call548, i8* %tmp59, i8* %call58)
2942 %tmp15 = call i8* @llvm.objc.retain(i8* %call6110) nounwind
2943 call void @llvm.objc.release(i8* %call137) nounwind
2944 %tmp64 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_46", align 8
2945 %call66 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @llvm.objc.msgSend to i8 (i8*, i8*, %1*)*)(i8* %call6110, i8* %tmp64, %1* bitcast (%struct.NSConstantString* @_unnamed_cfstring_44 to %1*))
2946 %tobool67 = icmp eq i8 %call66, 0
2947 br i1 %tobool67, label %if.end74, label %if.then68
2949 if.then68: ; preds = %if.then44
2950 %tmp70 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_48", align 8
2951 %call7220 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %call6110, i8* %tmp70)
2952 %tmp16 = call i8* @llvm.objc.retain(i8* %call7220) nounwind
2953 call void @llvm.objc.release(i8* %call6110) nounwind
2956 if.end74: ; preds = %if.then68, %if.then44
2957 %filename.0.in = phi i8* [ %call7220, %if.then68 ], [ %call6110, %if.then44 ]
2958 %filename.0 = bitcast i8* %filename.0.in to %1*
2959 %tmp17 = load i8*, i8** bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to i8**), align 16
2960 %tmp18 = bitcast i8* %tmp17 to i8 (i8*, %struct._message_ref_t*, i8*, ...)*
2961 %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)
2962 %tobool79 = icmp eq i8 %call78, 0
2963 br i1 %tobool79, label %land.lhs.true80, label %if.then109
2965 land.lhs.true80: ; preds = %if.end74
2966 %tmp82 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2967 %call84 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @llvm.objc.msgSend to i8 (i8*, i8*)*)(i8* %filename.0.in, i8* %tmp82)
2968 %tobool86 = icmp eq i8 %call84, 0
2969 br i1 %tobool86, label %if.then109, label %if.end106
2971 if.end106: ; preds = %land.lhs.true80
2972 %tmp88 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2973 %tmp90 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2974 %tmp91 = bitcast %struct._class_t* %tmp88 to i8*
2975 %call9218 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp91, i8* %tmp90, i8* %filename.0.in)
2976 %tmp20 = bitcast i8* %call9218 to %5*
2977 %tmp21 = call i8* @llvm.objc.retain(i8* %call9218) nounwind
2978 %tmp22 = bitcast %5* %url.025 to i8*
2979 call void @llvm.objc.release(i8* %tmp22) nounwind
2980 %tmp94 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2981 %tmp95 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2982 %tmp96 = bitcast %struct._class_t* %tmp94 to i8*
2983 %call97 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp96, i8* %tmp95)
2984 %tmp99 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2985 %call10119 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %call97, i8* %tmp99, i8* %call9218, i32 signext 1, %4** %err)
2986 %phitmp = icmp eq i8* %call10119, null
2987 br i1 %phitmp, label %if.then109, label %end
2989 if.then109: ; preds = %if.end106, %land.lhs.true80, %if.end74
2990 %url.129 = phi %5* [ %tmp20, %if.end106 ], [ %url.025, %if.end74 ], [ %url.025, %land.lhs.true80 ]
2991 %tmp110 = load %4*, %4** %err, align 8
2992 %tobool111 = icmp eq %4* %tmp110, null
2993 br i1 %tobool111, label %if.then112, label %if.end125
2995 if.then112: ; preds = %if.then109
2996 %tmp113 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_50", align 8
2997 %tmp114 = load %1*, %1** @NSCocoaErrorDomain, align 8
2998 %tmp115 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_51", align 8
2999 %call117 = call %1* @truncatedString(%1* %filename.0, i64 1034)
3000 %tmp118 = load %1*, %1** @NSFilePathErrorKey, align 8
3001 %tmp119 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_53", align 8
3002 %tmp120 = bitcast %struct._class_t* %tmp115 to i8*
3003 %call12113 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp120, i8* %tmp119, %1* %call117, %1* %tmp118, i8* null)
3004 %tmp122 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_55", align 8
3005 %tmp123 = bitcast %struct._class_t* %tmp113 to i8*
3006 %call12414 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp123, i8* %tmp122, %1* %tmp114, i64 258, i8* %call12113)
3007 %tmp23 = call i8* @llvm.objc.retain(i8* %call12414) nounwind
3008 %tmp25 = call i8* @llvm.objc.autorelease(i8* %tmp23) nounwind
3009 %tmp28 = bitcast i8* %tmp25 to %4*
3010 store %4* %tmp28, %4** %err, align 8
3013 if.end125: ; preds = %if.then112, %if.then109
3014 %tmp127 = phi %4* [ %tmp110, %if.then109 ], [ %tmp28, %if.then112 ]
3015 %tmp126 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_56", align 8
3016 %tmp128 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_58", align 8
3017 %tmp129 = bitcast %struct._class_t* %tmp126 to i8*
3018 %call13015 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %tmp129, i8* %tmp128, %4* %tmp127)
3019 %tmp131 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_60", align 8
3020 %call13317 = call i8* (i8*, i8*, ...) @llvm.objc.msgSend(i8* %call13015, i8* %tmp131)
3023 end: ; preds = %if.end125, %if.end106, %if.end, %land.lhs.true, %entry
3024 %filename.2 = phi %1* [ %filename.0, %if.end106 ], [ %filename.0, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
3025 %origFilename.0 = phi %1* [ %tmp, %if.end106 ], [ %tmp, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
3026 %url.2 = phi %5* [ %tmp20, %if.end106 ], [ %url.129, %if.end125 ], [ null, %land.lhs.true ], [ null, %entry ], [ %tmp13, %if.end ]
3027 call void @llvm.objc.release(i8* %tmp9) nounwind, !clang.imprecise_release !0
3028 %tmp29 = bitcast %5* %url.2 to i8*
3029 call void @llvm.objc.release(i8* %tmp29) nounwind, !clang.imprecise_release !0
3030 %tmp30 = bitcast %1* %origFilename.0 to i8*
3031 call void @llvm.objc.release(i8* %tmp30) nounwind, !clang.imprecise_release !0
3032 %tmp31 = bitcast %1* %filename.2 to i8*
3033 call void @llvm.objc.release(i8* %tmp31) nounwind, !clang.imprecise_release !0
3034 call void @llvm.objc.release(i8* %tmp7) nounwind, !clang.imprecise_release !0
3038 declare i32 @__gxx_personality_v0(...)
3040 declare i32 @llvm.objc.sync.enter(i8*)
3041 declare i32 @llvm.objc.sync.exit(i8*)
3043 ; Make sure that we understand that objc_sync_{enter,exit} are IC_User not
3044 ; IC_Call/IC_CallOrUser.
3046 ; CHECK-LABEL: define void @test67(
3047 ; CHECK-NEXT: call i32 @llvm.objc.sync.enter(i8* %x)
3048 ; CHECK-NEXT: call i32 @llvm.objc.sync.exit(i8* %x)
3049 ; CHECK-NEXT: ret void
3051 define void @test67(i8* %x) {
3052 call i8* @llvm.objc.retain(i8* %x)
3053 call i32 @llvm.objc.sync.enter(i8* %x)
3054 call i32 @llvm.objc.sync.exit(i8* %x)
3055 call void @llvm.objc.release(i8* %x), !clang.imprecise_release !0
3059 !llvm.module.flags = !{!1}
3060 !llvm.dbg.cu = !{!3}
3063 !1 = !{i32 1, !"Debug Info Version", i32 3}
3064 !2 = distinct !DISubprogram(unit: !3)
3065 !3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang",
3067 isOptimized: true, flags: "-O2",
3068 splitDebugFilename: "abc.debug", emissionKind: 2)
3069 !4 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
3070 !5 = !{i32 2, !"Debug Info Version", i32 3}
3072 ; CHECK: attributes [[NUW]] = { nounwind }
3073 ; CHECK: attributes #1 = { nounwind readnone speculatable }
3074 ; CHECK: ![[RELEASE]] = !{}