1 ; RUN: opt -basic-aa -objc-arc -S < %s | FileCheck %s
2 ; RUN: opt -aa-pipeline=basic-aa -passes=objc-arc -S < %s | FileCheck %s
4 target datalayout = "e-p:64:64:64"
6 declare i8* @llvm.objc.retain(i8*)
7 declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
8 declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)
9 declare void @llvm.objc.release(i8*)
10 declare i8* @llvm.objc.autorelease(i8*)
11 declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
12 declare void @llvm.objc.autoreleasePoolPop(i8*)
13 declare i8* @llvm.objc.autoreleasePoolPush()
14 declare i8* @llvm.objc.retainBlock(i8*)
16 declare i8* @llvm.objc.retainedObject(i8*)
17 declare i8* @llvm.objc.unretainedObject(i8*)
18 declare i8* @llvm.objc.unretainedPointer(i8*)
20 declare void @use_pointer(i8*)
21 declare void @callee()
22 declare void @callee2(i8*, i8*)
23 declare void @callee_fnptr(void ()*)
24 declare void @invokee()
25 declare i8* @returner()
26 declare void @bar(i32 ()*)
28 declare void @llvm.dbg.value(metadata, metadata, metadata)
30 declare i8* @objc_msgSend(i8*, i8*, ...)
32 ; Simple retain+release pair deletion, with some intervening control
33 ; flow and harmless instructions.
35 ; CHECK: define void @test0_precise(i32* %x, i1 %p) [[NUW:#[0-9]+]] {
36 ; CHECK: @llvm.objc.retain
37 ; CHECK: @llvm.objc.release
39 define void @test0_precise(i32* %x, i1 %p) nounwind {
41 %a = bitcast i32* %x to i8*
42 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
43 br i1 %p, label %t, label %f
47 %b = bitcast i32* %x to float*
48 store float 2.0, float* %b
56 %c = bitcast i32* %x to i8*
57 call void @llvm.objc.release(i8* %c) nounwind
61 ; CHECK: define void @test0_imprecise(i32* %x, i1 %p) [[NUW]] {
62 ; CHECK-NOT: @llvm.objc.
64 define void @test0_imprecise(i32* %x, i1 %p) nounwind {
66 %a = bitcast i32* %x to i8*
67 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
68 br i1 %p, label %t, label %f
72 %b = bitcast i32* %x to float*
73 store float 2.0, float* %b
81 %c = bitcast i32* %x to i8*
82 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
86 ; Like test0 but the release isn't always executed when the retain is,
87 ; so the optimization is not safe.
89 ; TODO: Make the llvm.objc.release's argument be %0.
91 ; CHECK: define void @test1_precise(i32* %x, i1 %p, i1 %q) [[NUW]] {
92 ; CHECK: @llvm.objc.retain(i8* %a)
93 ; CHECK: @llvm.objc.release
95 define void @test1_precise(i32* %x, i1 %p, i1 %q) nounwind {
97 %a = bitcast i32* %x to i8*
98 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
99 br i1 %p, label %t, label %f
103 %b = bitcast i32* %x to float*
104 store float 2.0, float* %b
110 br i1 %q, label %return, label %alt_return
113 %c = bitcast i32* %x to i8*
114 call void @llvm.objc.release(i8* %c) nounwind
121 ; CHECK: define void @test1_imprecise(i32* %x, i1 %p, i1 %q) [[NUW]] {
122 ; CHECK: @llvm.objc.retain(i8* %a)
123 ; CHECK: @llvm.objc.release
125 define void @test1_imprecise(i32* %x, i1 %p, i1 %q) nounwind {
127 %a = bitcast i32* %x to i8*
128 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
129 br i1 %p, label %t, label %f
133 %b = bitcast i32* %x to float*
134 store float 2.0, float* %b
140 br i1 %q, label %return, label %alt_return
143 %c = bitcast i32* %x to i8*
144 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
152 ; Don't do partial elimination into two different CFG diamonds.
154 ; CHECK: define void @test1b_precise(i8* %x, i1 %p, i1 %q) {
156 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
157 ; CHECK-NOT: @llvm.objc.
159 ; CHECK: tail call void @llvm.objc.release(i8* %x) [[NUW]]
160 ; CHECK-NOT: @llvm.objc.
162 define void @test1b_precise(i8* %x, i1 %p, i1 %q) {
164 tail call i8* @llvm.objc.retain(i8* %x) nounwind
165 br i1 %p, label %if.then, label %if.end
167 if.then: ; preds = %entry
168 tail call void @callee()
171 if.end: ; preds = %if.then, %entry
172 br i1 %q, label %if.then3, label %if.end5
174 if.then3: ; preds = %if.end
175 tail call void @use_pointer(i8* %x)
178 if.end5: ; preds = %if.then3, %if.end
179 tail call void @llvm.objc.release(i8* %x) nounwind
183 ; CHECK-LABEL: define void @test1b_imprecise(
185 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW:#[0-9]+]]
186 ; CHECK-NOT: @llvm.objc.
188 ; CHECK: tail call void @llvm.objc.release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE:[0-9]+]]
189 ; CHECK-NOT: @llvm.objc.
191 define void @test1b_imprecise(i8* %x, i1 %p, i1 %q) {
193 tail call i8* @llvm.objc.retain(i8* %x) nounwind
194 br i1 %p, label %if.then, label %if.end
196 if.then: ; preds = %entry
197 tail call void @callee()
200 if.end: ; preds = %if.then, %entry
201 br i1 %q, label %if.then3, label %if.end5
203 if.then3: ; preds = %if.end
204 tail call void @use_pointer(i8* %x)
207 if.end5: ; preds = %if.then3, %if.end
208 tail call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
213 ; Like test0 but the pointer is passed to an intervening call,
214 ; so the optimization is not safe.
216 ; CHECK-LABEL: define void @test2_precise(
217 ; CHECK: @llvm.objc.retain(i8* %a)
218 ; CHECK: @llvm.objc.release
220 define void @test2_precise(i32* %x, i1 %p) nounwind {
222 %a = bitcast i32* %x to i8*
223 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
224 br i1 %p, label %t, label %f
228 %b = bitcast i32* %x to float*
229 store float 2.0, float* %b
234 call void @use_pointer(i8* %0)
235 %d = bitcast i32* %x to float*
236 store float 3.0, float* %d
240 %c = bitcast i32* %x to i8*
241 call void @llvm.objc.release(i8* %c) nounwind
245 ; CHECK-LABEL: define void @test2_imprecise(
246 ; CHECK: @llvm.objc.retain(i8* %a)
247 ; CHECK: @llvm.objc.release
249 define void @test2_imprecise(i32* %x, i1 %p) nounwind {
251 %a = bitcast i32* %x to i8*
252 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
253 br i1 %p, label %t, label %f
257 %b = bitcast i32* %x to float*
258 store float 2.0, float* %b
263 call void @use_pointer(i8* %0)
264 %d = bitcast i32* %x to float*
265 store float 3.0, float* %d
269 %c = bitcast i32* %x to i8*
270 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
274 ; Like test0 but the release is in a loop,
275 ; so the optimization is not safe.
277 ; TODO: For now, assume this can't happen.
279 ; CHECK-LABEL: define void @test3_precise(
280 ; TODO: @llvm.objc.retain(i8* %a)
281 ; TODO: @llvm.objc.release
283 define void @test3_precise(i32* %x, i1* %q) nounwind {
285 %a = bitcast i32* %x to i8*
286 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
290 %c = bitcast i32* %x to i8*
291 call void @llvm.objc.release(i8* %c) nounwind
292 %j = load volatile i1, i1* %q
293 br i1 %j, label %loop, label %return
299 ; CHECK-LABEL: define void @test3_imprecise(
300 ; TODO: @llvm.objc.retain(i8* %a)
301 ; TODO: @llvm.objc.release
303 define void @test3_imprecise(i32* %x, i1* %q) nounwind {
305 %a = bitcast i32* %x to i8*
306 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
310 %c = bitcast i32* %x to i8*
311 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
312 %j = load volatile i1, i1* %q
313 br i1 %j, label %loop, label %return
320 ; TODO: For now, assume this can't happen.
322 ; Like test0 but the retain is in a loop,
323 ; so the optimization is not safe.
325 ; CHECK-LABEL: define void @test4_precise(
326 ; TODO: @llvm.objc.retain(i8* %a)
327 ; TODO: @llvm.objc.release
329 define void @test4_precise(i32* %x, i1* %q) nounwind {
334 %a = bitcast i32* %x to i8*
335 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
336 %j = load volatile i1, i1* %q
337 br i1 %j, label %loop, label %return
340 %c = bitcast i32* %x to i8*
341 call void @llvm.objc.release(i8* %c) nounwind
345 ; CHECK-LABEL: define void @test4_imprecise(
346 ; TODO: @llvm.objc.retain(i8* %a)
347 ; TODO: @llvm.objc.release
349 define void @test4_imprecise(i32* %x, i1* %q) nounwind {
354 %a = bitcast i32* %x to i8*
355 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
356 %j = load volatile i1, i1* %q
357 br i1 %j, label %loop, label %return
360 %c = bitcast i32* %x to i8*
361 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
366 ; Like test0 but the pointer is conditionally passed to an intervening call,
367 ; so the optimization is not safe.
369 ; CHECK-LABEL: define void @test5a(
370 ; CHECK: @llvm.objc.retain(i8*
371 ; CHECK: @llvm.objc.release
373 define void @test5a(i32* %x, i1 %q, i8* %y) nounwind {
375 %a = bitcast i32* %x to i8*
376 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
377 %s = select i1 %q, i8* %y, i8* %0
378 call void @use_pointer(i8* %s)
380 %c = bitcast i32* %x to i8*
381 call void @llvm.objc.release(i8* %c) nounwind
385 ; CHECK-LABEL: define void @test5b(
386 ; CHECK: @llvm.objc.retain(i8*
387 ; CHECK: @llvm.objc.release
389 define void @test5b(i32* %x, i1 %q, i8* %y) nounwind {
391 %a = bitcast i32* %x to i8*
392 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
393 %s = select i1 %q, i8* %y, i8* %0
394 call void @use_pointer(i8* %s)
396 %c = bitcast i32* %x to i8*
397 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
402 ; retain+release pair deletion, where the release happens on two different
405 ; CHECK-LABEL: define void @test6a(
407 ; CHECK: tail call i8* @llvm.objc.retain
409 ; CHECK: call void @llvm.objc.release
411 ; CHECK: call void @llvm.objc.release
414 define void @test6a(i32* %x, i1 %p) nounwind {
416 %a = bitcast i32* %x to i8*
417 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
418 br i1 %p, label %t, label %f
422 %b = bitcast i32* %x to float*
423 store float 2.0, float* %b
424 %ct = bitcast i32* %x to i8*
425 call void @llvm.objc.release(i8* %ct) nounwind
431 %cf = bitcast i32* %x to i8*
432 call void @llvm.objc.release(i8* %cf) nounwind
439 ; CHECK-LABEL: define void @test6b(
440 ; CHECK-NOT: @llvm.objc.
442 define void @test6b(i32* %x, i1 %p) nounwind {
444 %a = bitcast i32* %x to i8*
445 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
446 br i1 %p, label %t, label %f
450 %b = bitcast i32* %x to float*
451 store float 2.0, float* %b
452 %ct = bitcast i32* %x to i8*
453 call void @llvm.objc.release(i8* %ct) nounwind, !clang.imprecise_release !0
459 %cf = bitcast i32* %x to i8*
460 call void @llvm.objc.release(i8* %cf) nounwind, !clang.imprecise_release !0
467 ; CHECK-LABEL: define void @test6c(
469 ; CHECK: tail call i8* @llvm.objc.retain
471 ; CHECK: call void @llvm.objc.release
473 ; CHECK: call void @llvm.objc.release
476 define void @test6c(i32* %x, i1 %p) nounwind {
478 %a = bitcast i32* %x to i8*
479 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
480 br i1 %p, label %t, label %f
484 %b = bitcast i32* %x to float*
485 store float 2.0, float* %b
486 %ct = bitcast i32* %x to i8*
487 call void @llvm.objc.release(i8* %ct) nounwind
493 %cf = bitcast i32* %x to i8*
494 call void @llvm.objc.release(i8* %cf) nounwind, !clang.imprecise_release !0
501 ; CHECK-LABEL: define void @test6d(
503 ; CHECK: tail call i8* @llvm.objc.retain
505 ; CHECK: call void @llvm.objc.release
507 ; CHECK: call void @llvm.objc.release
510 define void @test6d(i32* %x, i1 %p) nounwind {
512 %a = bitcast i32* %x to i8*
513 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
514 br i1 %p, label %t, label %f
518 %b = bitcast i32* %x to float*
519 store float 2.0, float* %b
520 %ct = bitcast i32* %x to i8*
521 call void @llvm.objc.release(i8* %ct) nounwind, !clang.imprecise_release !0
527 %cf = bitcast i32* %x to i8*
528 call void @llvm.objc.release(i8* %cf) nounwind
536 ; retain+release pair deletion, where the retain happens on two different
539 ; CHECK-LABEL: define void @test7(
541 ; CHECK-NOT: llvm.objc.
543 ; CHECK: call i8* @llvm.objc.retain
545 ; CHECK: call i8* @llvm.objc.retain
547 ; CHECK: call void @llvm.objc.release
549 define void @test7(i32* %x, i1 %p) nounwind {
551 %a = bitcast i32* %x to i8*
552 br i1 %p, label %t, label %f
555 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
557 %b = bitcast i32* %x to float*
558 store float 2.0, float* %b
562 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
568 %c = bitcast i32* %x to i8*
569 call void @llvm.objc.release(i8* %c) nounwind
573 ; CHECK-LABEL: define void @test7b(
574 ; CHECK-NOT: @llvm.objc.
576 define void @test7b(i32* %x, i1 %p) nounwind {
578 %a = bitcast i32* %x to i8*
579 br i1 %p, label %t, label %f
582 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
584 %b = bitcast i32* %x to float*
585 store float 2.0, float* %b
589 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
595 %c = bitcast i32* %x to i8*
596 call void @llvm.objc.release(i8* %c) nounwind, !clang.imprecise_release !0
600 ; Like test7, but there's a retain/retainBlock mismatch. Don't delete!
602 ; CHECK-LABEL: define void @test7c(
604 ; CHECK: call i8* @llvm.objc.retainBlock
606 ; CHECK: call i8* @llvm.objc.retain
608 ; CHECK: call void @llvm.objc.release
610 define void @test7c(i32* %x, i1 %p) nounwind {
612 %a = bitcast i32* %x to i8*
613 br i1 %p, label %t, label %f
616 %0 = call i8* @llvm.objc.retainBlock(i8* %a) nounwind
618 %b = bitcast i32* %x to float*
619 store float 2.0, float* %b
623 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
629 %c = bitcast i32* %x to i8*
630 call void @llvm.objc.release(i8* %c) nounwind
634 ; retain+release pair deletion, where the retain and release both happen on
635 ; different flow paths. Wild!
637 ; CHECK-LABEL: define void @test8a(
640 ; CHECK: @llvm.objc.retain
642 ; CHECK: @llvm.objc.retain
645 ; CHECK: @llvm.objc.release
647 ; CHECK: @llvm.objc.release
650 define void @test8a(i32* %x, i1 %p, i1 %q) nounwind {
652 %a = bitcast i32* %x to i8*
653 br i1 %p, label %t, label %f
656 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
658 %b = bitcast i32* %x to float*
659 store float 2.0, float* %b
663 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
668 br i1 %q, label %u, label %g
672 %cu = bitcast i32* %x to i8*
673 call void @llvm.objc.release(i8* %cu) nounwind
677 %cg = bitcast i32* %x to i8*
678 call void @llvm.objc.release(i8* %cg) nounwind
685 ; CHECK-LABEL: define void @test8b(
686 ; CHECK-NOT: @llvm.objc.
688 define void @test8b(i32* %x, i1 %p, i1 %q) nounwind {
690 %a = bitcast i32* %x to i8*
691 br i1 %p, label %t, label %f
694 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
696 %b = bitcast i32* %x to float*
697 store float 2.0, float* %b
701 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
706 br i1 %q, label %u, label %g
710 %cu = bitcast i32* %x to i8*
711 call void @llvm.objc.release(i8* %cu) nounwind, !clang.imprecise_release !0
715 %cg = bitcast i32* %x to i8*
716 call void @llvm.objc.release(i8* %cg) nounwind, !clang.imprecise_release !0
723 ; CHECK-LABEL: define void @test8c(
726 ; CHECK-NOT: @llvm.objc.
728 ; CHECK-NOT: @llvm.objc.
731 ; CHECK: @llvm.objc.retain
732 ; CHECK: @llvm.objc.release
734 ; CHECK-NOT: @llvm.objc.
737 define void @test8c(i32* %x, i1 %p, i1 %q) nounwind {
739 %a = bitcast i32* %x to i8*
740 br i1 %p, label %t, label %f
743 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
745 %b = bitcast i32* %x to float*
746 store float 2.0, float* %b
750 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
755 br i1 %q, label %u, label %g
759 %cu = bitcast i32* %x to i8*
760 call void @llvm.objc.release(i8* %cu) nounwind
764 %cg = bitcast i32* %x to i8*
765 call void @llvm.objc.release(i8* %cg) nounwind, !clang.imprecise_release !0
772 ; CHECK-LABEL: define void @test8d(
775 ; CHECK: @llvm.objc.retain
777 ; CHECK: @llvm.objc.retain
780 ; CHECK: @llvm.objc.release
782 ; CHECK: @llvm.objc.release
785 define void @test8d(i32* %x, i1 %p, i1 %q) nounwind {
787 %a = bitcast i32* %x to i8*
788 br i1 %p, label %t, label %f
791 %0 = call i8* @llvm.objc.retain(i8* %a) nounwind
793 %b = bitcast i32* %x to float*
794 store float 2.0, float* %b
798 %1 = call i8* @llvm.objc.retain(i8* %a) nounwind
803 br i1 %q, label %u, label %g
807 %cu = bitcast i32* %x to i8*
808 call void @llvm.objc.release(i8* %cu) nounwind, !clang.imprecise_release !0
812 %cg = bitcast i32* %x to i8*
813 call void @llvm.objc.release(i8* %cg) nounwind
820 ; Trivial retain+release pair deletion.
822 ; CHECK-LABEL: define void @test9(
823 ; CHECK-NOT: @llvm.objc.
825 define void @test9(i8* %x) nounwind {
827 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
828 call void @llvm.objc.release(i8* %0) nounwind
832 ; Retain+release pair, but on an unknown pointer relationship. Don't delete!
834 ; CHECK-LABEL: define void @test9b(
835 ; CHECK: @llvm.objc.retain(i8* %x)
836 ; CHECK: @llvm.objc.release(i8* %s)
838 define void @test9b(i8* %x, i1 %j, i8* %p) nounwind {
840 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
841 %s = select i1 %j, i8* %x, i8* %p
842 call void @llvm.objc.release(i8* %s) nounwind
846 ; Trivial retain+release pair with intervening calls - don't delete!
848 ; CHECK-LABEL: define void @test10(
849 ; CHECK: @llvm.objc.retain(i8* %x)
851 ; CHECK: @use_pointer
852 ; CHECK: @llvm.objc.release
854 define void @test10(i8* %x) nounwind {
856 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
858 call void @use_pointer(i8* %x)
859 call void @llvm.objc.release(i8* %0) nounwind
863 ; Trivial retain+autoreleaserelease pair. Don't delete!
864 ; Also, add a tail keyword, since llvm.objc.retain can never be passed
867 ; CHECK-LABEL: define void @test11(
868 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
869 ; CHECK: call i8* @llvm.objc.autorelease(i8* %0) [[NUW]]
871 define void @test11(i8* %x) nounwind {
873 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
874 call i8* @llvm.objc.autorelease(i8* %0) nounwind
875 call void @use_pointer(i8* %x)
879 ; Same as test11 but with no use_pointer call. Delete the pair!
881 ; CHECK-LABEL: define void @test11a(
883 ; CHECK-NEXT: ret void
885 define void @test11a(i8* %x) nounwind {
887 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
888 call i8* @llvm.objc.autorelease(i8* %0) nounwind
892 ; Same as test11 but the value is returned. Do not perform an RV optimization
893 ; since if the frontend emitted code for an __autoreleasing variable, we may
894 ; want it to be in the autorelease pool.
896 ; CHECK-LABEL: define i8* @test11b(
897 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
898 ; CHECK: call i8* @llvm.objc.autorelease(i8* %0) [[NUW]]
900 define i8* @test11b(i8* %x) nounwind {
902 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
903 call i8* @llvm.objc.autorelease(i8* %0) nounwind
907 ; We can not delete this retain, release since we do not have a post-dominating
908 ; use of the release.
910 ; CHECK-LABEL: define void @test12(
912 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
913 ; CHECK-NEXT: @llvm.objc.retain
914 ; CHECK: @llvm.objc.release
916 define void @test12(i8* %x, i64 %n) {
918 call i8* @llvm.objc.retain(i8* %x) nounwind
919 call i8* @llvm.objc.retain(i8* %x) nounwind
920 call void @use_pointer(i8* %x)
921 call void @use_pointer(i8* %x)
922 call void @llvm.objc.release(i8* %x) nounwind
926 ; Trivial retain,autorelease pair. Don't delete!
928 ; CHECK-LABEL: define void @test13(
929 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
930 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
931 ; CHECK: @use_pointer(i8* %x)
932 ; CHECK: call i8* @llvm.objc.autorelease(i8* %x) [[NUW]]
934 define void @test13(i8* %x, i64 %n) {
936 call i8* @llvm.objc.retain(i8* %x) nounwind
937 call i8* @llvm.objc.retain(i8* %x) nounwind
938 call void @use_pointer(i8* %x)
939 call i8* @llvm.objc.autorelease(i8* %x) nounwind
943 ; Delete the retain+release pair.
945 ; CHECK-LABEL: define void @test13b(
947 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
948 ; CHECK-NEXT: @use_pointer
949 ; CHECK-NEXT: @use_pointer
950 ; CHECK-NEXT: @use_pointer
951 ; CHECK-NEXT: @llvm.objc.release
952 ; CHECK-NEXT: ret void
954 define void @test13b(i8* %x, i64 %n) {
956 call i8* @llvm.objc.retain(i8* %x) nounwind
957 call i8* @llvm.objc.retain(i8* %x) nounwind
958 call void @use_pointer(i8* %x)
959 call void @use_pointer(i8* %x)
960 call void @llvm.objc.release(i8* %x) nounwind
961 call void @use_pointer(i8* %x)
962 call void @llvm.objc.release(i8* %x) nounwind
966 ; Don't delete the retain+release pair because there's an
967 ; autoreleasePoolPop in the way.
969 ; CHECK-LABEL: define void @test13c(
970 ; CHECK: @llvm.objc.retain(i8* %x)
971 ; CHECK: @llvm.objc.autoreleasePoolPop
972 ; CHECK: @llvm.objc.retain(i8* %x)
973 ; CHECK: @use_pointer
974 ; CHECK: @llvm.objc.release
976 define void @test13c(i8* %x, i64 %n) {
978 call i8* @llvm.objc.retain(i8* %x) nounwind
979 call void @llvm.objc.autoreleasePoolPop(i8* undef)
980 call i8* @llvm.objc.retain(i8* %x) nounwind
981 call void @use_pointer(i8* %x)
982 call void @use_pointer(i8* %x)
983 call void @llvm.objc.release(i8* %x) nounwind
987 ; Like test13c, but there's an autoreleasePoolPush in the way, but that
990 ; CHECK-LABEL: define void @test13d(
992 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
993 ; CHECK-NEXT: @llvm.objc.autoreleasePoolPush
994 ; CHECK-NEXT: @use_pointer
995 ; CHECK-NEXT: @use_pointer
996 ; CHECK-NEXT: @use_pointer
997 ; CHECK-NEXT: @llvm.objc.release
998 ; CHECK-NEXT: ret void
1000 define void @test13d(i8* %x, i64 %n) {
1002 call i8* @llvm.objc.retain(i8* %x) nounwind
1003 call i8* @llvm.objc.autoreleasePoolPush()
1004 call i8* @llvm.objc.retain(i8* %x) nounwind
1005 call void @use_pointer(i8* %x)
1006 call void @use_pointer(i8* %x)
1007 call void @llvm.objc.release(i8* %x) nounwind
1008 call void @use_pointer(i8* %x)
1009 call void @llvm.objc.release(i8* %x) nounwind
1013 ; Trivial retain,release pair with intervening call, and it's post-dominated by
1014 ; another release. But it is not known safe in the top down direction. We can
1017 ; CHECK-LABEL: define void @test14(
1018 ; CHECK-NEXT: entry:
1019 ; CHECK-NEXT: @llvm.objc.retain
1020 ; CHECK-NEXT: @use_pointer
1021 ; CHECK-NEXT: @use_pointer
1022 ; CHECK-NEXT: @llvm.objc.release
1023 ; CHECK-NEXT: @llvm.objc.release
1024 ; CHECK-NEXT: ret void
1026 define void @test14(i8* %x, i64 %n) {
1028 call i8* @llvm.objc.retain(i8* %x) nounwind
1029 call void @use_pointer(i8* %x)
1030 call void @use_pointer(i8* %x)
1031 call void @llvm.objc.release(i8* %x) nounwind
1032 call void @llvm.objc.release(i8* %x) nounwind
1036 ; Trivial retain,autorelease pair with intervening call, but it's post-dominated
1037 ; by another release. Don't delete anything.
1039 ; CHECK-LABEL: define void @test15(
1040 ; CHECK-NEXT: entry:
1041 ; CHECK-NEXT: @llvm.objc.retain(i8* %x)
1042 ; CHECK-NEXT: @use_pointer
1043 ; CHECK-NEXT: @llvm.objc.autorelease(i8* %x)
1044 ; CHECK-NEXT: @llvm.objc.release
1045 ; CHECK-NEXT: ret void
1047 define void @test15(i8* %x, i64 %n) {
1049 call i8* @llvm.objc.retain(i8* %x) nounwind
1050 call void @use_pointer(i8* %x)
1051 call i8* @llvm.objc.autorelease(i8* %x) nounwind
1052 call void @llvm.objc.release(i8* %x) nounwind
1056 ; Trivial retain,autorelease pair, post-dominated
1057 ; by another release. Delete the retain and release.
1059 ; CHECK-LABEL: define void @test15b(
1060 ; CHECK-NEXT: entry:
1061 ; CHECK-NEXT: @llvm.objc.retain
1062 ; CHECK-NEXT: @llvm.objc.autorelease
1063 ; CHECK-NEXT: @llvm.objc.release
1064 ; CHECK-NEXT: ret void
1066 define void @test15b(i8* %x, i64 %n) {
1068 call i8* @llvm.objc.retain(i8* %x) nounwind
1069 call i8* @llvm.objc.autorelease(i8* %x) nounwind
1070 call void @llvm.objc.release(i8* %x) nounwind
1074 ; CHECK-LABEL: define void @test15c(
1075 ; CHECK-NEXT: entry:
1076 ; CHECK-NEXT: @llvm.objc.autorelease
1077 ; CHECK-NEXT: ret void
1079 define void @test15c(i8* %x, i64 %n) {
1081 call i8* @llvm.objc.retain(i8* %x) nounwind
1082 call i8* @llvm.objc.autorelease(i8* %x) nounwind
1083 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1087 ; Retain+release pairs in diamonds, all dominated by a retain.
1089 ; CHECK-LABEL: define void @test16a(
1090 ; CHECK: @llvm.objc.retain(i8* %x)
1093 ; CHECK: @use_pointer
1094 ; CHECK: @llvm.objc.release
1096 define void @test16a(i1 %a, i1 %b, i8* %x) {
1098 call i8* @llvm.objc.retain(i8* %x) nounwind
1099 br i1 %a, label %red, label %orange
1102 call i8* @llvm.objc.retain(i8* %x) nounwind
1106 call i8* @llvm.objc.retain(i8* %x) nounwind
1110 call void @use_pointer(i8* %x)
1111 call void @use_pointer(i8* %x)
1112 br i1 %b, label %green, label %blue
1115 call void @llvm.objc.release(i8* %x) nounwind
1119 call void @llvm.objc.release(i8* %x) nounwind
1123 call void @use_pointer(i8* %x)
1124 call void @llvm.objc.release(i8* %x) nounwind
1128 ; CHECK-LABEL: define void @test16b(
1129 ; CHECK: @llvm.objc.retain(i8* %x)
1132 ; CHECK-NEXT: @use_pointer
1133 ; CHECK-NEXT: @use_pointer
1134 ; CHECK-NEXT: @llvm.objc.release
1136 define void @test16b(i1 %a, i1 %b, i8* %x) {
1138 call i8* @llvm.objc.retain(i8* %x) nounwind
1139 br i1 %a, label %red, label %orange
1142 call i8* @llvm.objc.retain(i8* %x) nounwind
1146 call i8* @llvm.objc.retain(i8* %x) nounwind
1150 call void @use_pointer(i8* %x)
1151 call void @use_pointer(i8* %x)
1152 br i1 %b, label %green, label %blue
1155 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1159 call void @llvm.objc.release(i8* %x) nounwind
1163 call void @use_pointer(i8* %x)
1164 call void @use_pointer(i8* %x)
1165 call void @llvm.objc.release(i8* %x) nounwind
1169 ; CHECK-LABEL: define void @test16c(
1170 ; CHECK: @llvm.objc.retain(i8* %x)
1173 ; CHECK: @use_pointer
1174 ; CHECK: @llvm.objc.release
1176 define void @test16c(i1 %a, i1 %b, i8* %x) {
1178 call i8* @llvm.objc.retain(i8* %x) nounwind
1179 br i1 %a, label %red, label %orange
1182 call i8* @llvm.objc.retain(i8* %x) nounwind
1186 call i8* @llvm.objc.retain(i8* %x) nounwind
1190 call void @use_pointer(i8* %x)
1191 call void @use_pointer(i8* %x)
1192 br i1 %b, label %green, label %blue
1195 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1199 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1203 call void @use_pointer(i8* %x)
1204 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1208 ; CHECK-LABEL: define void @test16d(
1209 ; CHECK: @llvm.objc.retain(i8* %x)
1212 define void @test16d(i1 %a, i1 %b, i8* %x) {
1214 call i8* @llvm.objc.retain(i8* %x) nounwind
1215 br i1 %a, label %red, label %orange
1218 call i8* @llvm.objc.retain(i8* %x) nounwind
1222 call i8* @llvm.objc.retain(i8* %x) nounwind
1226 call void @use_pointer(i8* %x)
1227 call void @use_pointer(i8* %x)
1228 br i1 %b, label %green, label %blue
1231 call void @llvm.objc.release(i8* %x) nounwind
1235 call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
1244 ; CHECK-LABEL: define void @test18(
1245 ; CHECK-NOT: @llvm.objc.
1247 define void @test18() {
1248 call i8* @llvm.objc.retain(i8* null)
1249 call void @llvm.objc.release(i8* null)
1250 call i8* @llvm.objc.autorelease(i8* null)
1254 ; Delete no-ops where undef can be assumed to be null.
1256 ; CHECK-LABEL: define void @test18b(
1257 ; CHECK-NOT: @llvm.objc.
1259 define void @test18b() {
1260 call i8* @llvm.objc.retain(i8* undef)
1261 call void @llvm.objc.release(i8* undef)
1262 call i8* @llvm.objc.autorelease(i8* undef)
1266 ; Replace uses of arguments with uses of return values, to reduce
1267 ; register pressure.
1269 ; CHECK: define void @test19(i32* %y) {
1270 ; CHECK: %z = bitcast i32* %y to i8*
1271 ; CHECK: %0 = bitcast i32* %y to i8*
1272 ; CHECK: %1 = tail call i8* @llvm.objc.retain(i8* %0)
1273 ; CHECK: call void @use_pointer(i8* %z)
1274 ; CHECK: call void @use_pointer(i8* %z)
1275 ; CHECK: %2 = bitcast i32* %y to i8*
1276 ; CHECK: call void @llvm.objc.release(i8* %2)
1279 define void @test19(i32* %y) {
1281 %x = bitcast i32* %y to i8*
1282 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
1283 %z = bitcast i32* %y to i8*
1284 call void @use_pointer(i8* %z)
1285 call void @use_pointer(i8* %z)
1286 call void @llvm.objc.release(i8* %x)
1292 ; CHECK-LABEL: define void @test20(
1293 ; CHECK: %tmp1 = tail call i8* @llvm.objc.retain(i8* %tmp) [[NUW]]
1294 ; CHECK-NEXT: invoke
1296 define void @test20(double* %self) personality i32 (...)* @__gxx_personality_v0 {
1298 %tmp = bitcast double* %self to i8*
1299 %tmp1 = call i8* @llvm.objc.retain(i8* %tmp) nounwind
1300 invoke void @invokee()
1301 to label %invoke.cont23 unwind label %lpad20
1303 invoke.cont23: ; preds = %if.then12
1304 invoke void @invokee()
1305 to label %if.end unwind label %lpad20
1307 lpad20: ; preds = %invoke.cont23, %if.then12
1308 %tmp502 = phi double* [ undef, %invoke.cont23 ], [ %self, %if.then12 ]
1309 %exn = landingpad {i8*, i32}
1313 if.end: ; preds = %invoke.cont23
1317 ; Delete a redundant retain,autorelease when forwaring a call result
1318 ; directly to a return value.
1320 ; CHECK-LABEL: define i8* @test21(
1321 ; CHECK: call i8* @returner()
1322 ; CHECK-NEXT: ret i8* %call
1324 define i8* @test21() {
1326 %call = call i8* @returner()
1327 %0 = call i8* @llvm.objc.retain(i8* %call) nounwind
1328 %1 = call i8* @llvm.objc.autorelease(i8* %0) nounwind
1332 ; Move an objc call up through a phi that has null operands.
1334 ; CHECK-LABEL: define void @test22(
1336 ; CHECK: %1 = bitcast double* %p to i8*
1337 ; CHECK: call void @llvm.objc.release(i8* %1)
1338 ; CHECK: br label %C
1339 ; CHECK: C: ; preds = %B, %A
1340 ; CHECK-NOT: @llvm.objc.release
1342 define void @test22(double* %p, i1 %a) {
1343 br i1 %a, label %A, label %B
1349 %h = phi double* [ null, %A ], [ %p, %B ]
1350 %c = bitcast double* %h to i8*
1351 call void @llvm.objc.release(i8* %c), !clang.imprecise_release !0
1355 ; Do not move an llvm.objc.release that doesn't have the clang.imprecise_release tag.
1357 ; CHECK-LABEL: define void @test22_precise(
1358 ; CHECK: %[[P0:.*]] = phi double*
1359 ; CHECK: %[[V0:.*]] = bitcast double* %[[P0]] to i8*
1360 ; CHECK: call void @llvm.objc.release(i8* %[[V0]])
1362 define void @test22_precise(double* %p, i1 %a) {
1363 br i1 %a, label %A, label %B
1369 %h = phi double* [ null, %A ], [ %p, %B ]
1370 %c = bitcast double* %h to i8*
1371 call void @llvm.objc.release(i8* %c)
1375 ; Any call can decrement a retain count.
1377 ; CHECK-LABEL: define void @test24(
1378 ; CHECK: @llvm.objc.retain(i8* %a)
1379 ; CHECK: @llvm.objc.release
1381 define void @test24(i8* %r, i8* %a) {
1382 call i8* @llvm.objc.retain(i8* %a)
1383 call void @use_pointer(i8* %r)
1384 %q = load i8, i8* %a
1385 call void @llvm.objc.release(i8* %a)
1389 ; Don't move a retain/release pair if the release can be moved
1390 ; but the retain can't be moved to balance it.
1392 ; CHECK-LABEL: define void @test25(
1394 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1397 ; CHECK: call void @llvm.objc.release(i8* %p)
1399 define void @test25(i8* %p, i1 %x) {
1401 %f0 = call i8* @llvm.objc.retain(i8* %p)
1403 br i1 %x, label %true, label %done
1410 call void @llvm.objc.release(i8* %p)
1414 ; Don't move a retain/release pair if the retain can be moved
1415 ; but the release can't be moved to balance it.
1417 ; CHECK-LABEL: define void @test26(
1419 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1422 ; CHECK: call void @llvm.objc.release(i8* %p)
1424 define void @test26(i8* %p, i1 %x) {
1426 %f0 = call i8* @llvm.objc.retain(i8* %p)
1427 br i1 %x, label %true, label %done
1435 call void @llvm.objc.release(i8* %p)
1439 ; Don't sink the retain,release into the loop.
1441 ; CHECK-LABEL: define void @test27(
1443 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1445 ; CHECK-NOT: @llvm.objc.
1447 ; CHECK: call void @llvm.objc.release
1449 define void @test27(i8* %p, i1 %x, i1 %y) {
1451 %f0 = call i8* @llvm.objc.retain(i8* %p)
1452 br i1 %x, label %loop, label %done
1457 br i1 %y, label %done, label %loop
1460 call void @llvm.objc.release(i8* %p)
1464 ; Trivial code motion case: Triangle.
1466 ; CHECK-LABEL: define void @test28(
1467 ; CHECK-NOT: @llvm.objc.
1469 ; CHECK: call i8* @llvm.objc.retain
1470 ; CHECK: call void @callee()
1472 ; CHECK: call void @llvm.objc.release
1474 ; CHECK-NOT: @llvm.objc.
1476 define void @test28(i8* %p, i1 %x) {
1478 %f0 = call i8* @llvm.objc.retain(i8* %p)
1479 br i1 %x, label %true, label %done
1487 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1491 ; Trivial code motion case: Triangle, but no metadata. Don't move past
1492 ; unrelated memory references!
1494 ; CHECK-LABEL: define void @test28b(
1495 ; CHECK: call i8* @llvm.objc.retain
1497 ; CHECK-NOT: @llvm.objc.
1498 ; CHECK: call void @callee()
1499 ; CHECK-NOT: @llvm.objc.
1501 ; CHECK-NOT: @llvm.objc.
1503 ; CHECK: @llvm.objc.release
1505 define void @test28b(i8* %p, i1 %x, i8* noalias %t) {
1507 %f0 = call i8* @llvm.objc.retain(i8* %p)
1508 br i1 %x, label %true, label %done
1517 call void @llvm.objc.release(i8* %p)
1521 ; Trivial code motion case: Triangle, with metadata. Do move past
1522 ; unrelated memory references! And preserve the metadata.
1524 ; CHECK-LABEL: define void @test28c(
1525 ; CHECK-NOT: @llvm.objc.
1527 ; CHECK: call i8* @llvm.objc.retain
1528 ; CHECK: call void @callee()
1530 ; CHECK: call void @llvm.objc.release(i8* %p) [[NUW]], !clang.imprecise_release
1532 ; CHECK-NOT: @llvm.objc.
1534 define void @test28c(i8* %p, i1 %x, i8* noalias %t) {
1536 %f0 = call i8* @llvm.objc.retain(i8* %p)
1537 br i1 %x, label %true, label %done
1546 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1550 ; Like test28. but with two releases.
1552 ; CHECK-LABEL: define void @test29(
1553 ; CHECK: call i8* @llvm.objc.retain
1555 ; CHECK: call void @callee()
1558 ; CHECK: call void @llvm.objc.release
1560 ; CHECK: call void @llvm.objc.release
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: call i8* @llvm.objc.retain
1587 ; CHECK: call void @callee()
1591 ; CHECK: call void @llvm.objc.release
1593 ; CHECK: call void @llvm.objc.release
1595 define void @test30(i8* %p, i1 %x, i1 %y, i1 %z) {
1597 %f0 = call i8* @llvm.objc.retain(i8* %p)
1598 br i1 %x, label %true, label %false
1603 br i1 %y, label %done, label %ohno
1606 br i1 %z, label %done, label %ohno
1609 call void @llvm.objc.release(i8* %p)
1613 call void @llvm.objc.release(i8* %p)
1617 ; Basic case with a mergeable release.
1619 ; CHECK-LABEL: define void @test31(
1620 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
1621 ; CHECK: call void @callee()
1624 ; CHECK: call void @llvm.objc.release
1626 ; CHECK: call void @llvm.objc.release
1629 define void @test31(i8* %p, i1 %x) {
1631 %f0 = call i8* @llvm.objc.retain(i8* %p)
1634 br i1 %x, label %true, label %false
1636 call void @llvm.objc.release(i8* %p)
1639 call void @llvm.objc.release(i8* %p)
1643 ; Don't consider bitcasts or getelementptrs direct uses.
1645 ; CHECK-LABEL: define void @test32(
1646 ; CHECK: call i8* @llvm.objc.retain
1648 ; CHECK: call void @callee()
1651 ; CHECK: call void @llvm.objc.release
1653 define void @test32(i8* %p, i1 %x) {
1655 %f0 = call i8* @llvm.objc.retain(i8* %p)
1656 br i1 %x, label %true, label %done
1664 %g = bitcast i8* %p to i8*
1665 %h = getelementptr i8, i8* %g, i64 0
1666 call void @llvm.objc.release(i8* %g)
1670 ; Do consider icmps to be direct uses.
1672 ; CHECK-LABEL: define void @test33(
1673 ; CHECK: call i8* @llvm.objc.retain
1675 ; CHECK: call void @callee()
1678 ; CHECK: call void @llvm.objc.release
1680 define void @test33(i8* %p, i1 %x, i8* %y) {
1682 %f0 = call i8* @llvm.objc.retain(i8* %p)
1683 br i1 %x, label %true, label %done
1687 %v = icmp eq i8* %p, %y
1691 %g = bitcast i8* %p to i8*
1692 %h = getelementptr i8, i8* %g, i64 0
1693 call void @llvm.objc.release(i8* %g)
1697 ; Delete retain,release if there's just a possible dec and we have imprecise
1700 ; CHECK-LABEL: define void @test34a(
1701 ; CHECK: call i8* @llvm.objc.retain
1704 ; CHECK: call void @llvm.objc.release
1706 define void @test34a(i8* %p, i1 %x, i8* %y) {
1708 %f0 = call i8* @llvm.objc.retain(i8* %p)
1709 br i1 %x, label %true, label %done
1716 %g = bitcast i8* %p to i8*
1717 %h = getelementptr i8, i8* %g, i64 0
1718 call void @llvm.objc.release(i8* %g)
1722 ; CHECK-LABEL: define void @test34b(
1723 ; CHECK-NOT: @llvm.objc.
1725 define void @test34b(i8* %p, i1 %x, i8* %y) {
1727 %f0 = call i8* @llvm.objc.retain(i8* %p)
1728 br i1 %x, label %true, label %done
1735 %g = bitcast i8* %p to i8*
1736 %h = getelementptr i8, i8* %g, i64 0
1737 call void @llvm.objc.release(i8* %g), !clang.imprecise_release !0
1742 ; Delete retain,release if there's just a use and we do not have a precise
1746 ; CHECK-LABEL: define void @test35a(
1748 ; CHECK: call i8* @llvm.objc.retain
1751 ; CHECK: call void @llvm.objc.release
1753 define void @test35a(i8* %p, i1 %x, i8* %y) {
1755 %f0 = call i8* @llvm.objc.retain(i8* %p)
1756 br i1 %x, label %true, label %done
1759 %v = icmp eq i8* %p, %y
1763 %g = bitcast i8* %p to i8*
1764 %h = getelementptr i8, i8* %g, i64 0
1765 call void @llvm.objc.release(i8* %g)
1770 ; CHECK-LABEL: define void @test35b(
1771 ; CHECK-NOT: @llvm.objc.
1773 define void @test35b(i8* %p, i1 %x, i8* %y) {
1775 %f0 = call i8* @llvm.objc.retain(i8* %p)
1776 br i1 %x, label %true, label %done
1779 %v = icmp eq i8* %p, %y
1783 %g = bitcast i8* %p to i8*
1784 %h = getelementptr i8, i8* %g, i64 0
1785 call void @llvm.objc.release(i8* %g), !clang.imprecise_release !0
1789 ; Delete a retain,release if there's no actual use and we have precise release.
1791 ; CHECK-LABEL: define void @test36a(
1792 ; CHECK: @llvm.objc.retain
1793 ; CHECK: call void @callee()
1794 ; CHECK-NOT: @llvm.objc.
1795 ; CHECK: call void @callee()
1796 ; CHECK: @llvm.objc.release
1798 define void @test36a(i8* %p) {
1800 call i8* @llvm.objc.retain(i8* %p)
1803 call void @llvm.objc.release(i8* %p)
1807 ; Like test36, but with metadata.
1809 ; CHECK-LABEL: define void @test36b(
1810 ; CHECK-NOT: @llvm.objc.
1812 define void @test36b(i8* %p) {
1814 call i8* @llvm.objc.retain(i8* %p)
1817 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1821 ; Be aggressive about analyzing phis to eliminate possible uses.
1823 ; CHECK-LABEL: define void @test38(
1824 ; CHECK-NOT: @llvm.objc.
1826 define void @test38(i8* %p, i1 %u, i1 %m, i8* %z, i8* %y, i8* %x, i8* %w) {
1828 call i8* @llvm.objc.retain(i8* %p)
1829 br i1 %u, label %true, label %false
1831 br i1 %m, label %a, label %b
1833 br i1 %m, label %c, label %d
1843 %j = phi i8* [ %z, %a ], [ %y, %b ]
1846 %k = phi i8* [ %w, %c ], [ %x, %d ]
1849 %h = phi i8* [ %j, %e ], [ %k, %f ]
1850 call void @use_pointer(i8* %h)
1851 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
1855 ; Delete retain,release pairs around loops.
1857 ; CHECK-LABEL: define void @test39(
1858 ; CHECK-NOT: @llvm.objc.
1860 define void @test39(i8* %p) {
1862 %0 = call i8* @llvm.objc.retain(i8* %p)
1865 loop: ; preds = %loop, %entry
1866 br i1 undef, label %loop, label %exit
1868 exit: ; preds = %loop
1869 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1873 ; Delete retain,release pairs around loops containing uses.
1875 ; CHECK-LABEL: define void @test39b(
1876 ; CHECK-NOT: @llvm.objc.
1878 define void @test39b(i8* %p) {
1880 %0 = call i8* @llvm.objc.retain(i8* %p)
1883 loop: ; preds = %loop, %entry
1885 br i1 undef, label %loop, label %exit
1887 exit: ; preds = %loop
1888 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1892 ; Delete retain,release pairs around loops containing potential decrements.
1894 ; CHECK-LABEL: define void @test39c(
1895 ; CHECK-NOT: @llvm.objc.
1897 define void @test39c(i8* %p) {
1899 %0 = call i8* @llvm.objc.retain(i8* %p)
1902 loop: ; preds = %loop, %entry
1903 call void @use_pointer(i8* %0)
1904 br i1 undef, label %loop, label %exit
1906 exit: ; preds = %loop
1907 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1911 ; Delete retain,release pairs around loops even if
1912 ; the successors are in a different order.
1914 ; CHECK-LABEL: define void @test40(
1915 ; CHECK-NOT: @llvm.objc.
1917 define void @test40(i8* %p) {
1919 %0 = call i8* @llvm.objc.retain(i8* %p)
1922 loop: ; preds = %loop, %entry
1923 call void @use_pointer(i8* %0)
1924 br i1 undef, label %exit, label %loop
1926 exit: ; preds = %loop
1927 call void @llvm.objc.release(i8* %0), !clang.imprecise_release !0
1931 ; Do the known-incremented retain+release elimination even if the pointer
1932 ; is also autoreleased.
1934 ; CHECK-LABEL: define void @test42(
1935 ; CHECK-NEXT: entry:
1936 ; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %p)
1937 ; CHECK-NEXT: call i8* @llvm.objc.autorelease(i8* %p)
1938 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1939 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1940 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1941 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1942 ; CHECK-NEXT: call void @llvm.objc.release(i8* %p)
1943 ; CHECK-NEXT: ret void
1945 define void @test42(i8* %p) {
1947 call i8* @llvm.objc.retain(i8* %p)
1948 call i8* @llvm.objc.autorelease(i8* %p)
1949 call i8* @llvm.objc.retain(i8* %p)
1950 call void @use_pointer(i8* %p)
1951 call void @use_pointer(i8* %p)
1952 call void @llvm.objc.release(i8* %p)
1953 call void @use_pointer(i8* %p)
1954 call void @use_pointer(i8* %p)
1955 call void @llvm.objc.release(i8* %p)
1959 ; Don't the known-incremented retain+release elimination if the pointer is
1960 ; autoreleased and there's an autoreleasePoolPop.
1962 ; CHECK-LABEL: define void @test43(
1963 ; CHECK-NEXT: entry:
1964 ; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %p)
1965 ; CHECK-NEXT: call i8* @llvm.objc.autorelease(i8* %p)
1966 ; CHECK-NEXT: call i8* @llvm.objc.retain
1967 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1968 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1969 ; CHECK-NEXT: call void @llvm.objc.autoreleasePoolPop(i8* undef)
1970 ; CHECK-NEXT: call void @llvm.objc.release
1971 ; CHECK-NEXT: ret void
1973 define void @test43(i8* %p) {
1975 call i8* @llvm.objc.retain(i8* %p)
1976 call i8* @llvm.objc.autorelease(i8* %p)
1977 call i8* @llvm.objc.retain(i8* %p)
1978 call void @use_pointer(i8* %p)
1979 call void @use_pointer(i8* %p)
1980 call void @llvm.objc.autoreleasePoolPop(i8* undef)
1981 call void @llvm.objc.release(i8* %p)
1985 ; Do the known-incremented retain+release elimination if the pointer is
1986 ; autoreleased and there's an autoreleasePoolPush.
1988 ; CHECK-LABEL: define void @test43b(
1989 ; CHECK-NEXT: entry:
1990 ; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %p)
1991 ; CHECK-NEXT: call i8* @llvm.objc.autorelease(i8* %p)
1992 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1993 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1994 ; CHECK-NEXT: call i8* @llvm.objc.autoreleasePoolPush()
1995 ; CHECK-NEXT: call void @use_pointer(i8* %p)
1996 ; CHECK-NEXT: call void @llvm.objc.release
1997 ; CHECK-NEXT: ret void
1999 define void @test43b(i8* %p) {
2001 call i8* @llvm.objc.retain(i8* %p)
2002 call i8* @llvm.objc.autorelease(i8* %p)
2003 call i8* @llvm.objc.retain(i8* %p)
2004 call void @use_pointer(i8* %p)
2005 call void @use_pointer(i8* %p)
2006 call i8* @llvm.objc.autoreleasePoolPush()
2007 call void @llvm.objc.release(i8* %p)
2008 call void @use_pointer(i8* %p)
2009 call void @llvm.objc.release(i8* %p)
2013 ; Do retain+release elimination for non-provenance pointers.
2015 ; CHECK-LABEL: define void @test44(
2016 ; CHECK-NOT: llvm.objc.
2018 define void @test44(i8** %pp) {
2019 %p = load i8*, i8** %pp
2020 %q = call i8* @llvm.objc.retain(i8* %p)
2021 call void @llvm.objc.release(i8* %q)
2025 ; Don't delete retain+release with an unknown-provenance
2026 ; may-alias llvm.objc.release between them.
2028 ; CHECK-LABEL: define void @test45(
2029 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
2030 ; CHECK: call void @llvm.objc.release(i8* %q)
2031 ; CHECK: call void @use_pointer(i8* %p)
2032 ; CHECK: call void @llvm.objc.release(i8* %p)
2034 define void @test45(i8** %pp, i8** %qq) {
2035 %p = load i8*, i8** %pp
2036 %q = load i8*, i8** %qq
2037 call i8* @llvm.objc.retain(i8* %p)
2038 call void @llvm.objc.release(i8* %q)
2039 call void @use_pointer(i8* %p)
2040 call void @llvm.objc.release(i8* %p)
2044 ; Don't delete retain and autorelease here.
2046 ; CHECK-LABEL: define void @test46(
2047 ; CHECK: tail call i8* @llvm.objc.retain(i8* %p) [[NUW]]
2049 ; CHECK: call i8* @llvm.objc.autorelease(i8* %p) [[NUW]]
2051 define void @test46(i8* %p, i1 %a) {
2053 call i8* @llvm.objc.retain(i8* %p)
2054 br i1 %a, label %true, label %false
2057 call i8* @llvm.objc.autorelease(i8* %p)
2058 call void @use_pointer(i8* %p)
2065 ; Delete no-op cast calls.
2067 ; CHECK-LABEL: define i8* @test47(
2071 define i8* @test47(i8* %p) nounwind {
2072 %x = call i8* @llvm.objc.retainedObject(i8* %p)
2076 ; Delete no-op cast calls.
2078 ; CHECK-LABEL: define i8* @test48(
2082 define i8* @test48(i8* %p) nounwind {
2083 %x = call i8* @llvm.objc.unretainedObject(i8* %p)
2087 ; Delete no-op cast calls.
2089 ; CHECK-LABEL: define i8* @test49(
2093 define i8* @test49(i8* %p) nounwind {
2094 %x = call i8* @llvm.objc.unretainedPointer(i8* %p)
2098 ; Do delete retain+release with intervening stores of the address value if we
2099 ; have imprecise release attached to llvm.objc.release.
2101 ; CHECK-LABEL: define void @test50a(
2102 ; CHECK-NEXT: call i8* @llvm.objc.retain
2103 ; CHECK-NEXT: call void @callee
2105 ; CHECK-NEXT: call void @llvm.objc.release
2106 ; CHECK-NEXT: ret void
2108 define void @test50a(i8* %p, i8** %pp) {
2109 call i8* @llvm.objc.retain(i8* %p)
2111 store i8* %p, i8** %pp
2112 call void @llvm.objc.release(i8* %p)
2116 ; CHECK-LABEL: define void @test50b(
2117 ; CHECK-NOT: @llvm.objc.
2119 define void @test50b(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), !clang.imprecise_release !0
2128 ; Don't delete retain+release with intervening stores through the
2131 ; CHECK-LABEL: define void @test51a(
2132 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
2133 ; CHECK: call void @llvm.objc.release(i8* %p)
2136 define void @test51a(i8* %p) {
2137 call i8* @llvm.objc.retain(i8* %p)
2140 call void @llvm.objc.release(i8* %p)
2144 ; CHECK-LABEL: define void @test51b(
2145 ; CHECK: call i8* @llvm.objc.retain(i8* %p)
2146 ; CHECK: call void @llvm.objc.release(i8* %p)
2149 define void @test51b(i8* %p) {
2150 call i8* @llvm.objc.retain(i8* %p)
2153 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
2157 ; Don't delete retain+release with intervening use of a pointer of
2158 ; unknown provenance.
2160 ; CHECK-LABEL: define void @test52a(
2161 ; CHECK: call i8* @llvm.objc.retain
2162 ; CHECK: call void @callee()
2163 ; CHECK: call void @use_pointer(i8* %z)
2164 ; CHECK: call void @llvm.objc.release
2167 define void @test52a(i8** %zz, i8** %pp) {
2168 %p = load i8*, i8** %pp
2169 %1 = call i8* @llvm.objc.retain(i8* %p)
2171 %z = load i8*, i8** %zz
2172 call void @use_pointer(i8* %z)
2173 call void @llvm.objc.release(i8* %p)
2177 ; CHECK-LABEL: define void @test52b(
2178 ; CHECK: call i8* @llvm.objc.retain
2179 ; CHECK: call void @callee()
2180 ; CHECK: call void @use_pointer(i8* %z)
2181 ; CHECK: call void @llvm.objc.release
2184 define void @test52b(i8** %zz, i8** %pp) {
2185 %p = load i8*, i8** %pp
2186 %1 = call i8* @llvm.objc.retain(i8* %p)
2188 %z = load i8*, i8** %zz
2189 call void @use_pointer(i8* %z)
2190 call void @llvm.objc.release(i8* %p), !clang.imprecise_release !0
2194 ; Like test52, but the pointer has function type, so it's assumed to
2195 ; be not reference counted.
2196 ; Oops. That's wrong. Clang sometimes uses function types gratuitously.
2197 ; See rdar://10551239.
2199 ; CHECK-LABEL: define void @test53(
2200 ; CHECK: @llvm.objc.
2202 define void @test53(void ()** %zz, i8** %pp) {
2203 %p = load i8*, i8** %pp
2204 %1 = call i8* @llvm.objc.retain(i8* %p)
2206 %z = load void ()*, void ()** %zz
2207 call void @callee_fnptr(void ()* %z)
2208 call void @llvm.objc.release(i8* %p)
2212 ; Convert autorelease to release if the value is unused.
2214 ; CHECK-LABEL: define void @test54(
2215 ; CHECK: call i8* @returner()
2216 ; CHECK-NEXT: call void @llvm.objc.release(i8* %t) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2217 ; CHECK-NEXT: ret void
2219 define void @test54() {
2220 %t = call i8* @returner()
2221 call i8* @llvm.objc.autorelease(i8* %t)
2225 ; Nested retain+release pairs. Delete them both.
2227 ; CHECK-LABEL: define void @test55(
2230 define void @test55(i8* %x) {
2232 %0 = call i8* @llvm.objc.retain(i8* %x) nounwind
2233 %1 = call i8* @llvm.objc.retain(i8* %x) nounwind
2234 call void @llvm.objc.release(i8* %x) nounwind
2235 call void @llvm.objc.release(i8* %x) nounwind
2239 ; Nested retain+release pairs where the inner pair depends
2240 ; on the outer pair to be removed, and then the outer pair
2241 ; can be partially eliminated. Plus an extra outer pair to
2242 ; eliminate, for fun.
2244 ; CHECK-LABEL: define void @test56(
2247 ; CHECK-NEXT: %0 = tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2248 ; CHECK-NEXT: tail call void @use_pointer(i8* %x)
2249 ; CHECK-NEXT: tail call void @use_pointer(i8* %x)
2250 ; CHECK-NEXT: tail call void @llvm.objc.release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2251 ; CHECK-NEXT: br label %if.end
2254 define void @test56(i8* %x, i32 %n) {
2256 %0 = tail call i8* @llvm.objc.retain(i8* %x) nounwind
2257 %1 = tail call i8* @llvm.objc.retain(i8* %0) nounwind
2258 %tobool = icmp eq i32 %n, 0
2259 br i1 %tobool, label %if.end, label %if.then
2261 if.then: ; preds = %entry
2262 %2 = tail call i8* @llvm.objc.retain(i8* %1) nounwind
2263 tail call void @use_pointer(i8* %2)
2264 tail call void @use_pointer(i8* %2)
2265 tail call void @llvm.objc.release(i8* %2) nounwind, !clang.imprecise_release !0
2268 if.end: ; preds = %entry, %if.then
2269 tail call void @llvm.objc.release(i8* %1) nounwind, !clang.imprecise_release !0
2270 tail call void @llvm.objc.release(i8* %0) nounwind, !clang.imprecise_release !0
2274 ; When there are adjacent retain+release pairs, the first one is known
2275 ; unnecessary because the presence of the second one means that the first one
2276 ; won't be deleting the object.
2278 ; CHECK-LABEL: define void @test57(
2279 ; CHECK-NEXT: entry:
2280 ; CHECK-NEXT: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2281 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2282 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2283 ; CHECK-NEXT: tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2284 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2285 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2286 ; CHECK-NEXT: call void @llvm.objc.release(i8* %x) [[NUW]]
2287 ; CHECK-NEXT: ret void
2289 define void @test57(i8* %x) nounwind {
2291 call i8* @llvm.objc.retain(i8* %x) nounwind
2292 call i8* @llvm.objc.retain(i8* %x) nounwind
2293 call void @use_pointer(i8* %x)
2294 call void @use_pointer(i8* %x)
2295 call void @llvm.objc.release(i8* %x) nounwind
2296 call i8* @llvm.objc.retain(i8* %x) nounwind
2297 call void @use_pointer(i8* %x)
2298 call void @use_pointer(i8* %x)
2299 call void @llvm.objc.release(i8* %x) nounwind
2303 ; An adjacent retain+release pair is sufficient even if it will be
2306 ; CHECK-LABEL: define void @test58(
2307 ; CHECK-NEXT: entry:
2308 ; CHECK-NEXT: @llvm.objc.retain
2309 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2310 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2311 ; CHECK-NEXT: ret void
2313 define void @test58(i8* %x) nounwind {
2315 call i8* @llvm.objc.retain(i8* %x) nounwind
2316 call i8* @llvm.objc.retain(i8* %x) nounwind
2317 call void @use_pointer(i8* %x)
2318 call void @use_pointer(i8* %x)
2319 call void @llvm.objc.release(i8* %x) nounwind
2320 call i8* @llvm.objc.retain(i8* %x) nounwind
2321 call void @llvm.objc.release(i8* %x) nounwind
2325 ; Don't delete the second retain+release pair in an adjacent set.
2327 ; CHECK-LABEL: define void @test59(
2328 ; CHECK-NEXT: entry:
2329 ; CHECK-NEXT: %0 = tail call i8* @llvm.objc.retain(i8* %x) [[NUW]]
2330 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2331 ; CHECK-NEXT: call void @use_pointer(i8* %x)
2332 ; CHECK-NEXT: call void @llvm.objc.release(i8* %x) [[NUW]]
2333 ; CHECK-NEXT: ret void
2335 define void @test59(i8* %x) nounwind {
2337 %a = call i8* @llvm.objc.retain(i8* %x) nounwind
2338 call void @llvm.objc.release(i8* %x) nounwind
2339 %b = call i8* @llvm.objc.retain(i8* %x) nounwind
2340 call void @use_pointer(i8* %x)
2341 call void @use_pointer(i8* %x)
2342 call void @llvm.objc.release(i8* %x) nounwind
2346 ; Constant pointers to objects don't need reference counting.
2348 @constptr = external constant i8*
2349 @something = external global i8*
2351 ; We have a precise lifetime retain/release here. We can not remove them since
2352 ; @something is not constant.
2354 ; CHECK-LABEL: define void @test60a(
2355 ; CHECK: call i8* @llvm.objc.retain
2356 ; CHECK: call void @llvm.objc.release
2358 define void @test60a() {
2359 %t = load i8*, i8** @constptr
2360 %s = load i8*, i8** @something
2361 call i8* @llvm.objc.retain(i8* %s)
2363 call void @use_pointer(i8* %t)
2364 call void @llvm.objc.release(i8* %s)
2368 ; CHECK-LABEL: define void @test60b(
2369 ; CHECK: call i8* @llvm.objc.retain
2370 ; CHECK-NOT: call i8* @llvm.objc.retain
2371 ; CHECK-NOT: call i8* @llvm.objc.release
2373 define void @test60b() {
2374 %t = load i8*, i8** @constptr
2375 %s = load i8*, i8** @something
2376 call i8* @llvm.objc.retain(i8* %t)
2377 call i8* @llvm.objc.retain(i8* %t)
2379 call void @use_pointer(i8* %s)
2380 call void @llvm.objc.release(i8* %t)
2384 ; CHECK-LABEL: define void @test60c(
2385 ; CHECK-NOT: @llvm.objc.
2387 define void @test60c() {
2388 %t = load i8*, i8** @constptr
2389 %s = load i8*, i8** @something
2390 call i8* @llvm.objc.retain(i8* %t)
2392 call void @use_pointer(i8* %s)
2393 call void @llvm.objc.release(i8* %t), !clang.imprecise_release !0
2397 ; CHECK-LABEL: define void @test60d(
2398 ; CHECK-NOT: @llvm.objc.
2400 define void @test60d() {
2401 %t = load i8*, i8** @constptr
2402 %s = load i8*, i8** @something
2403 call i8* @llvm.objc.retain(i8* %t)
2405 call void @use_pointer(i8* %s)
2406 call void @llvm.objc.release(i8* %t)
2410 ; CHECK-LABEL: define void @test60e(
2411 ; CHECK-NOT: @llvm.objc.
2413 define void @test60e() {
2414 %t = load i8*, i8** @constptr
2415 %s = load i8*, i8** @something
2416 call i8* @llvm.objc.retain(i8* %t)
2418 call void @use_pointer(i8* %s)
2419 call void @llvm.objc.release(i8* %t), !clang.imprecise_release !0
2423 ; Constant pointers to objects don't need to be considered related to other
2426 ; CHECK-LABEL: define void @test61(
2427 ; CHECK-NOT: @llvm.objc.
2429 define void @test61() {
2430 %t = load i8*, i8** @constptr
2431 call i8* @llvm.objc.retain(i8* %t)
2433 call void @use_pointer(i8* %t)
2434 call void @llvm.objc.release(i8* %t)
2438 ; Delete a retain matched by releases when one is inside the loop and the
2439 ; other is outside the loop.
2441 ; CHECK-LABEL: define void @test62(
2442 ; CHECK-NOT: @llvm.objc.
2444 define void @test62(i8* %x, i1* %p) nounwind {
2449 call i8* @llvm.objc.retain(i8* %x)
2450 %q = load i1, i1* %p
2451 br i1 %q, label %loop.more, label %exit
2454 call void @llvm.objc.release(i8* %x)
2458 call void @llvm.objc.release(i8* %x)
2462 ; Like test62 but with no release in exit.
2463 ; Don't delete anything!
2465 ; CHECK-LABEL: define void @test63(
2467 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x)
2469 ; CHECK: call void @llvm.objc.release(i8* %x)
2471 define void @test63(i8* %x, i1* %p) nounwind {
2476 call i8* @llvm.objc.retain(i8* %x)
2477 %q = load i1, i1* %p
2478 br i1 %q, label %loop.more, label %exit
2481 call void @llvm.objc.release(i8* %x)
2488 ; Like test62 but with no release in loop.more.
2489 ; Don't delete anything!
2491 ; CHECK-LABEL: define void @test64(
2493 ; CHECK: tail call i8* @llvm.objc.retain(i8* %x)
2495 ; CHECK: call void @llvm.objc.release(i8* %x)
2497 define void @test64(i8* %x, i1* %p) nounwind {
2502 call i8* @llvm.objc.retain(i8* %x)
2503 %q = load i1, i1* %p
2504 br i1 %q, label %loop.more, label %exit
2510 call void @llvm.objc.release(i8* %x)
2514 ; Move an autorelease past a phi with a null.
2516 ; CHECK-LABEL: define i8* @test65(
2518 ; CHECK: call i8* @llvm.objc.autorelease(
2520 ; CHECK-NOT: @llvm.objc.autorelease
2522 define i8* @test65(i1 %x) {
2524 br i1 %x, label %return, label %if.then
2526 if.then: ; preds = %entry
2527 %c = call i8* @returner()
2528 %s = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %c) nounwind
2531 return: ; preds = %if.then, %entry
2532 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2533 %q = call i8* @llvm.objc.autorelease(i8* %retval) nounwind
2537 ; Don't move an autorelease past an autorelease pool boundary.
2539 ; CHECK-LABEL: define i8* @test65b(
2541 ; CHECK-NOT: @llvm.objc.autorelease
2543 ; CHECK: call i8* @llvm.objc.autorelease(
2545 define i8* @test65b(i1 %x) {
2547 %t = call i8* @llvm.objc.autoreleasePoolPush()
2548 br i1 %x, label %return, label %if.then
2550 if.then: ; preds = %entry
2551 %c = call i8* @returner()
2552 %s = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %c) nounwind
2555 return: ; preds = %if.then, %entry
2556 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2557 call void @llvm.objc.autoreleasePoolPop(i8* %t)
2558 %q = call i8* @llvm.objc.autorelease(i8* %retval) nounwind
2562 ; Don't move an autoreleaseReuturnValue, which would break
2563 ; the RV optimization.
2565 ; CHECK-LABEL: define i8* @test65c(
2567 ; CHECK-NOT: @llvm.objc.autorelease
2569 ; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(
2571 define i8* @test65c(i1 %x) {
2573 br i1 %x, label %return, label %if.then
2575 if.then: ; preds = %entry
2576 %c = call i8* @returner()
2577 %s = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %c) nounwind
2580 return: ; preds = %if.then, %entry
2581 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2582 %q = call i8* @llvm.objc.autoreleaseReturnValue(i8* %retval) nounwind
2586 ; CHECK-LABEL: define i8* @test65d(
2588 ; CHECK-NOT: @llvm.objc.autorelease
2590 ; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(
2592 define i8* @test65d(i1 %x) {
2594 br i1 %x, label %return, label %if.then
2596 if.then: ; preds = %entry
2597 %c = call i8* @returner()
2598 %s = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %c) nounwind
2601 return: ; preds = %if.then, %entry
2602 %retval = phi i8* [ %s, %if.then ], [ null, %entry ]
2603 %q = call i8* @llvm.objc.autoreleaseReturnValue(i8* %retval) nounwind
2607 ; An llvm.objc.retain can serve as a may-use for a different pointer.
2610 ; CHECK-LABEL: define void @test66a(
2611 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2612 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2613 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2614 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2616 define void @test66a(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2618 br i1 %tobool, label %cond.true, label %cond.end
2623 cond.end: ; preds = %cond.true, %entry
2624 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2625 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2626 tail call void @llvm.objc.release(i8* %call) nounwind
2627 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2628 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind
2629 tail call void @llvm.objc.release(i8* %cond) nounwind
2633 ; CHECK-LABEL: define void @test66b(
2634 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2635 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2636 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2637 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2639 define void @test66b(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2641 br i1 %tobool, label %cond.true, label %cond.end
2646 cond.end: ; preds = %cond.true, %entry
2647 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2648 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2649 tail call void @llvm.objc.release(i8* %call) nounwind, !clang.imprecise_release !0
2650 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2651 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind
2652 tail call void @llvm.objc.release(i8* %cond) nounwind
2656 ; CHECK-LABEL: define void @test66c(
2657 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2658 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2659 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2660 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2662 define void @test66c(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2664 br i1 %tobool, label %cond.true, label %cond.end
2669 cond.end: ; preds = %cond.true, %entry
2670 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2671 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2672 tail call void @llvm.objc.release(i8* %call) nounwind
2673 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2674 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind, !clang.imprecise_release !0
2675 tail call void @llvm.objc.release(i8* %cond) nounwind
2679 ; CHECK-LABEL: define void @test66d(
2680 ; CHECK: tail call i8* @llvm.objc.retain(i8* %cond) [[NUW]]
2681 ; CHECK: tail call void @llvm.objc.release(i8* %call) [[NUW]]
2682 ; CHECK: tail call i8* @llvm.objc.retain(i8* %tmp8) [[NUW]]
2683 ; CHECK: tail call void @llvm.objc.release(i8* %cond) [[NUW]]
2685 define void @test66d(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) {
2687 br i1 %tobool, label %cond.true, label %cond.end
2692 cond.end: ; preds = %cond.true, %entry
2693 %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ]
2694 %tmp7 = tail call i8* @llvm.objc.retain(i8* %cond) nounwind
2695 tail call void @llvm.objc.release(i8* %call) nounwind, !clang.imprecise_release !0
2696 %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar
2697 %tmp9 = tail call i8* @llvm.objc.retain(i8* %tmp8) nounwind
2698 tail call void @llvm.objc.release(i8* %cond) nounwind, !clang.imprecise_release !0
2702 ; A few real-world testcases.
2704 @.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
2705 @"OBJC_IVAR_$_A.myZ" = global i64 20, section "__DATA, __objc_const", align 8
2706 declare i32 @printf(i8* nocapture, ...) nounwind
2707 declare i32 @puts(i8* nocapture) nounwind
2708 @str = internal constant [16 x i8] c"-[ Top0 _getX ]\00"
2710 ; CHECK: define { <2 x float>, <2 x float> } @"\01-[A z]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
2711 ; CHECK-NOT: @llvm.objc.
2714 define {<2 x float>, <2 x float>} @"\01-[A z]"({}* %self, i8* nocapture %_cmd) nounwind {
2716 %0 = bitcast {}* %self to i8*
2717 %1 = tail call i8* @llvm.objc.retain(i8* %0) nounwind
2718 tail call void @llvm.dbg.value(metadata {}* %self, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2)
2719 tail call void @llvm.dbg.value(metadata {}* %self, metadata !DILocalVariable(scope: !2), metadata !DIExpression()), !dbg !DILocation(scope: !2)
2720 %ivar = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8
2721 %add.ptr = getelementptr i8, i8* %0, i64 %ivar
2722 %tmp1 = bitcast i8* %add.ptr to float*
2723 %tmp2 = load float, float* %tmp1, align 4
2724 %conv = fpext float %tmp2 to double
2725 %add.ptr.sum = add i64 %ivar, 4
2726 %tmp6 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum
2727 %2 = bitcast i8* %tmp6 to float*
2728 %tmp7 = load float, float* %2, align 4
2729 %conv8 = fpext float %tmp7 to double
2730 %add.ptr.sum36 = add i64 %ivar, 8
2731 %tmp12 = getelementptr inbounds i8, i8* %0, i64 %add.ptr.sum36
2732 %arrayidx = bitcast i8* %tmp12 to float*
2733 %tmp13 = load float, float* %arrayidx, align 4
2734 %conv14 = fpext float %tmp13 to double
2735 %tmp12.sum = add i64 %ivar, 12
2736 %arrayidx19 = getelementptr inbounds i8, i8* %0, i64 %tmp12.sum
2737 %3 = bitcast i8* %arrayidx19 to float*
2738 %tmp20 = load float, float* %3, align 4
2739 %conv21 = fpext float %tmp20 to double
2740 %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)
2741 %ivar23 = load i64, i64* @"OBJC_IVAR_$_A.myZ", align 8
2742 %add.ptr24 = getelementptr i8, i8* %0, i64 %ivar23
2743 %4 = bitcast i8* %add.ptr24 to i128*
2744 %srcval = load i128, i128* %4, align 4
2745 tail call void @llvm.objc.release(i8* %0) nounwind
2746 %tmp29 = trunc i128 %srcval to i64
2747 %tmp30 = bitcast i64 %tmp29 to <2 x float>
2748 %tmp31 = insertvalue {<2 x float>, <2 x float>} undef, <2 x float> %tmp30, 0
2749 %tmp32 = lshr i128 %srcval, 64
2750 %tmp33 = trunc i128 %tmp32 to i64
2751 %tmp34 = bitcast i64 %tmp33 to <2 x float>
2752 %tmp35 = insertvalue {<2 x float>, <2 x float>} %tmp31, <2 x float> %tmp34, 1
2753 ret {<2 x float>, <2 x float>} %tmp35
2756 ; CHECK: @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
2757 ; CHECK-NOT: @llvm.objc.
2760 define i32 @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) nounwind {
2762 %0 = bitcast {}* %self to i8*
2763 %1 = tail call i8* @llvm.objc.retain(i8* %0) nounwind
2764 %puts = tail call i32 @puts(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @str, i64 0, i64 0))
2765 tail call void @llvm.objc.release(i8* %0) nounwind
2769 @"\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"
2770 @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip"
2771 @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"
2773 ; A simple loop. Eliminate the retain and release inside of it!
2775 ; CHECK: define void @loop(i8* %x, i64 %n) {
2777 ; CHECK-NOT: @llvm.objc.
2778 ; CHECK: @objc_msgSend
2779 ; CHECK-NOT: @llvm.objc.
2782 define void @loop(i8* %x, i64 %n) {
2784 %0 = tail call i8* @llvm.objc.retain(i8* %x) nounwind
2785 %cmp9 = icmp sgt i64 %n, 0
2786 br i1 %cmp9, label %for.body, label %for.end
2788 for.body: ; preds = %entry, %for.body
2789 %i.010 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
2790 %1 = tail call i8* @llvm.objc.retain(i8* %x) nounwind
2791 %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8
2792 %call = tail call i8* (i8*, i8*, ...) @objc_msgSend(i8* %1, i8* %tmp5)
2793 tail call void @llvm.objc.release(i8* %1) nounwind, !clang.imprecise_release !0
2794 %inc = add nsw i64 %i.010, 1
2795 %exitcond = icmp eq i64 %inc, %n
2796 br i1 %exitcond, label %for.end, label %for.body
2798 for.end: ; preds = %for.body, %entry
2799 tail call void @llvm.objc.release(i8* %x) nounwind, !clang.imprecise_release !0
2803 ; ObjCARCOpt can delete the retain,release on self.
2805 ; CHECK: define void @TextEditTest(%2* %self, %3* %pboard) {
2806 ; CHECK-NOT: call i8* @llvm.objc.retain(i8* %tmp7)
2809 %0 = type { i8* (i8*, %struct._message_ref_t*, ...)*, i8* }
2815 %struct.NSConstantString = type { i32*, i32, i8*, i64 }
2816 %struct._NSRange = type { i64, i64 }
2817 %struct.__CFString = type opaque
2818 %struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] }
2819 %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* }
2820 %struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* }
2821 %struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] }
2822 %struct._ivar_t = type { i64*, i8*, i8*, i32, i32 }
2823 %struct._message_ref_t = type { i8*, i8* }
2824 %struct._objc_cache = type opaque
2825 %struct._objc_method = type { i8*, i8*, i8* }
2826 %struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] }
2827 %struct._prop_list_t = type { i32, i32, [0 x %struct._message_ref_t] }
2828 %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 }
2830 @"\01L_OBJC_CLASSLIST_REFERENCES_$_17" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2831 @kUTTypePlainText = external constant %struct.__CFString*
2832 @"\01L_OBJC_SELECTOR_REFERENCES_19" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2833 @"\01L_OBJC_SELECTOR_REFERENCES_21" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2834 @"\01L_OBJC_SELECTOR_REFERENCES_23" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2835 @"\01L_OBJC_SELECTOR_REFERENCES_25" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2836 @"\01L_OBJC_CLASSLIST_REFERENCES_$_26" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2837 @"\01L_OBJC_SELECTOR_REFERENCES_28" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2838 @"\01L_OBJC_CLASSLIST_REFERENCES_$_29" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2839 @"\01L_OBJC_SELECTOR_REFERENCES_31" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2840 @"\01L_OBJC_SELECTOR_REFERENCES_33" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2841 @"\01L_OBJC_SELECTOR_REFERENCES_35" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2842 @"\01L_OBJC_SELECTOR_REFERENCES_37" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2843 @"\01L_OBJC_CLASSLIST_REFERENCES_$_38" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2844 @"\01L_OBJC_SELECTOR_REFERENCES_40" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2845 @"\01L_OBJC_SELECTOR_REFERENCES_42" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2846 @_unnamed_cfstring_44 = external hidden constant %struct.NSConstantString, section "__DATA,__cfstring"
2847 @"\01L_OBJC_SELECTOR_REFERENCES_46" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2848 @"\01L_OBJC_SELECTOR_REFERENCES_48" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2849 @"\01l_objc_msgSend_fixup_isEqual_" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16
2850 @"\01L_OBJC_CLASSLIST_REFERENCES_$_50" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2851 @NSCocoaErrorDomain = external constant %1*
2852 @"\01L_OBJC_CLASSLIST_REFERENCES_$_51" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2853 @NSFilePathErrorKey = external constant %1*
2854 @"\01L_OBJC_SELECTOR_REFERENCES_53" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2855 @"\01L_OBJC_SELECTOR_REFERENCES_55" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2856 @"\01L_OBJC_CLASSLIST_REFERENCES_$_56" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
2857 @"\01L_OBJC_SELECTOR_REFERENCES_58" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2858 @"\01L_OBJC_SELECTOR_REFERENCES_60" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
2860 declare %1* @truncatedString(%1*, i64)
2861 define void @TextEditTest(%2* %self, %3* %pboard) {
2863 %err = alloca %4*, align 8
2864 %tmp7 = bitcast %2* %self to i8*
2865 %tmp8 = call i8* @llvm.objc.retain(i8* %tmp7) nounwind
2866 store %4* null, %4** %err, align 8
2867 %tmp1 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_17", align 8
2868 %tmp2 = load %struct.__CFString*, %struct.__CFString** @kUTTypePlainText, align 8
2869 %tmp3 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_19", align 8
2870 %tmp4 = bitcast %struct._class_t* %tmp1 to i8*
2871 %call5 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp4, i8* %tmp3, %struct.__CFString* %tmp2)
2872 %tmp5 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_21", align 8
2873 %tmp6 = bitcast %3* %pboard to i8*
2874 %call76 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp6, i8* %tmp5, i8* %call5)
2875 %tmp9 = call i8* @llvm.objc.retain(i8* %call76) nounwind
2876 %tobool = icmp eq i8* %tmp9, null
2877 br i1 %tobool, label %end, label %land.lhs.true
2879 land.lhs.true: ; preds = %entry
2880 %tmp11 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_23", align 8
2881 %call137 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp6, i8* %tmp11, i8* %tmp9)
2882 %tmp = bitcast i8* %call137 to %1*
2883 %tmp10 = call i8* @llvm.objc.retain(i8* %call137) nounwind
2884 call void @llvm.objc.release(i8* null) nounwind
2885 %tmp12 = call i8* @llvm.objc.retain(i8* %call137) nounwind
2886 call void @llvm.objc.release(i8* null) nounwind
2887 %tobool16 = icmp eq i8* %call137, null
2888 br i1 %tobool16, label %end, label %if.then
2890 if.then: ; preds = %land.lhs.true
2891 %tmp19 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2892 %call21 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %call137, i8* %tmp19)
2893 %tobool22 = icmp eq i8 %call21, 0
2894 br i1 %tobool22, label %if.then44, label %land.lhs.true23
2896 land.lhs.true23: ; preds = %if.then
2897 %tmp24 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2898 %tmp26 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2899 %tmp27 = bitcast %struct._class_t* %tmp24 to i8*
2900 %call2822 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp27, i8* %tmp26, i8* %call137)
2901 %tmp13 = bitcast i8* %call2822 to %5*
2902 %tmp14 = call i8* @llvm.objc.retain(i8* %call2822) nounwind
2903 call void @llvm.objc.release(i8* null) nounwind
2904 %tobool30 = icmp eq i8* %call2822, null
2905 br i1 %tobool30, label %if.then44, label %if.end
2907 if.end: ; preds = %land.lhs.true23
2908 %tmp32 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2909 %tmp33 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2910 %tmp34 = bitcast %struct._class_t* %tmp32 to i8*
2911 %call35 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp34, i8* %tmp33)
2912 %tmp37 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2913 %call3923 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call35, i8* %tmp37, i8* %call2822, i32 signext 1, %4** %err)
2914 %cmp = icmp eq i8* %call3923, null
2915 br i1 %cmp, label %if.then44, label %end
2917 if.then44: ; preds = %if.end, %land.lhs.true23, %if.then
2918 %url.025 = phi %5* [ %tmp13, %if.end ], [ %tmp13, %land.lhs.true23 ], [ null, %if.then ]
2919 %tmp49 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_35", align 8
2920 %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)
2921 %call513 = extractvalue %struct._NSRange %call51, 0
2922 %call514 = extractvalue %struct._NSRange %call51, 1
2923 %tmp52 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_37", align 8
2924 %call548 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call137, i8* %tmp52, i64 %call513, i64 %call514)
2925 %tmp55 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_38", align 8
2926 %tmp56 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_40", align 8
2927 %tmp57 = bitcast %struct._class_t* %tmp55 to i8*
2928 %call58 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp57, i8* %tmp56)
2929 %tmp59 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_42", align 8
2930 %call6110 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call548, i8* %tmp59, i8* %call58)
2931 %tmp15 = call i8* @llvm.objc.retain(i8* %call6110) nounwind
2932 call void @llvm.objc.release(i8* %call137) nounwind
2933 %tmp64 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_46", align 8
2934 %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*))
2935 %tobool67 = icmp eq i8 %call66, 0
2936 br i1 %tobool67, label %if.end74, label %if.then68
2938 if.then68: ; preds = %if.then44
2939 %tmp70 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_48", align 8
2940 %call7220 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call6110, i8* %tmp70)
2941 %tmp16 = call i8* @llvm.objc.retain(i8* %call7220) nounwind
2942 call void @llvm.objc.release(i8* %call6110) nounwind
2945 if.end74: ; preds = %if.then68, %if.then44
2946 %filename.0.in = phi i8* [ %call7220, %if.then68 ], [ %call6110, %if.then44 ]
2947 %filename.0 = bitcast i8* %filename.0.in to %1*
2948 %tmp17 = load i8*, i8** bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to i8**), align 16
2949 %tmp18 = bitcast i8* %tmp17 to i8 (i8*, %struct._message_ref_t*, i8*, ...)*
2950 %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)
2951 %tobool79 = icmp eq i8 %call78, 0
2952 br i1 %tobool79, label %land.lhs.true80, label %if.then109
2954 land.lhs.true80: ; preds = %if.end74
2955 %tmp82 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8
2956 %call84 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %filename.0.in, i8* %tmp82)
2957 %tobool86 = icmp eq i8 %call84, 0
2958 br i1 %tobool86, label %if.then109, label %if.end106
2960 if.end106: ; preds = %land.lhs.true80
2961 %tmp88 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8
2962 %tmp90 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8
2963 %tmp91 = bitcast %struct._class_t* %tmp88 to i8*
2964 %call9218 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp91, i8* %tmp90, i8* %filename.0.in)
2965 %tmp20 = bitcast i8* %call9218 to %5*
2966 %tmp21 = call i8* @llvm.objc.retain(i8* %call9218) nounwind
2967 %tmp22 = bitcast %5* %url.025 to i8*
2968 call void @llvm.objc.release(i8* %tmp22) nounwind
2969 %tmp94 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8
2970 %tmp95 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8
2971 %tmp96 = bitcast %struct._class_t* %tmp94 to i8*
2972 %call97 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp96, i8* %tmp95)
2973 %tmp99 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8
2974 %call10119 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call97, i8* %tmp99, i8* %call9218, i32 signext 1, %4** %err)
2975 %phitmp = icmp eq i8* %call10119, null
2976 br i1 %phitmp, label %if.then109, label %end
2978 if.then109: ; preds = %if.end106, %land.lhs.true80, %if.end74
2979 %url.129 = phi %5* [ %tmp20, %if.end106 ], [ %url.025, %if.end74 ], [ %url.025, %land.lhs.true80 ]
2980 %tmp110 = load %4*, %4** %err, align 8
2981 %tobool111 = icmp eq %4* %tmp110, null
2982 br i1 %tobool111, label %if.then112, label %if.end125
2984 if.then112: ; preds = %if.then109
2985 %tmp113 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_50", align 8
2986 %tmp114 = load %1*, %1** @NSCocoaErrorDomain, align 8
2987 %tmp115 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_51", align 8
2988 %call117 = call %1* @truncatedString(%1* %filename.0, i64 1034)
2989 %tmp118 = load %1*, %1** @NSFilePathErrorKey, align 8
2990 %tmp119 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_53", align 8
2991 %tmp120 = bitcast %struct._class_t* %tmp115 to i8*
2992 %call12113 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp120, i8* %tmp119, %1* %call117, %1* %tmp118, i8* null)
2993 %tmp122 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_55", align 8
2994 %tmp123 = bitcast %struct._class_t* %tmp113 to i8*
2995 %call12414 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp123, i8* %tmp122, %1* %tmp114, i64 258, i8* %call12113)
2996 %tmp23 = call i8* @llvm.objc.retain(i8* %call12414) nounwind
2997 %tmp25 = call i8* @llvm.objc.autorelease(i8* %tmp23) nounwind
2998 %tmp28 = bitcast i8* %tmp25 to %4*
2999 store %4* %tmp28, %4** %err, align 8
3002 if.end125: ; preds = %if.then112, %if.then109
3003 %tmp127 = phi %4* [ %tmp110, %if.then109 ], [ %tmp28, %if.then112 ]
3004 %tmp126 = load %struct._class_t*, %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_56", align 8
3005 %tmp128 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_58", align 8
3006 %tmp129 = bitcast %struct._class_t* %tmp126 to i8*
3007 %call13015 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %tmp129, i8* %tmp128, %4* %tmp127)
3008 %tmp131 = load i8*, i8** @"\01L_OBJC_SELECTOR_REFERENCES_60", align 8
3009 %call13317 = call i8* (i8*, i8*, ...) @objc_msgSend(i8* %call13015, i8* %tmp131)
3012 end: ; preds = %if.end125, %if.end106, %if.end, %land.lhs.true, %entry
3013 %filename.2 = phi %1* [ %filename.0, %if.end106 ], [ %filename.0, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
3014 %origFilename.0 = phi %1* [ %tmp, %if.end106 ], [ %tmp, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ]
3015 %url.2 = phi %5* [ %tmp20, %if.end106 ], [ %url.129, %if.end125 ], [ null, %land.lhs.true ], [ null, %entry ], [ %tmp13, %if.end ]
3016 call void @llvm.objc.release(i8* %tmp9) nounwind, !clang.imprecise_release !0
3017 %tmp29 = bitcast %5* %url.2 to i8*
3018 call void @llvm.objc.release(i8* %tmp29) nounwind, !clang.imprecise_release !0
3019 %tmp30 = bitcast %1* %origFilename.0 to i8*
3020 call void @llvm.objc.release(i8* %tmp30) nounwind, !clang.imprecise_release !0
3021 %tmp31 = bitcast %1* %filename.2 to i8*
3022 call void @llvm.objc.release(i8* %tmp31) nounwind, !clang.imprecise_release !0
3023 call void @llvm.objc.release(i8* %tmp7) nounwind, !clang.imprecise_release !0
3027 declare i32 @__gxx_personality_v0(...)
3029 declare i32 @llvm.objc.sync.enter(i8*)
3030 declare i32 @llvm.objc.sync.exit(i8*)
3032 ; Make sure that we understand that objc_sync_{enter,exit} are IC_User not
3033 ; IC_Call/IC_CallOrUser.
3035 ; CHECK-LABEL: define void @test67(
3036 ; CHECK-NEXT: call i32 @llvm.objc.sync.enter(i8* %x)
3037 ; CHECK-NEXT: call i32 @llvm.objc.sync.exit(i8* %x)
3038 ; CHECK-NEXT: ret void
3040 define void @test67(i8* %x) {
3041 call i8* @llvm.objc.retain(i8* %x)
3042 call i32 @llvm.objc.sync.enter(i8* %x)
3043 call i32 @llvm.objc.sync.exit(i8* %x)
3044 call void @llvm.objc.release(i8* %x), !clang.imprecise_release !0
3048 ; CHECK-LABEL: define void @test68(
3050 ; CHECK: call void @callee2(
3054 define void @test68(i8* %a, i8* %b) {
3055 call i8* @llvm.objc.retain(i8* %a)
3056 call i8* @llvm.objc.retain(i8* %b)
3057 call void @callee2(i8* %a, i8* %b)
3058 call void @llvm.objc.release(i8* %b), !clang.imprecise_release !0
3059 call void @llvm.objc.release(i8* %a), !clang.imprecise_release !0
3063 !llvm.module.flags = !{!1}
3064 !llvm.dbg.cu = !{!3}
3067 !1 = !{i32 1, !"Debug Info Version", i32 3}
3068 !2 = distinct !DISubprogram(unit: !3)
3069 !3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang",
3071 isOptimized: true, flags: "-O2",
3072 splitDebugFilename: "abc.debug", emissionKind: 2)
3073 !4 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
3074 !5 = !{i32 2, !"Debug Info Version", i32 3}
3076 ; CHECK: attributes [[NUW]] = { nounwind }
3077 ; CHECK: attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
3078 ; CHECK: ![[RELEASE]] = !{}