1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -objc-arc -objc-arc-contract < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 4*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedObject(i8*) 5*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainAutoreleasedReturnValue(i8*) 6*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleaseReturnValue(i8*) 7*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_msgSend(i8*, i8*, ...) 8*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*) 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker; Test that the optimizer can create an objc_retainAutoreleaseReturnValue 11*9880d681SAndroid Build Coastguard Worker; declaration even if no objc_retain declaration exists. 12*9880d681SAndroid Build Coastguard Worker; rdar://9401303 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test0(i8* %p) { 15*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry: 16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %p) [[NUW:#[0-9]+]] 17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %0 18*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: } 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerdefine i8* @test0(i8* %p) { 21*9880d681SAndroid Build Coastguard Workerentry: 22*9880d681SAndroid Build Coastguard Worker %call = tail call i8* @objc_unretainedObject(i8* %p) 23*9880d681SAndroid Build Coastguard Worker %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind 24*9880d681SAndroid Build Coastguard Worker %1 = tail call i8* @objc_autoreleaseReturnValue(i8* %call) nounwind 25*9880d681SAndroid Build Coastguard Worker ret i8* %call 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; Properly create the @objc_retain declaration when it doesn't already exist. 29*9880d681SAndroid Build Coastguard Worker; rdar://9825114 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 32*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain( 33*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retainAutoreleasedReturnValue( 34*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release( 35*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release( 36*9880d681SAndroid Build Coastguard Worker; CHECK: } 37*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8* %call88) nounwind personality i32 (...)* @__gxx_personality_v0 { 38*9880d681SAndroid Build Coastguard Workerentry: 39*9880d681SAndroid Build Coastguard Worker %tmp1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call88) nounwind 40*9880d681SAndroid Build Coastguard Worker %call94 = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*)*)(i8* %tmp1) 41*9880d681SAndroid Build Coastguard Worker to label %invoke.cont93 unwind label %lpad91 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workerinvoke.cont93: ; preds = %entry 44*9880d681SAndroid Build Coastguard Worker %tmp2 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call94) nounwind 45*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp1) nounwind 46*9880d681SAndroid Build Coastguard Worker invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %tmp2) 47*9880d681SAndroid Build Coastguard Worker to label %invoke.cont102 unwind label %lpad100 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerinvoke.cont102: ; preds = %invoke.cont93 50*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0 51*9880d681SAndroid Build Coastguard Worker unreachable 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Workerlpad91: ; preds = %entry 54*9880d681SAndroid Build Coastguard Worker %exn91 = landingpad {i8*, i32} 55*9880d681SAndroid Build Coastguard Worker cleanup 56*9880d681SAndroid Build Coastguard Worker unreachable 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workerlpad100: ; preds = %invoke.cont93 59*9880d681SAndroid Build Coastguard Worker %exn100 = landingpad {i8*, i32} 60*9880d681SAndroid Build Coastguard Worker cleanup 61*9880d681SAndroid Build Coastguard Worker call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0 62*9880d681SAndroid Build Coastguard Worker unreachable 63*9880d681SAndroid Build Coastguard Worker} 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_v0(...) 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker!0 = !{} 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; CHECK: attributes [[NUW]] = { nounwind } 70