1; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s 2 3; CHECK-LABEL: define void @test0() { 4; CHECK: %[[CALL:.*]] = notail call ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 5; CHECK-NOT: call ptr @llvm.objc.retainAutoreleasedReturnValue( 6 7define void @test0() { 8 %call1 = call ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 9 ret void 10} 11 12; CHECK-LABEL: define void @test1() { 13; CHECK: %[[CALL:.*]] = notail call ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 14; CHECK-NOT: call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue( 15 16define void @test1() { 17 %call1 = call ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] 18 ret void 19} 20 21; CHECK-LABEL:define ptr @test2( 22; CHECK: %[[V0:.*]] = invoke ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 23 24; CHECK-NOT: = call ptr @llvm.objc.retainAutoreleasedReturnValue( 25; CHECK: br 26 27; CHECK: %[[V2:.*]] = invoke ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 28 29; CHECK-NOT: = call ptr @llvm.objc.retainAutoreleasedReturnValue( 30; CHECK: br 31 32; CHECK: %[[RETVAL:.*]] = phi ptr [ %[[V0]], {{.*}} ], [ %[[V2]], {{.*}} ] 33; CHECK: ret ptr %[[RETVAL]] 34 35define ptr @test2(i1 zeroext %b) personality ptr @__gxx_personality_v0 { 36entry: 37 br i1 %b, label %if.then, label %if.end 38 39if.then: 40 %call1 = invoke ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 41 to label %cleanup unwind label %lpad 42 43lpad: 44 %0 = landingpad { ptr, i32 } 45 cleanup 46 resume { ptr, i32 } undef 47 48if.end: 49 %call3 = invoke ptr @foo() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 50 to label %cleanup unwind label %lpad 51 52cleanup: 53 %retval.0 = phi ptr [ %call1, %if.then ], [ %call3, %if.end ] 54 ret ptr %retval.0 55} 56 57; "clang.arc.attachedcall" is ignored if the return type of the called function is void. 58; CHECK-LABEL: define void @test3( 59; CHECK: call void @foo2() #[[ATTR1:.*]] [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 60; CHECK-NEXT: ret void 61 62define void @test3() { 63 call void @foo2() #0 [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] 64 ret void 65} 66 67declare ptr @foo() 68declare void @foo2() 69declare i32 @__gxx_personality_v0(...) 70declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr) 71declare ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr) 72 73!llvm.module.flags = !{!0} 74 75; CHECK: attributes #[[ATTR1]] = { noreturn } 76attributes #0 = { noreturn } 77 78!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09fp, fp\09\09// marker for objc_retainAutoreleaseReturnValue"} 79