Lines Matching +full:- +full:release

1 ; RUN: opt -aa-pipeline=basic-aa -passes=objc-arc -S < %s | FileCheck %s
3 target datalayout = "e-p:64:64:64"
8 declare void @llvm.objc.release(ptr)
31 ; Simple retain+release pair deletion, with some intervening control
34 ; CHECK: define void @test0_precise(ptr %x, i1 %p) [[NUW:#[0-9]+]] {
36 ; CHECK: @llvm.objc.release
53 call void @llvm.objc.release(ptr %x) nounwind
58 ; CHECK-NOT: @llvm.objc.
75 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
79 ; Like test0 but the release isn't always executed when the retain is,
82 ; TODO: Make the llvm.objc.release's argument be %0.
86 ; CHECK: @llvm.objc.release(ptr %x)
104 call void @llvm.objc.release(ptr %x) nounwind
113 ; CHECK: @llvm.objc.release
131 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
144 ; CHECK-NOT: @llvm.objc.
146 ; CHECK: tail call void @llvm.objc.release(ptr %x) [[NUW]]
147 ; CHECK-NOT: @llvm.objc.
166 tail call void @llvm.objc.release(ptr %x) nounwind
170 ; CHECK-LABEL: define void @test1b_imprecise(
172 ; CHECK: tail call ptr @llvm.objc.retain(ptr %x) [[NUW:#[0-9]+]]
173 ; CHECK-NOT: @llvm.objc.
175 ; CHECK: tail call void @llvm.objc.release(ptr %x) [[NUW]], !clang.imprecise_release ![[RELEASE:[0-9]+]]
176 ; CHECK-NOT: @llvm.objc.
195 tail call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
203 ; CHECK-LABEL: define void @test2_precise(
205 ; CHECK: @llvm.objc.release
224 call void @llvm.objc.release(ptr %x) nounwind
228 ; CHECK-LABEL: define void @test2_imprecise(
230 ; CHECK: @llvm.objc.release
249 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
253 ; Like test0 but the release is in a loop,
258 ; CHECK-LABEL: define void @test3_precise(
260 ; TODO: @llvm.objc.release
268 call void @llvm.objc.release(ptr %x) nounwind
276 ; CHECK-LABEL: define void @test3_imprecise(
278 ; TODO: @llvm.objc.release
286 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
300 ; CHECK-LABEL: define void @test4_precise(
302 ; TODO: @llvm.objc.release
314 call void @llvm.objc.release(ptr %x) nounwind
318 ; CHECK-LABEL: define void @test4_imprecise(
320 ; TODO: @llvm.objc.release
332 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
340 ; CHECK-LABEL: define void @test5a(
342 ; CHECK: @llvm.objc.release
350 call void @llvm.objc.release(ptr %x) nounwind
354 ; CHECK-LABEL: define void @test5b(
356 ; CHECK: @llvm.objc.release
364 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
369 ; retain+release pair deletion, where the release happens on two different
372 ; CHECK-LABEL: define void @test6a(
376 ; CHECK: call void @llvm.objc.release
378 ; CHECK: call void @llvm.objc.release
389 call void @llvm.objc.release(ptr %x) nounwind
395 call void @llvm.objc.release(ptr %x) nounwind
402 ; CHECK-LABEL: define void @test6b(
403 ; CHECK-NOT: @llvm.objc.
413 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
419 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
426 ; CHECK-LABEL: define void @test6c(
430 ; CHECK: call void @llvm.objc.release
432 ; CHECK: call void @llvm.objc.release
443 call void @llvm.objc.release(ptr %x) nounwind
449 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
456 ; CHECK-LABEL: define void @test6d(
460 ; CHECK: call void @llvm.objc.release
462 ; CHECK: call void @llvm.objc.release
473 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
479 call void @llvm.objc.release(ptr %x) nounwind
487 ; retain+release pair deletion, where the retain happens on two different
490 ; CHECK-LABEL: define void @test7(
492 ; CHECK-NOT: llvm.objc.
498 ; CHECK: call void @llvm.objc.release
517 call void @llvm.objc.release(ptr %x) nounwind
521 ; CHECK-LABEL: define void @test7b(
522 ; CHECK-NOT: @llvm.objc.
541 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
547 ; CHECK-LABEL: define void @test7c(
553 ; CHECK: call void @llvm.objc.release
572 call void @llvm.objc.release(ptr %x) nounwind
576 ; retain+release pair deletion, where the retain and release both happen on
579 ; CHECK-LABEL: define void @test8a(
587 ; CHECK: @llvm.objc.release
589 ; CHECK: @llvm.objc.release
612 call void @llvm.objc.release(ptr %x) nounwind
616 call void @llvm.objc.release(ptr %x) nounwind
623 ; CHECK-LABEL: define void @test8b(
624 ; CHECK-NOT: @llvm.objc.
646 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
650 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
657 ; CHECK-LABEL: define void @test8c(
660 ; CHECK-NOT: @llvm.objc.
662 ; CHECK-NOT: @llvm.objc.
666 ; CHECK: @llvm.objc.release
668 ; CHECK-NOT: @llvm.objc.
691 call void @llvm.objc.release(ptr %x) nounwind
695 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
702 ; CHECK-LABEL: define void @test8d(
710 ; CHECK: @llvm.objc.release
712 ; CHECK: @llvm.objc.release
735 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
739 call void @llvm.objc.release(ptr %x) nounwind
746 ; Trivial retain+release pair deletion.
748 ; CHECK-LABEL: define void @test9(
749 ; CHECK-NOT: @llvm.objc.
754 call void @llvm.objc.release(ptr %0) nounwind
758 ; Retain+release pair, but on an unknown pointer relationship. Don't delete!
760 ; CHECK-LABEL: define void @test9b(
762 ; CHECK: @llvm.objc.release(ptr %s)
768 call void @llvm.objc.release(ptr %s) nounwind
772 ; Trivial retain+release pair with intervening calls - don't delete!
774 ; CHECK-LABEL: define void @test10(
778 ; CHECK: @llvm.objc.release
785 call void @llvm.objc.release(ptr %0) nounwind
793 ; CHECK-LABEL: define void @test11(
807 ; CHECK-LABEL: define void @test11a(
809 ; CHECK-NEXT: ret void
822 ; CHECK-LABEL: define ptr @test11b(
833 ; We can not delete this retain, release since we do not have a post-dominating
834 ; use of the release.
836 ; CHECK-LABEL: define void @test12(
837 ; CHECK-NEXT: entry:
838 ; CHECK-NEXT: @llvm.objc.retain(ptr %x)
839 ; CHECK-NEXT: @llvm.objc.retain
840 ; CHECK: @llvm.objc.release
848 call void @llvm.objc.release(ptr %x) nounwind
854 ; CHECK-LABEL: define void @test13(
869 ; Delete the retain+release pair.
871 ; CHECK-LABEL: define void @test13b(
872 ; CHECK-NEXT: entry:
873 ; CHECK-NEXT: @llvm.objc.retain(ptr %x)
874 ; CHECK-NEXT: @use_pointer
875 ; CHECK-NEXT: @use_pointer
876 ; CHECK-NEXT: @use_pointer
877 ; CHECK-NEXT: @llvm.objc.release
878 ; CHECK-NEXT: ret void
879 ; CHECK-NEXT: }
886 call void @llvm.objc.release(ptr %x) nounwind
888 call void @llvm.objc.release(ptr %x) nounwind
892 ; Don't delete the retain+release pair because there's an
895 ; CHECK-LABEL: define void @test13c(
900 ; CHECK: @llvm.objc.release
909 call void @llvm.objc.release(ptr %x) nounwind
916 ; CHECK-LABEL: define void @test13d(
917 ; CHECK-NEXT: entry:
918 ; CHECK-NEXT: @llvm.objc.retain(ptr %x)
919 ; CHECK-NEXT: @llvm.objc.autoreleasePoolPush
920 ; CHECK-NEXT: @use_pointer
921 ; CHECK-NEXT: @use_pointer
922 ; CHECK-NEXT: @use_pointer
923 ; CHECK-NEXT: @llvm.objc.release
924 ; CHECK-NEXT: ret void
925 ; CHECK-NEXT: }
933 call void @llvm.objc.release(ptr %x) nounwind
935 call void @llvm.objc.release(ptr %x) nounwind
939 ; Trivial retain,release pair with intervening call, and it's post-dominated by
940 ; another release. But it is not known safe in the top down direction. We can
943 ; CHECK-LABEL: define void @test14(
944 ; CHECK-NEXT: entry:
945 ; CHECK-NEXT: @llvm.objc.retain
946 ; CHECK-NEXT: @use_pointer
947 ; CHECK-NEXT: @use_pointer
948 ; CHECK-NEXT: @llvm.objc.release
949 ; CHECK-NEXT: @llvm.objc.release
950 ; CHECK-NEXT: ret void
951 ; CHECK-NEXT: }
957 call void @llvm.objc.release(ptr %x) nounwind
958 call void @llvm.objc.release(ptr %x) nounwind
962 ; Trivial retain,autorelease pair with intervening call, but it's post-dominated
963 ; by another release. Don't delete anything.
965 ; CHECK-LABEL: define void @test15(
966 ; CHECK-NEXT: entry:
967 ; CHECK-NEXT: @llvm.objc.retain(ptr %x)
968 ; CHECK-NEXT: @use_pointer
969 ; CHECK-NEXT: @llvm.objc.autorelease(ptr %x)
970 ; CHECK-NEXT: @llvm.objc.release
971 ; CHECK-NEXT: ret void
972 ; CHECK-NEXT: }
978 call void @llvm.objc.release(ptr %x) nounwind
982 ; Trivial retain,autorelease pair, post-dominated
983 ; by another release. Delete the retain and release.
985 ; CHECK-LABEL: define void @test15b(
986 ; CHECK-NEXT: entry:
987 ; CHECK-NEXT: @llvm.objc.retain
988 ; CHECK-NEXT: @llvm.objc.autorelease
989 ; CHECK-NEXT: @llvm.objc.release
990 ; CHECK-NEXT: ret void
991 ; CHECK-NEXT: }
996 call void @llvm.objc.release(ptr %x) nounwind
1000 ; CHECK-LABEL: define void @test15c(
1001 ; CHECK-NEXT: entry:
1002 ; CHECK-NEXT: @llvm.objc.autorelease
1003 ; CHECK-NEXT: ret void
1004 ; CHECK-NEXT: }
1009 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
1013 ; Retain+release pairs in diamonds, all dominated by a retain.
1015 ; CHECK-LABEL: define void @test16a(
1017 ; CHECK-NOT: @objc
1020 ; CHECK: @llvm.objc.release
1041 call void @llvm.objc.release(ptr %x) nounwind
1045 call void @llvm.objc.release(ptr %x) nounwind
1050 call void @llvm.objc.release(ptr %x) nounwind
1054 ; CHECK-LABEL: define void @test16b(
1056 ; CHECK-NOT: @objc
1058 ; CHECK-NEXT: @use_pointer
1059 ; CHECK-NEXT: @use_pointer
1060 ; CHECK-NEXT: @llvm.objc.release
1081 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
1085 call void @llvm.objc.release(ptr %x) nounwind
1091 call void @llvm.objc.release(ptr %x) nounwind
1095 ; CHECK-LABEL: define void @test16c(
1097 ; CHECK-NOT: @objc
1100 ; CHECK: @llvm.objc.release
1121 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
1125 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
1130 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
1134 ; CHECK-LABEL: define void @test16d(
1157 call void @llvm.objc.release(ptr %x) nounwind
1161 call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
1168 ; Delete no-ops.
1170 ; CHECK-LABEL: define void @test18(
1171 ; CHECK-NOT: @llvm.objc.
1175 call void @llvm.objc.release(ptr null)
1180 ; Delete no-ops where undef can be assumed to be null.
1182 ; CHECK-LABEL: define void @test18b(
1183 ; CHECK-NOT: @llvm.objc.
1187 call void @llvm.objc.release(ptr undef)
1199 ; CHECK: call void @llvm.objc.release(ptr %y)
1207 call void @llvm.objc.release(ptr %y)
1213 ; CHECK-LABEL: define void @test20(
1215 ; CHECK-NEXT: invoke
1240 ; CHECK-LABEL: define ptr @test21(
1242 ; CHECK-NEXT: ret ptr %call
1243 ; CHECK-NEXT: }
1254 ; CHECK-LABEL: define void @test22(
1256 ; CHECK: call void @llvm.objc.release(ptr %p)
1259 ; CHECK-NOT: @llvm.objc.release
1269 call void @llvm.objc.release(ptr %h), !clang.imprecise_release !0
1273 ; Do not move an llvm.objc.release that doesn't have the clang.imprecise_release tag.
1275 ; CHECK-LABEL: define void @test22_precise(
1277 ; CHECK: call void @llvm.objc.release(ptr %[[P0]])
1287 call void @llvm.objc.release(ptr %h)
1293 ; CHECK-LABEL: define void @test24(
1295 ; CHECK: @llvm.objc.release
1301 call void @llvm.objc.release(ptr %a)
1305 ; Don't move a retain/release pair if the release can be moved
1308 ; CHECK-LABEL: define void @test25(
1313 ; CHECK: call void @llvm.objc.release(ptr %p)
1326 call void @llvm.objc.release(ptr %p)
1330 ; Don't move a retain/release pair if the retain can be moved
1331 ; but the release can't be moved to balance it.
1333 ; CHECK-LABEL: define void @test26(
1338 ; CHECK: call void @llvm.objc.release(ptr %p)
1351 call void @llvm.objc.release(ptr %p)
1355 ; Don't sink the retain,release into the loop.
1357 ; CHECK-LABEL: define void @test27(
1361 ; CHECK-NOT: @llvm.objc.
1363 ; CHECK: call void @llvm.objc.release
1376 call void @llvm.objc.release(ptr %p)
1382 ; CHECK-LABEL: define void @test28(
1383 ; CHECK-NOT: @llvm.objc.
1388 ; CHECK: call void @llvm.objc.release
1390 ; CHECK-NOT: @llvm.objc.
1403 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
1410 ; CHECK-LABEL: define void @test28b(
1413 ; CHECK-NOT: @llvm.objc.
1415 ; CHECK-NOT: @llvm.objc.
1417 ; CHECK-NOT: @llvm.objc.
1419 ; CHECK: @llvm.objc.release
1433 call void @llvm.objc.release(ptr %p)
1440 ; CHECK-LABEL: define void @test28c(
1441 ; CHECK-NOT: @llvm.objc.
1446 ; CHECK: call void @llvm.objc.release(ptr %p) [[NUW]], !clang.imprecise_release
1448 ; CHECK-NOT: @llvm.objc.
1462 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
1468 ; CHECK-LABEL: define void @test29(
1474 ; CHECK: call void @llvm.objc.release
1476 ; CHECK: call void @llvm.objc.release
1489 call void @llvm.objc.release(ptr %p)
1493 call void @llvm.objc.release(ptr %p)
1498 ; with an extra release.
1500 ; CHECK-LABEL: define void @test30(
1507 ; CHECK: call void @llvm.objc.release
1509 ; CHECK: call void @llvm.objc.release
1525 call void @llvm.objc.release(ptr %p)
1529 call void @llvm.objc.release(ptr %p)
1533 ; Basic case with a mergeable release.
1535 ; CHECK-LABEL: define void @test31(
1540 ; CHECK: call void @llvm.objc.release
1542 ; CHECK: call void @llvm.objc.release
1552 call void @llvm.objc.release(ptr %p)
1555 call void @llvm.objc.release(ptr %p)
1561 ; CHECK-LABEL: define void @test32(
1567 ; CHECK: call void @llvm.objc.release
1580 call void @llvm.objc.release(ptr %p)
1586 ; CHECK-LABEL: define void @test33(
1592 ; CHECK: call void @llvm.objc.release
1605 call void @llvm.objc.release(ptr %p)
1609 ; Delete retain,release if there's just a possible dec and we have imprecise
1612 ; CHECK-LABEL: define void @test34a(
1616 ; CHECK: call void @llvm.objc.release
1628 call void @llvm.objc.release(ptr %p)
1632 ; CHECK-LABEL: define void @test34b(
1633 ; CHECK-NOT: @llvm.objc.
1645 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
1650 ; Delete retain,release if there's just a use and we do not have a precise
1651 ; release.
1654 ; CHECK-LABEL: define void @test35a(
1659 ; CHECK: call void @llvm.objc.release
1671 call void @llvm.objc.release(ptr %p)
1676 ; CHECK-LABEL: define void @test35b(
1677 ; CHECK-NOT: @llvm.objc.
1689 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
1693 ; Delete a retain,release if there's no actual use and we have precise release.
1695 ; CHECK-LABEL: define void @test36a(
1698 ; CHECK-NOT: @llvm.objc.
1700 ; CHECK: @llvm.objc.release
1707 call void @llvm.objc.release(ptr %p)
1713 ; CHECK-LABEL: define void @test36b(
1714 ; CHECK-NOT: @llvm.objc.
1721 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
1727 ; CHECK-LABEL: define void @test38(
1728 ; CHECK-NOT: @llvm.objc.
1755 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
1759 ; Delete retain,release pairs around loops.
1761 ; CHECK-LABEL: define void @test39(
1762 ; CHECK-NOT: @llvm.objc.
1773 call void @llvm.objc.release(ptr %0), !clang.imprecise_release !0
1777 ; Delete retain,release pairs around loops containing uses.
1779 ; CHECK-LABEL: define void @test39b(
1780 ; CHECK-NOT: @llvm.objc.
1792 call void @llvm.objc.release(ptr %0), !clang.imprecise_release !0
1796 ; Delete retain,release pairs around loops containing potential decrements.
1798 ; CHECK-LABEL: define void @test39c(
1799 ; CHECK-NOT: @llvm.objc.
1811 call void @llvm.objc.release(ptr %0), !clang.imprecise_release !0
1815 ; Delete retain,release pairs around loops even if
1818 ; CHECK-LABEL: define void @test40(
1819 ; CHECK-NOT: @llvm.objc.
1831 call void @llvm.objc.release(ptr %0), !clang.imprecise_release !0
1835 ; Do the known-incremented retain+release elimination even if the pointer
1838 ; CHECK-LABEL: define void @test42(
1839 ; CHECK-NEXT: entry:
1840 ; CHECK-NEXT: call ptr @llvm.objc.retain(ptr %p)
1841 ; CHECK-NEXT: call ptr @llvm.objc.autorelease(ptr %p)
1842 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1843 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1844 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1845 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1846 ; CHECK-NEXT: call void @llvm.objc.release(ptr %p)
1847 ; CHECK-NEXT: ret void
1848 ; CHECK-NEXT: }
1856 call void @llvm.objc.release(ptr %p)
1859 call void @llvm.objc.release(ptr %p)
1863 ; Don't the known-incremented retain+release elimination if the pointer is
1866 ; CHECK-LABEL: define void @test43(
1867 ; CHECK-NEXT: entry:
1868 ; CHECK-NEXT: call ptr @llvm.objc.retain(ptr %p)
1869 ; CHECK-NEXT: call ptr @llvm.objc.autorelease(ptr %p)
1870 ; CHECK-NEXT: call ptr @llvm.objc.retain
1871 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1872 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1873 ; CHECK-NEXT: call void @llvm.objc.autoreleasePoolPop(ptr undef)
1874 ; CHECK-NEXT: call void @llvm.objc.release
1875 ; CHECK-NEXT: ret void
1876 ; CHECK-NEXT: }
1885 call void @llvm.objc.release(ptr %p)
1889 ; Do the known-incremented retain+release elimination if the pointer is
1892 ; CHECK-LABEL: define void @test43b(
1893 ; CHECK-NEXT: entry:
1894 ; CHECK-NEXT: call ptr @llvm.objc.retain(ptr %p)
1895 ; CHECK-NEXT: call ptr @llvm.objc.autorelease(ptr %p)
1896 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1897 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1898 ; CHECK-NEXT: call ptr @llvm.objc.autoreleasePoolPush()
1899 ; CHECK-NEXT: call void @use_pointer(ptr %p)
1900 ; CHECK-NEXT: call void @llvm.objc.release
1901 ; CHECK-NEXT: ret void
1902 ; CHECK-NEXT: }
1911 call void @llvm.objc.release(ptr %p)
1913 call void @llvm.objc.release(ptr %p)
1917 ; Do retain+release elimination for non-provenance pointers.
1919 ; CHECK-LABEL: define void @test44(
1920 ; CHECK-NOT: llvm.objc.
1925 call void @llvm.objc.release(ptr %q)
1929 ; Don't delete retain+release with an unknown-provenance
1930 ; may-alias llvm.objc.release between them.
1932 ; CHECK-LABEL: define void @test45(
1934 ; CHECK: call void @llvm.objc.release(ptr %q)
1936 ; CHECK: call void @llvm.objc.release(ptr %p)
1942 call void @llvm.objc.release(ptr %q)
1944 call void @llvm.objc.release(ptr %p)
1950 ; CHECK-LABEL: define void @test46(
1969 ; Delete no-op cast calls.
1971 ; CHECK-LABEL: define ptr @test47(
1972 ; CHECK-NOT: call
1980 ; Delete no-op cast calls.
1982 ; CHECK-LABEL: define ptr @test48(
1983 ; CHECK-NOT: call
1991 ; Delete no-op cast calls.
1993 ; CHECK-LABEL: define ptr @test49(
1994 ; CHECK-NOT: call
2002 ; Do delete retain+release with intervening stores of the address value if we
2003 ; have imprecise release attached to llvm.objc.release.
2005 ; CHECK-LABEL: define void @test50a(
2006 ; CHECK-NEXT: call ptr @llvm.objc.retain
2007 ; CHECK-NEXT: call void @callee
2008 ; CHECK-NEXT: store
2009 ; CHECK-NEXT: call void @llvm.objc.release
2010 ; CHECK-NEXT: ret void
2011 ; CHECK-NEXT: }
2016 call void @llvm.objc.release(ptr %p)
2020 ; CHECK-LABEL: define void @test50b(
2021 ; CHECK-NOT: @llvm.objc.
2027 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
2032 ; Don't delete retain+release with intervening stores through the
2035 ; CHECK-LABEL: define void @test51a(
2037 ; CHECK: call void @llvm.objc.release(ptr %p)
2044 call void @llvm.objc.release(ptr %p)
2048 ; CHECK-LABEL: define void @test51b(
2050 ; CHECK: call void @llvm.objc.release(ptr %p)
2057 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
2061 ; Don't delete retain+release with intervening use of a pointer of
2064 ; CHECK-LABEL: define void @test52a(
2068 ; CHECK: call void @llvm.objc.release
2077 call void @llvm.objc.release(ptr %p)
2081 ; CHECK-LABEL: define void @test52b(
2085 ; CHECK: call void @llvm.objc.release
2094 call void @llvm.objc.release(ptr %p), !clang.imprecise_release !0
2103 ; CHECK-LABEL: define void @test53(
2112 call void @llvm.objc.release(ptr %p)
2116 ; Convert autorelease to release if the value is unused.
2118 ; CHECK-LABEL: define void @test54(
2120 ; CHECK-NEXT: call void @llvm.objc.release(ptr %t) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2121 ; CHECK-NEXT: ret void
2129 ; Nested retain+release pairs. Delete them both.
2131 ; CHECK-LABEL: define void @test55(
2132 ; CHECK-NOT: @objc
2138 call void @llvm.objc.release(ptr %x) nounwind
2139 call void @llvm.objc.release(ptr %x) nounwind
2143 ; Nested retain+release pairs where the inner pair depends
2148 ; CHECK-LABEL: define void @test56(
2149 ; CHECK-NOT: @objc
2151 ; CHECK-NEXT: %0 = tail call ptr @llvm.objc.retain(ptr %x) [[NUW]]
2152 ; CHECK-NEXT: tail call void @use_pointer(ptr %x)
2153 ; CHECK-NEXT: tail call void @use_pointer(ptr %x)
2154 ; CHECK-NEXT: tail call void @llvm.objc.release(ptr %x) [[NUW]], !clang.imprecise_release ![[RELEASE]]
2155 ; CHECK-NEXT: br label %if.end
2156 ; CHECK-NOT: @objc
2169 tail call void @llvm.objc.release(ptr %2) nounwind, !clang.imprecise_release !0
2173 tail call void @llvm.objc.release(ptr %1) nounwind, !clang.imprecise_release !0
2174 tail call void @llvm.objc.release(ptr %0) nounwind, !clang.imprecise_release !0
2178 ; When there are adjacent retain+release pairs, the first one is known
2182 ; CHECK-LABEL: define void @test57(
2183 ; CHECK-NEXT: entry:
2184 ; CHECK-NEXT: tail call ptr @llvm.objc.retain(ptr %x) [[NUW]]
2185 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2186 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2187 ; CHECK-NEXT: tail call ptr @llvm.objc.retain(ptr %x) [[NUW]]
2188 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2189 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2190 ; CHECK-NEXT: call void @llvm.objc.release(ptr %x) [[NUW]]
2191 ; CHECK-NEXT: ret void
2192 ; CHECK-NEXT: }
2199 call void @llvm.objc.release(ptr %x) nounwind
2203 call void @llvm.objc.release(ptr %x) nounwind
2207 ; An adjacent retain+release pair is sufficient even if it will be
2210 ; CHECK-LABEL: define void @test58(
2211 ; CHECK-NEXT: entry:
2212 ; CHECK-NEXT: @llvm.objc.retain
2213 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2214 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2215 ; CHECK-NEXT: ret void
2216 ; CHECK-NEXT: }
2223 call void @llvm.objc.release(ptr %x) nounwind
2225 call void @llvm.objc.release(ptr %x) nounwind
2229 ; Don't delete the second retain+release pair in an adjacent set.
2231 ; CHECK-LABEL: define void @test59(
2232 ; CHECK-NEXT: entry:
2233 ; CHECK-NEXT: %0 = tail call ptr @llvm.objc.retain(ptr %x) [[NUW]]
2234 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2235 ; CHECK-NEXT: call void @use_pointer(ptr %x)
2236 ; CHECK-NEXT: call void @llvm.objc.release(ptr %x) [[NUW]]
2237 ; CHECK-NEXT: ret void
2238 ; CHECK-NEXT: }
2242 call void @llvm.objc.release(ptr %x) nounwind
2246 call void @llvm.objc.release(ptr %x) nounwind
2255 ; We have a precise lifetime retain/release here. We can not remove them since
2258 ; CHECK-LABEL: define void @test60a(
2260 ; CHECK: call void @llvm.objc.release
2268 call void @llvm.objc.release(ptr %s)
2272 ; CHECK-LABEL: define void @test60b(
2274 ; CHECK-NOT: call ptr @llvm.objc.retain
2275 ; CHECK-NOT: call ptr @llvm.objc.release
2284 call void @llvm.objc.release(ptr %t)
2288 ; CHECK-LABEL: define void @test60c(
2289 ; CHECK-NOT: @llvm.objc.
2297 call void @llvm.objc.release(ptr %t), !clang.imprecise_release !0
2301 ; CHECK-LABEL: define void @test60d(
2302 ; CHECK-NOT: @llvm.objc.
2310 call void @llvm.objc.release(ptr %t)
2314 ; CHECK-LABEL: define void @test60e(
2315 ; CHECK-NOT: @llvm.objc.
2323 call void @llvm.objc.release(ptr %t), !clang.imprecise_release !0
2330 ; CHECK-LABEL: define void @test61(
2331 ; CHECK-NOT: @llvm.objc.
2338 call void @llvm.objc.release(ptr %t)
2345 ; CHECK-LABEL: define void @test62(
2346 ; CHECK-NOT: @llvm.objc.
2358 call void @llvm.objc.release(ptr %x)
2362 call void @llvm.objc.release(ptr %x)
2366 ; Like test62 but with no release in exit.
2369 ; CHECK-LABEL: define void @test63(
2373 ; CHECK: call void @llvm.objc.release(ptr %x)
2385 call void @llvm.objc.release(ptr %x)
2392 ; Like test62 but with no release in loop.more.
2395 ; CHECK-LABEL: define void @test64(
2399 ; CHECK: call void @llvm.objc.release(ptr %x)
2414 call void @llvm.objc.release(ptr %x)
2420 ; CHECK-LABEL: define ptr @test65(
2424 ; CHECK-NOT: @llvm.objc.autorelease
2443 ; CHECK-LABEL: define ptr @test65b(
2445 ; CHECK-NOT: @llvm.objc.autorelease
2469 ; CHECK-LABEL: define ptr @test65c(
2471 ; CHECK-NOT: @llvm.objc.autorelease
2490 ; CHECK-LABEL: define ptr @test65d(
2492 ; CHECK-NOT: @llvm.objc.autorelease
2511 ; An llvm.objc.retain can serve as a may-use for a different pointer.
2514 ; CHECK-LABEL: define void @test66a(
2516 ; CHECK: tail call void @llvm.objc.release(ptr %call) [[NUW]]
2518 ; CHECK: tail call void @llvm.objc.release(ptr %cond) [[NUW]]
2530 tail call void @llvm.objc.release(ptr %call) nounwind
2533 tail call void @llvm.objc.release(ptr %cond) nounwind
2537 ; CHECK-LABEL: define void @test66b(
2539 ; CHECK: tail call void @llvm.objc.release(ptr %call) [[NUW]]
2541 ; CHECK: tail call void @llvm.objc.release(ptr %cond) [[NUW]]
2553 tail call void @llvm.objc.release(ptr %call) nounwind, !clang.imprecise_release !0
2556 tail call void @llvm.objc.release(ptr %cond) nounwind
2560 ; CHECK-LABEL: define void @test66c(
2562 ; CHECK: tail call void @llvm.objc.release(ptr %call) [[NUW]]
2564 ; CHECK: tail call void @llvm.objc.release(ptr %cond) [[NUW]]
2576 tail call void @llvm.objc.release(ptr %call) nounwind
2579 tail call void @llvm.objc.release(ptr %cond) nounwind
2583 ; CHECK-LABEL: define void @test66d(
2585 ; CHECK: tail call void @llvm.objc.release(ptr %call) [[NUW]]
2587 ; CHECK: tail call void @llvm.objc.release(ptr %cond) [[NUW]]
2599 tail call void @llvm.objc.release(ptr %call) nounwind, !clang.imprecise_release !0
2602 tail call void @llvm.objc.release(ptr %cond) nounwind, !clang.imprecise_release !0
2606 ; A few real-world testcases.
2608 @.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
2612 @str = internal constant [16 x i8] c"-[ Top0 _getX ]\00"
2614 ; FIXME: Should be able to eliminate the retain and release
2615 ; CHECK-LABEL: define { <2 x float>, <2 x float> } @"\01-[A z]"(ptr %self, ptr captures(none) %_cmd)
2617 ; CHECK-NEXT: %call = tail call i32 (ptr, ...) @printf(
2618 ; CHECK: tail call void @llvm.objc.release(ptr %self)
2620 define { <2 x float>, <2 x float> } @"\01-[A z]"(ptr %self, ptr captures(none) %_cmd) nounwind {
2645 tail call void @llvm.objc.release(ptr %self) nounwind
2656 ; FIXME: Should be able to eliminate the retain and release
2657 ; CHECK-LABEL: @"\01-[Top0 _getX]"(ptr %self, ptr captures(none) %_cmd)
2660 ; CHECK: tail call void @llvm.objc.release(ptr %self)
2661 define i32 @"\01-[Top0 _getX]"(ptr %self, ptr captures(none) %_cmd) nounwind {
2665 tail call void @llvm.objc.release(ptr %self) nounwind
2673 ; A simple loop. Eliminate the retain and release inside of it!
2677 ; CHECK-NOT: @llvm.objc.
2679 ; CHECK-NOT: @llvm.objc.
2693 tail call void @llvm.objc.release(ptr %1) nounwind, !clang.imprecise_release !0
2699 tail call void @llvm.objc.release(ptr %x) nounwind, !clang.imprecise_release !0
2703 ; ObjCARCOpt can delete the retain,release on self.
2706 ; CHECK-NOT: call ptr @llvm.objc.retain(ptr %tmp7)
2780 call void @llvm.objc.release(ptr null) nounwind
2782 call void @llvm.objc.release(ptr null) nounwind
2797 call void @llvm.objc.release(ptr null) nounwind
2824 call void @llvm.objc.release(ptr %call137) nounwind
2834 call void @llvm.objc.release(ptr %call6110) nounwind
2855 call void @llvm.objc.release(ptr %url.025) nounwind
2898 call void @llvm.objc.release(ptr %tmp9) nounwind, !clang.imprecise_release !0
2899 call void @llvm.objc.release(ptr %url.2) nounwind, !clang.imprecise_release !0
2900 call void @llvm.objc.release(ptr %origFilename.0) nounwind, !clang.imprecise_release !0
2901 call void @llvm.objc.release(ptr %filename.2) nounwind, !clang.imprecise_release !0
2902 call void @llvm.objc.release(ptr %self) nounwind, !clang.imprecise_release !0
2914 ; CHECK-LABEL: define void @test67(
2915 ; CHECK-NEXT: call i32 @llvm.objc.sync.enter(ptr %x)
2916 ; CHECK-NEXT: call i32 @llvm.objc.sync.exit(ptr %x)
2917 ; CHECK-NEXT: ret void
2918 ; CHECK-NEXT: }
2923 call void @llvm.objc.release(ptr %x), !clang.imprecise_release !0
2927 ; CHECK-LABEL: define void @test68(
2928 ; CHECK-NOT: call
2930 ; CHECK-NOT: call
2937 call void @llvm.objc.release(ptr %b), !clang.imprecise_release !0
2938 call void @llvm.objc.release(ptr %a), !clang.imprecise_release !0
2950 isOptimized: true, flags: "-O2",
2956 ; CHECK: ![[RELEASE]] = !{}