declare i8* @returner()
declare void @bar(i32 ()*)
-declare void @llvm.dbg.value(metadata, i64, metadata)
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
declare i8* @objc_msgSend(i8*, i8*, ...)
ret void
}
-; CHECK: define void @test1b_imprecise(
+; CHECK-LABEL: define void @test1b_imprecise(
; CHECK: entry:
; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW:#[0-9]+]]
; CHECK-NOT: @objc_
; CHECK: if.end5:
-; CHECK: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release !0
+; CHECK: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE:[0-9]+]]
; CHECK-NOT: @objc_
; CHECK: }
define void @test1b_imprecise(i8* %x, i1 %p, i1 %q) {
; Like test0 but the pointer is passed to an intervening call,
; so the optimization is not safe.
-; CHECK: define void @test2_precise(
+; CHECK-LABEL: define void @test2_precise(
; CHECK: @objc_retain(i8* %a)
; CHECK: @objc_release
; CHECK: }
ret void
}
-; CHECK: define void @test2_imprecise(
+; CHECK-LABEL: define void @test2_imprecise(
; CHECK: @objc_retain(i8* %a)
; CHECK: @objc_release
; CHECK: }
; TODO: For now, assume this can't happen.
-; CHECK: define void @test3_precise(
+; CHECK-LABEL: define void @test3_precise(
; TODO: @objc_retain(i8* %a)
; TODO: @objc_release
; CHECK: }
ret void
}
-; CHECK: define void @test3_imprecise(
+; CHECK-LABEL: define void @test3_imprecise(
; TODO: @objc_retain(i8* %a)
; TODO: @objc_release
; CHECK: }
; Like test0 but the retain is in a loop,
; so the optimization is not safe.
-; CHECK: define void @test4_precise(
+; CHECK-LABEL: define void @test4_precise(
; TODO: @objc_retain(i8* %a)
; TODO: @objc_release
; CHECK: }
ret void
}
-; CHECK: define void @test4_imprecise(
+; CHECK-LABEL: define void @test4_imprecise(
; TODO: @objc_retain(i8* %a)
; TODO: @objc_release
; CHECK: }
; Like test0 but the pointer is conditionally passed to an intervening call,
; so the optimization is not safe.
-; CHECK: define void @test5a(
+; CHECK-LABEL: define void @test5a(
; CHECK: @objc_retain(i8*
; CHECK: @objc_release
; CHECK: }
ret void
}
-; CHECK: define void @test5b(
+; CHECK-LABEL: define void @test5b(
; CHECK: @objc_retain(i8*
; CHECK: @objc_release
; CHECK: }
; retain+release pair deletion, where the release happens on two different
; flow paths.
-; CHECK: define void @test6a(
+; CHECK-LABEL: define void @test6a(
; CHECK: entry:
; CHECK: tail call i8* @objc_retain(
; CHECK: t:
ret void
}
-; CHECK: define void @test6b(
+; CHECK-LABEL: define void @test6b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test6b(i32* %x, i1 %p) nounwind {
ret void
}
-; CHECK: define void @test6c(
+; CHECK-LABEL: define void @test6c(
; CHECK: entry:
; CHECK: tail call i8* @objc_retain(
; CHECK: t:
ret void
}
-; CHECK: define void @test6d(
+; CHECK-LABEL: define void @test6d(
; CHECK: entry:
; CHECK: tail call i8* @objc_retain(
; CHECK: t:
; retain+release pair deletion, where the retain happens on two different
; flow paths.
-; CHECK: define void @test7(
+; CHECK-LABEL: define void @test7(
; CHECK: entry:
; CHECK-NOT: objc_
; CHECK: t:
ret void
}
-; CHECK: define void @test7b(
+; CHECK-LABEL: define void @test7b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test7b(i32* %x, i1 %p) nounwind {
; Like test7, but there's a retain/retainBlock mismatch. Don't delete!
-; CHECK: define void @test7c
+; CHECK-LABEL: define void @test7c(
; CHECK: t:
; CHECK: call i8* @objc_retainBlock
; CHECK: f:
; retain+release pair deletion, where the retain and release both happen on
; different flow paths. Wild!
-; CHECK: define void @test8a(
+; CHECK-LABEL: define void @test8a(
; CHECK: entry:
; CHECK: t:
; CHECK: @objc_retain
ret void
}
-; CHECK: define void @test8b(
+; CHECK-LABEL: define void @test8b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test8b(i32* %x, i1 %p, i1 %q) nounwind {
ret void
}
-; CHECK: define void @test8c(
+; CHECK-LABEL: define void @test8c(
; CHECK: entry:
; CHECK: t:
; CHECK: @objc_retain
ret void
}
-; CHECK: define void @test8d(
+; CHECK-LABEL: define void @test8d(
; CHECK: entry:
; CHECK: t:
; CHECK: @objc_retain
; Trivial retain+release pair deletion.
-; CHECK: define void @test9(
+; CHECK-LABEL: define void @test9(
; CHECK-NOT: @objc_
; CHECK: }
define void @test9(i8* %x) nounwind {
; Retain+release pair, but on an unknown pointer relationship. Don't delete!
-; CHECK: define void @test9b
+; CHECK-LABEL: define void @test9b(
; CHECK: @objc_retain(i8* %x)
; CHECK: @objc_release(i8* %s)
; CHECK: }
; Trivial retain+release pair with intervening calls - don't delete!
-; CHECK: define void @test10(
+; CHECK-LABEL: define void @test10(
; CHECK: @objc_retain(i8* %x)
; CHECK: @callee
; CHECK: @use_pointer
; Also, add a tail keyword, since objc_retain can never be passed
; a stack argument.
-; CHECK: define void @test11(
+; CHECK-LABEL: define void @test11(
; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]]
; CHECK: }
; Same as test11 but with no use_pointer call. Delete the pair!
-; CHECK: define void @test11a(
+; CHECK-LABEL: define void @test11a(
; CHECK: entry:
; CHECK-NEXT: ret void
; CHECK: }
; since if the frontend emitted code for an __autoreleasing variable, we may
; want it to be in the autorelease pool.
-; CHECK: define i8* @test11b(
+; CHECK-LABEL: define i8* @test11b(
; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK: call i8* @objc_autorelease(i8* %0) [[NUW]]
; CHECK: }
; Trivial retain,release pair with intervening call, but it's dominated
; by another retain - delete!
-; CHECK: define void @test12(
+; CHECK-LABEL: define void @test12(
; CHECK-NEXT: entry:
; CHECK-NEXT: @objc_retain(i8* %x)
; CHECK-NOT: @objc_
; Trivial retain,autorelease pair. Don't delete!
-; CHECK: define void @test13(
+; CHECK-LABEL: define void @test13(
; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK: @use_pointer(i8* %x)
; Delete the retain+release pair.
-; CHECK: define void @test13b
+; CHECK-LABEL: define void @test13b(
; CHECK-NEXT: entry:
; CHECK-NEXT: @objc_retain(i8* %x)
; CHECK-NEXT: @use_pointer
; Don't delete the retain+release pair because there's an
; autoreleasePoolPop in the way.
-; CHECK: define void @test13c
+; CHECK-LABEL: define void @test13c(
; CHECK: @objc_retain(i8* %x)
; CHECK: @objc_autoreleasePoolPop
; CHECK: @objc_retain(i8* %x)
; Like test13c, but there's an autoreleasePoolPush in the way, but that
; doesn't matter.
-; CHECK: define void @test13d
+; CHECK-LABEL: define void @test13d(
; CHECK-NEXT: entry:
; CHECK-NEXT: @objc_retain(i8* %x)
; CHECK-NEXT: @objc_autoreleasePoolPush
; Trivial retain,release pair with intervening call, but it's post-dominated
; by another release - delete!
-; CHECK: define void @test14(
+; CHECK-LABEL: define void @test14(
; CHECK-NEXT: entry:
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: @use_pointer
; Trivial retain,autorelease pair with intervening call, but it's post-dominated
; by another release. Don't delete anything.
-; CHECK: define void @test15(
+; CHECK-LABEL: define void @test15(
; CHECK-NEXT: entry:
; CHECK-NEXT: @objc_retain(i8* %x)
; CHECK-NEXT: @use_pointer
; Trivial retain,autorelease pair, post-dominated
; by another release. Delete the retain and release.
-; CHECK: define void @test15b
+; CHECK-LABEL: define void @test15b(
; CHECK-NEXT: entry:
; CHECK-NEXT: @objc_retain
; CHECK-NEXT: @objc_autorelease
ret void
}
-; CHECK: define void @test15c
+; CHECK-LABEL: define void @test15c(
; CHECK-NEXT: entry:
; CHECK-NEXT: @objc_autorelease
; CHECK-NEXT: ret void
; Retain+release pairs in diamonds, all dominated by a retain.
-; CHECK: define void @test16a(
+; CHECK-LABEL: define void @test16a(
; CHECK: @objc_retain(i8* %x)
; CHECK-NOT: @objc
; CHECK: }
ret void
}
-; CHECK: define void @test16b(
+; CHECK-LABEL: define void @test16b(
; CHECK: @objc_retain(i8* %x)
; CHECK-NOT: @objc
; CHECK: }
ret void
}
-; CHECK: define void @test16c(
+; CHECK-LABEL: define void @test16c(
; CHECK: @objc_retain(i8* %x)
; CHECK-NOT: @objc
; CHECK: }
ret void
}
-; CHECK: define void @test16d(
+; CHECK-LABEL: define void @test16d(
; CHECK: @objc_retain(i8* %x)
; CHECK-NOT: @objc
; CHECK: }
; Retain+release pairs in diamonds, all post-dominated by a release.
-; CHECK: define void @test17(
+; CHECK-LABEL: define void @test17(
; CHECK-NOT: @objc_
; CHECK: purple:
; CHECK: @objc_release
; Delete no-ops.
-; CHECK: define void @test18(
+; CHECK-LABEL: define void @test18(
; CHECK-NOT: @objc_
; CHECK: }
define void @test18() {
; Delete no-ops where undef can be assumed to be null.
-; CHECK: define void @test18b
+; CHECK-LABEL: define void @test18b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test18b() {
; Bitcast insertion
-; CHECK: define void @test20(
+; CHECK-LABEL: define void @test20(
; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) [[NUW]]
; CHECK-NEXT: invoke
; CHECK: }
; Delete a redundant retain,autorelease when forwaring a call result
; directly to a return value.
-; CHECK: define i8* @test21(
+; CHECK-LABEL: define i8* @test21(
; CHECK: call i8* @returner()
; CHECK-NEXT: ret i8* %call
; CHECK-NEXT: }
; Move an objc call up through a phi that has null operands.
-; CHECK: define void @test22(
+; CHECK-LABEL: define void @test22(
; CHECK: B:
; CHECK: %1 = bitcast double* %p to i8*
; CHECK: call void @objc_release(i8* %1)
ret void
}
-; Optimize objc_retainBlock.
-
-; CHECK: define void @test23(
-; CHECK-NOT: @objc_
-; CHECK: }
-%block0 = type { i64, i64, i8*, i8* }
-%block1 = type { i8**, i32, i32, i32 (%struct.__block_literal_1*)*, %block0* }
-%struct.__block_descriptor = type { i64, i64 }
-%struct.__block_literal_1 = type { i8**, i32, i32, i8**, %struct.__block_descriptor* }
-@__block_holder_tmp_1 = external constant %block1
-define void @test23() {
-entry:
- %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind, !clang.arc.copy_on_escape !0
- call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
- call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
- call void @objc_release(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
- ret void
-}
-
-; Don't optimize objc_retainBlock, but do strength reduce it.
-
-; CHECK: define void @test23b(i8* %p) {
-; CHECK: @objc_retain
-; CHECK: @objc_release
-; CHECK: }
-define void @test23b(i8* %p) {
-entry:
- %0 = call i8* @objc_retainBlock(i8* %p) nounwind, !clang.arc.copy_on_escape !0
- call void @callee()
- call void @use_pointer(i8* %p)
- call void @objc_release(i8* %p) nounwind
- ret void
-}
-
-; Don't optimize objc_retainBlock, because there's no copy_on_escape metadata.
-
-; CHECK: define void @test23c(
-; CHECK: @objc_retainBlock
-; CHECK: @objc_release
-; CHECK: }
-define void @test23c() {
-entry:
- %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
- call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
- call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*))
- call void @objc_release(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind
- ret void
-}
-
; Any call can decrement a retain count.
-; CHECK: define void @test24(
+; CHECK-LABEL: define void @test24(
; CHECK: @objc_retain(i8* %a)
; CHECK: @objc_release
; CHECK: }
; Don't move a retain/release pair if the release can be moved
; but the retain can't be moved to balance it.
-; CHECK: define void @test25(
+; CHECK-LABEL: define void @test25(
; CHECK: entry:
; CHECK: call i8* @objc_retain(i8* %p)
; CHECK: true:
; Don't move a retain/release pair if the retain can be moved
; but the release can't be moved to balance it.
-; CHECK: define void @test26(
+; CHECK-LABEL: define void @test26(
; CHECK: entry:
; CHECK: call i8* @objc_retain(i8* %p)
; CHECK: true:
; Don't sink the retain,release into the loop.
-; CHECK: define void @test27(
+; CHECK-LABEL: define void @test27(
; CHECK: entry:
; CHECK: call i8* @objc_retain(i8* %p)
; CHECK: loop:
; Trivial code motion case: Triangle.
-; CHECK: define void @test28(
+; CHECK-LABEL: define void @test28(
; CHECK-NOT: @objc_
; CHECK: true:
; CHECK: call i8* @objc_retain(
; Trivial code motion case: Triangle, but no metadata. Don't move past
; unrelated memory references!
-; CHECK: define void @test28b
+; CHECK-LABEL: define void @test28b(
; CHECK: call i8* @objc_retain(
; CHECK: true:
; CHECK-NOT: @objc_
; Trivial code motion case: Triangle, with metadata. Do move past
; unrelated memory references! And preserve the metadata.
-; CHECK: define void @test28c
+; CHECK-LABEL: define void @test28c(
; CHECK-NOT: @objc_
; CHECK: true:
; CHECK: call i8* @objc_retain(
; Like test28. but with two releases.
-; CHECK: define void @test29(
+; CHECK-LABEL: define void @test29(
; CHECK-NOT: @objc_
; CHECK: true:
; CHECK: call i8* @objc_retain(
; Basic case with the use and call in a diamond
; with an extra release.
-; CHECK: define void @test30(
+; CHECK-LABEL: define void @test30(
; CHECK-NOT: @objc_
; CHECK: true:
; CHECK: call i8* @objc_retain(
; Basic case with a mergeable release.
-; CHECK: define void @test31(
+; CHECK-LABEL: define void @test31(
; CHECK: call i8* @objc_retain(i8* %p)
; CHECK: call void @callee()
; CHECK: store
; Don't consider bitcasts or getelementptrs direct uses.
-; CHECK: define void @test32(
+; CHECK-LABEL: define void @test32(
; CHECK-NOT: @objc_
; CHECK: true:
; CHECK: call i8* @objc_retain(
; Do consider icmps to be direct uses.
-; CHECK: define void @test33(
+; CHECK-LABEL: define void @test33(
; CHECK-NOT: @objc_
; CHECK: true:
; CHECK: call i8* @objc_retain(
; Delete retain,release if there's just a possible dec and we have imprecise
; releases.
-; CHECK: define void @test34a(
+; CHECK-LABEL: define void @test34a(
; CHECK: call i8* @objc_retain
; CHECK: true:
; CHECK: done:
ret void
}
-; CHECK: define void @test34b(
+; CHECK-LABEL: define void @test34b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test34b(i8* %p, i1 %x, i8* %y) {
; release.
; Precise.
-; CHECK: define void @test35a(
+; CHECK-LABEL: define void @test35a(
; CHECK: entry:
; CHECK: call i8* @objc_retain
; CHECK: true:
}
; Imprecise.
-; CHECK: define void @test35b(
+; CHECK-LABEL: define void @test35b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test35b(i8* %p, i1 %x, i8* %y) {
; Delete a retain,release if there's no actual use and we have precise release.
-; CHECK: define void @test36a(
+; CHECK-LABEL: define void @test36a(
; CHECK: @objc_retain
; CHECK: call void @callee()
; CHECK-NOT: @objc_
; Like test36, but with metadata.
-; CHECK: define void @test36b(
+; CHECK-LABEL: define void @test36b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test36b(i8* %p) {
; Be aggressive about analyzing phis to eliminate possible uses.
-; CHECK: define void @test38(
+; CHECK-LABEL: define void @test38(
; CHECK-NOT: @objc_
; CHECK: }
define void @test38(i8* %p, i1 %u, i1 %m, i8* %z, i8* %y, i8* %x, i8* %w) {
; Delete retain,release pairs around loops.
-; CHECK: define void @test39(
+; CHECK-LABEL: define void @test39(
; CHECK-NOT: @objc_
; CHECK: }
define void @test39(i8* %p) {
; Delete retain,release pairs around loops containing uses.
-; CHECK: define void @test39b(
+; CHECK-LABEL: define void @test39b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test39b(i8* %p) {
; Delete retain,release pairs around loops containing potential decrements.
-; CHECK: define void @test39c(
+; CHECK-LABEL: define void @test39c(
; CHECK-NOT: @objc_
; CHECK: }
define void @test39c(i8* %p) {
; Delete retain,release pairs around loops even if
; the successors are in a different order.
-; CHECK: define void @test40(
+; CHECK-LABEL: define void @test40(
; CHECK-NOT: @objc_
; CHECK: }
define void @test40(i8* %p) {
; Do the known-incremented retain+release elimination even if the pointer
; is also autoreleased.
-; CHECK: define void @test42(
+; CHECK-LABEL: define void @test42(
; CHECK-NEXT: entry:
; CHECK-NEXT: call i8* @objc_retain(i8* %p)
; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
; Don't the known-incremented retain+release elimination if the pointer is
; autoreleased and there's an autoreleasePoolPop.
-; CHECK: define void @test43(
+; CHECK-LABEL: define void @test43(
; CHECK-NEXT: entry:
; CHECK-NEXT: call i8* @objc_retain(i8* %p)
; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
; Do the known-incremented retain+release elimination if the pointer is
; autoreleased and there's an autoreleasePoolPush.
-; CHECK: define void @test43b
+; CHECK-LABEL: define void @test43b(
; CHECK-NEXT: entry:
; CHECK-NEXT: call i8* @objc_retain(i8* %p)
; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
; Do retain+release elimination for non-provenance pointers.
-; CHECK: define void @test44(
+; CHECK-LABEL: define void @test44(
; CHECK-NOT: objc_
; CHECK: }
define void @test44(i8** %pp) {
; Don't delete retain+release with an unknown-provenance
; may-alias objc_release between them.
-; CHECK: define void @test45(
+; CHECK-LABEL: define void @test45(
; CHECK: call i8* @objc_retain(i8* %p)
; CHECK: call void @objc_release(i8* %q)
; CHECK: call void @use_pointer(i8* %p)
; Don't delete retain and autorelease here.
-; CHECK: define void @test46(
+; CHECK-LABEL: define void @test46(
; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]]
; CHECK: true:
; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]]
; Delete no-op cast calls.
-; CHECK: define i8* @test47(
+; CHECK-LABEL: define i8* @test47(
; CHECK-NOT: call
; CHECK: ret i8* %p
; CHECK: }
; Delete no-op cast calls.
-; CHECK: define i8* @test48(
+; CHECK-LABEL: define i8* @test48(
; CHECK-NOT: call
; CHECK: ret i8* %p
; CHECK: }
; Delete no-op cast calls.
-; CHECK: define i8* @test49(
+; CHECK-LABEL: define i8* @test49(
; CHECK-NOT: call
; CHECK: ret i8* %p
; CHECK: }
; Do delete retain+release with intervening stores of the address value if we
; have imprecise release attached to objc_release.
-; CHECK: define void @test50a(
+; CHECK-LABEL: define void @test50a(
; CHECK-NEXT: call i8* @objc_retain
; CHECK-NEXT: call void @callee
; CHECK-NEXT: store
ret void
}
-; CHECK: define void @test50b(
+; CHECK-LABEL: define void @test50b(
; CHECK-NOT: @objc_
; CHECK: }
define void @test50b(i8* %p, i8** %pp) {
; Don't delete retain+release with intervening stores through the
; address value.
-; CHECK: define void @test51a(
+; CHECK-LABEL: define void @test51a(
; CHECK: call i8* @objc_retain(i8* %p)
; CHECK: call void @objc_release(i8* %p)
; CHECK: ret void
ret void
}
-; CHECK: define void @test51b(
+; CHECK-LABEL: define void @test51b(
; CHECK: call i8* @objc_retain(i8* %p)
; CHECK: call void @objc_release(i8* %p)
; CHECK: ret void
; Don't delete retain+release with intervening use of a pointer of
; unknown provenance.
-; CHECK: define void @test52a(
+; CHECK-LABEL: define void @test52a(
; CHECK: call i8* @objc_retain
; CHECK: call void @callee()
; CHECK: call void @use_pointer(i8* %z)
ret void
}
-; CHECK: define void @test52b(
+; CHECK-LABEL: define void @test52b(
; CHECK: call i8* @objc_retain
; CHECK: call void @callee()
; CHECK: call void @use_pointer(i8* %z)
; Oops. That's wrong. Clang sometimes uses function types gratuitously.
; See rdar://10551239.
-; CHECK: define void @test53(
+; CHECK-LABEL: define void @test53(
; CHECK: @objc_
; CHECK: }
define void @test53(void ()** %zz, i8** %pp) {
; Convert autorelease to release if the value is unused.
-; CHECK: define void @test54(
+; CHECK-LABEL: define void @test54(
; CHECK: call i8* @returner()
-; CHECK-NEXT: call void @objc_release(i8* %t) [[NUW]], !clang.imprecise_release !0
+; CHECK-NEXT: call void @objc_release(i8* %t) [[NUW]], !clang.imprecise_release ![[RELEASE]]
; CHECK-NEXT: ret void
; CHECK: }
define void @test54() {
; Nested retain+release pairs. Delete them both.
-; CHECK: define void @test55(
+; CHECK-LABEL: define void @test55(
; CHECK-NOT: @objc
; CHECK: }
define void @test55(i8* %x) {
; can be partially eliminated. Plus an extra outer pair to
; eliminate, for fun.
-; CHECK: define void @test56(
+; CHECK-LABEL: define void @test56(
; CHECK-NOT: @objc
; CHECK: if.then:
; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK-NEXT: tail call void @use_pointer(i8* %x)
; CHECK-NEXT: tail call void @use_pointer(i8* %x)
-; CHECK-NEXT: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release !0
+; CHECK-NEXT: tail call void @objc_release(i8* %x) [[NUW]], !clang.imprecise_release ![[RELEASE]]
; CHECK-NEXT: br label %if.end
; CHECK-NOT: @objc
; CHECK: }
; known unnecessary because the presence of the second one means that
; the first one won't be deleting the object.
-; CHECK: define void @test57(
+; CHECK-LABEL: define void @test57(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @use_pointer(i8* %x)
; CHECK-NEXT: call void @use_pointer(i8* %x)
; An adjacent retain+release pair is sufficient even if it will be
; removed itself.
-; CHECK: define void @test58(
+; CHECK-LABEL: define void @test58(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @use_pointer(i8* %x)
; CHECK-NEXT: call void @use_pointer(i8* %x)
; Don't delete the second retain+release pair in an adjacent set.
-; CHECK: define void @test59(
+; CHECK-LABEL: define void @test59(
; CHECK-NEXT: entry:
; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK-NEXT: call void @use_pointer(i8* %x)
; We have a precise lifetime retain/release here. We can not remove them since
; @something is not constant.
-; CHECK: define void @test60a(
+; CHECK-LABEL: define void @test60a(
; CHECK: call i8* @objc_retain
; CHECK: call void @objc_release
; CHECK: }
ret void
}
-; CHECK: define void @test60b(
+; CHECK-LABEL: define void @test60b(
; CHECK: call i8* @objc_retain
; CHECK-NOT: call i8* @objc_retain
; CHECK-NOT: call i8* @objc_rrelease
ret void
}
-; CHECK: define void @test60c(
+; CHECK-LABEL: define void @test60c(
; CHECK-NOT: @objc_
; CHECK: }
define void @test60c() {
ret void
}
-; CHECK: define void @test60d(
+; CHECK-LABEL: define void @test60d(
; CHECK-NOT: @objc_
; CHECK: }
define void @test60d() {
ret void
}
-; CHECK: define void @test60e(
+; CHECK-LABEL: define void @test60e(
; CHECK-NOT: @objc_
; CHECK: }
define void @test60e() {
; Constant pointers to objects don't need to be considered related to other
; pointers.
-; CHECK: define void @test61(
+; CHECK-LABEL: define void @test61(
; CHECK-NOT: @objc_
; CHECK: }
define void @test61() {
; Delete a retain matched by releases when one is inside the loop and the
; other is outside the loop.
-; CHECK: define void @test62(
+; CHECK-LABEL: define void @test62(
; CHECK-NOT: @objc_
; CHECK: }
define void @test62(i8* %x, i1* %p) nounwind {
; Like test62 but with no release in exit.
; Don't delete anything!
-; CHECK: define void @test63(
+; CHECK-LABEL: define void @test63(
; CHECK: loop:
; CHECK: tail call i8* @objc_retain(i8* %x)
; CHECK: loop.more:
; Like test62 but with no release in loop.more.
; Don't delete anything!
-; CHECK: define void @test64(
+; CHECK-LABEL: define void @test64(
; CHECK: loop:
; CHECK: tail call i8* @objc_retain(i8* %x)
; CHECK: exit:
; Move an autorelease past a phi with a null.
-; CHECK: define i8* @test65(
+; CHECK-LABEL: define i8* @test65(
; CHECK: if.then:
; CHECK: call i8* @objc_autorelease(
; CHECK: return:
; Don't move an autorelease past an autorelease pool boundary.
-; CHECK: define i8* @test65b(
+; CHECK-LABEL: define i8* @test65b(
; CHECK: if.then:
; CHECK-NOT: @objc_autorelease
; CHECK: return:
; Don't move an autoreleaseReuturnValue, which would break
; the RV optimization.
-; CHECK: define i8* @test65c(
+; CHECK-LABEL: define i8* @test65c(
; CHECK: if.then:
; CHECK-NOT: @objc_autorelease
; CHECK: return:
; An objc_retain can serve as a may-use for a different pointer.
; rdar://11931823
-; CHECK: define void @test66a(
+; CHECK-LABEL: define void @test66a(
; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
ret void
}
-; CHECK: define void @test66b(
+; CHECK-LABEL: define void @test66b(
; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
ret void
}
-; CHECK: define void @test66c(
+; CHECK-LABEL: define void @test66c(
; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
ret void
}
-; CHECK: define void @test66d(
+; CHECK-LABEL: define void @test66d(
; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
invoke.cont:
%0 = bitcast {}* %self to i8*
%1 = tail call i8* @objc_retain(i8* %0) nounwind
- tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0)
- tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0)
+ tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0, metadata !{})
+ tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0, metadata !{})
%ivar = load i64* @"OBJC_IVAR_$_A.myZ", align 8
%add.ptr = getelementptr i8* %0, i64 %ivar
%tmp1 = bitcast i8* %add.ptr to float*
; Make sure that we understand that objc_sync_{enter,exit} are IC_User not
; IC_Call/IC_CallOrUser.
-; CHECK: define void @test67
+; CHECK-LABEL: define void @test67(
; CHECK-NEXT: call i32 @objc_sync_enter(i8* %x)
; CHECK-NEXT: call i32 @objc_sync_exit(i8* %x)
; CHECK-NEXT: ret void
ret void
}
+!llvm.module.flags = !{!1}
+
!0 = metadata !{}
+!1 = metadata !{i32 1, metadata !"Debug Info Version", i32 2}
; CHECK: attributes #0 = { nounwind readnone }
; CHECK: attributes [[NUW]] = { nounwind }
+; CHECK: ![[RELEASE]] = metadata !{}