; Simple retain+release pair deletion, with some intervening control
; flow and harmless instructions.
-; CHECK: define void @test0_precise(
+; CHECK: define void @test0_precise(i32* %x, i1 %p) [[NUW:#[0-9]+]] {
; CHECK: @objc_retain
; CHECK: @objc_release
; CHECK: }
ret void
}
-; CHECK: define void @test0_imprecise(
+; CHECK: define void @test0_imprecise(i32* %x, i1 %p) [[NUW]] {
; CHECK-NOT: @objc_
; CHECK: }
define void @test0_imprecise(i32* %x, i1 %p) nounwind {
; TODO: Make the objc_release's argument be %0.
-; CHECK: define void @test1_precise(
+; CHECK: define void @test1_precise(i32* %x, i1 %p, i1 %q) [[NUW]] {
; CHECK: @objc_retain(i8* %a)
; CHECK: @objc_release
; CHECK: }
ret void
}
-; CHECK: define void @test1_imprecise(
+; CHECK: define void @test1_imprecise(i32* %x, i1 %p, i1 %q) [[NUW]] {
; CHECK: @objc_retain(i8* %a)
; CHECK: @objc_release
; CHECK: }
; Don't do partial elimination into two different CFG diamonds.
-; CHECK: define void @test1b_precise(
+; CHECK: define void @test1b_precise(i8* %x, i1 %p, i1 %q) {
; CHECK: entry:
-; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW:#[0-9]+]]
+; CHECK: tail call i8* @objc_retain(i8* %x) [[NUW]]
; CHECK-NOT: @objc_
; CHECK: if.end5:
; CHECK: tail call void @objc_release(i8* %x) [[NUW]]
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: ret void
+; CHECK-NEXT: }
define void @test13b(i8* %x, i64 %n) {
entry:
call i8* @objc_retain(i8* %x) nounwind
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: @use_pointer
; CHECK-NEXT: ret void
+; CHECK-NEXT: }
define void @test13d(i8* %x, i64 %n) {
entry:
call i8* @objc_retain(i8* %x) nounwind
; CHECK: define void @test20(
; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) [[NUW]]
; CHECK-NEXT: invoke
+; CHECK: }
define void @test20(double* %self) {
if.then12:
%tmp = bitcast double* %self to i8*
; CHECK: define i8* @test21(
; CHECK: call i8* @returner()
; CHECK-NEXT: ret i8* %call
+; CHECK-NEXT: }
define i8* @test21() {
entry:
%call = call i8* @returner()
; Don't optimize objc_retainBlock, but do strength reduce it.
-; CHECK: define void @test23b
+; CHECK: define void @test23b(i8* %p) {
; CHECK: @objc_retain
; CHECK: @objc_release
; CHECK: }
; CHECK: call void @objc_release(i8* %q)
; CHECK: call void @use_pointer(i8* %p)
; CHECK: call void @objc_release(i8* %p)
+; CHECK: }
define void @test45(i8** %pp, i8** %qq) {
%p = load i8** %pp
%q = load i8** %qq
; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]]
; CHECK: true:
; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]]
+; CHECK: }
define void @test46(i8* %p, i1 %a) {
entry:
call i8* @objc_retain(i8* %p)
; CHECK: define i8* @test47(
; CHECK-NOT: call
; CHECK: ret i8* %p
+; CHECK: }
define i8* @test47(i8* %p) nounwind {
%x = call i8* @objc_retainedObject(i8* %p)
ret i8* %x
; CHECK: define i8* @test48(
; CHECK-NOT: call
; CHECK: ret i8* %p
+; CHECK: }
define i8* @test48(i8* %p) nounwind {
%x = call i8* @objc_unretainedObject(i8* %p)
ret i8* %x
; CHECK: define i8* @test49(
; CHECK-NOT: call
; CHECK: ret i8* %p
+; CHECK: }
define i8* @test49(i8* %p) nounwind {
%x = call i8* @objc_unretainedPointer(i8* %p)
ret i8* %x
; CHECK: call i8* @returner()
; CHECK-NEXT: call void @objc_release(i8* %t) [[NUW]], !clang.imprecise_release !0
; CHECK-NEXT: ret void
+; CHECK: }
define void @test54() {
%t = call i8* @returner()
call i8* @objc_autorelease(i8* %t)
declare i32 @puts(i8* nocapture) nounwind
@str = internal constant [16 x i8] c"-[ Top0 _getX ]\00"
-; CHECK: @"\01-[A z]"
+; CHECK: define { <2 x float>, <2 x float> } @"\01-[A z]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
; CHECK-NOT: @objc_
; CHECK: }
ret {<2 x float>, <2 x float>} %tmp35
}
-; CHECK: @"\01-[Top0 _getX]"
+; CHECK: @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) [[NUW]] {
; CHECK-NOT: @objc_
; CHECK: }
; A simple loop. Eliminate the retain and release inside of it!
-; CHECK: define void @loop
+; CHECK: define void @loop(i8* %x, i64 %n) {
; CHECK: for.body:
; CHECK-NOT: @objc_
; CHECK: @objc_msgSend
; CHECK-NOT: @objc_
; CHECK: for.end:
+; CHECK: }
define void @loop(i8* %x, i64 %n) {
entry:
%0 = tail call i8* @objc_retain(i8* %x) nounwind
; ObjCARCOpt can delete the retain,release on self.
-; CHECK: define void @TextEditTest
+; CHECK: define void @TextEditTest(%2* %self, %3* %pboard) {
; CHECK-NOT: call i8* @objc_retain(i8* %tmp7)
; CHECK: }
; CHECK: entry:
; CHECK-NEXT: tail call void @objc_storeStrong(i8** @x, i8* %p) [[NUW:#[0-9]+]]
; CHECK-NEXT: ret void
+; CHECK-NEXT: }
define void @test0(i8* %p) {
entry:
%0 = tail call i8* @objc_retain(i8* %p) nounwind
; CHECK: define i1 @test5(i8* %newValue, i8* %foo) {
; CHECK: %t = icmp eq i8* %x1, %foo
; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) [[NUW]]
+; CHECK: }
define i1 @test5(i8* %newValue, i8* %foo) {
entry:
%x0 = tail call i8* @objc_retain(i8* %newValue) nounwind
; CHECK: define i1 @test6(i8* %newValue, i8* %foo) {
; CHECK: %t = icmp eq i8* %x1, %foo
; CHECK: tail call void @objc_storeStrong(i8** @x, i8* %newValue) [[NUW]]
+; CHECK: }
define i1 @test6(i8* %newValue, i8* %foo) {
entry:
%x0 = tail call i8* @objc_retain(i8* %newValue) nounwind