Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -319,6 +319,50 @@ [llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty], [IntrArgMemOnly, NoCapture<1>, NoCapture<2>]>; +//===------------------- ObjC ARC runtime Intrinsics --------------------===// +// +// Note these are to support the Objective-C ARC optimizer which wants to +// eliminate retain and releases where possible. + +def int_objc_autorelease : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty]>; +def int_objc_autoreleasePoolPop : Intrinsic<[], [llvm_ptr_ty]>; +def int_objc_autoreleasePoolPush : Intrinsic<[llvm_ptr_ty], []>; +def int_objc_autoreleaseReturnValue : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty]>; +def int_objc_copyWeak : Intrinsic<[], + [llvm_ptrptr_ty, + llvm_ptrptr_ty]>; +def int_objc_destroyWeak : Intrinsic<[], [llvm_ptrptr_ty]>; +def int_objc_initWeak : Intrinsic<[llvm_ptr_ty], + [llvm_ptrptr_ty, + llvm_ptr_ty]>; +def int_objc_loadWeak : Intrinsic<[llvm_ptr_ty], + [llvm_ptrptr_ty]>; +def int_objc_loadWeakRetained : Intrinsic<[llvm_ptr_ty], + [llvm_ptrptr_ty]>; +def int_objc_moveWeak : Intrinsic<[], + [llvm_ptrptr_ty, + llvm_ptrptr_ty]>; +def int_objc_release : Intrinsic<[], [llvm_ptr_ty]>; +def int_objc_retain : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty]>; +def int_objc_retainAutorelease : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty]>; +def int_objc_retainAutoreleaseReturnValue : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty]>; +def int_objc_retainAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty]>; +def int_objc_retainBlock : Intrinsic<[llvm_ptr_ty], + [llvm_ptr_ty]>; +def int_objc_storeStrong : Intrinsic<[llvm_ptr_ty], + [llvm_ptrptr_ty, + llvm_ptr_ty]>; +def int_objc_storeWeak : Intrinsic<[llvm_ptr_ty], + [llvm_ptrptr_ty, + llvm_ptr_ty]>; + + //===--------------------- Code Generator Intrinsics ----------------------===// // def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>; Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6337,6 +6337,42 @@ // MachineFunction in SelectionDAGISel::PrepareEHLandingPad. We can safely // delete it now. return nullptr; + case Intrinsic::objc_autorelease: + return "objc_autorelease"; + case Intrinsic::objc_autoreleasePoolPop: + return "objc_autoreleasePoolPop"; + case Intrinsic::objc_autoreleasePoolPush: + return "objc_autoreleasePoolPush"; + case Intrinsic::objc_autoreleaseReturnValue: + return "objc_autoreleaseReturnValue"; + case Intrinsic::objc_copyWeak: + return "objc_copyWeak"; + case Intrinsic::objc_destroyWeak: + return "objc_destroyWeak"; + case Intrinsic::objc_initWeak: + return "objc_initWeak"; + case Intrinsic::objc_loadWeak: + return "objc_loadWeak"; + case Intrinsic::objc_loadWeakRetained: + return "objc_loadWeakRetained"; + case Intrinsic::objc_moveWeak: + return "objc_moveWeak"; + case Intrinsic::objc_release: + return "objc_release"; + case Intrinsic::objc_retain: + return "objc_retain"; + case Intrinsic::objc_retainAutorelease: + return "objc_retainAutorelease"; + case Intrinsic::objc_retainAutoreleaseReturnValue: + return "objc_retainAutoreleaseReturnValue"; + case Intrinsic::objc_retainAutoreleasedReturnValue: + return "objc_retainAutoreleasedReturnValue"; + case Intrinsic::objc_retainBlock: + return "objc_retainBlock"; + case Intrinsic::objc_storeStrong: + return "objc_storeStrong"; + case Intrinsic::objc_storeWeak: + return "objc_storeWeak"; } } Index: test/CodeGen/X86/objc-arc.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/objc-arc.ll @@ -0,0 +1,167 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s + +; Make sure calls to the objc intrinsics are translated to calls in to the +; runtime + +define i8* @test_objc_autorelease(i8* %arg0) { +; CHECK-LABEL: test_objc_autorelease +; CHECK: callq _objc_autorelease +entry: + %0 = call i8* @llvm.objc.autorelease(i8* %arg0) + ret i8* %0 +} + +define void @test_objc_autoreleasePoolPop(i8* %arg0) { +; CHECK-LABEL: test_objc_autoreleasePoolPop +; CHECK: callq _objc_autoreleasePoolPop +entry: + call void @llvm.objc.autoreleasePoolPop(i8* %arg0) + ret void +} + +define i8* @test_objc_autoreleasePoolPush() { +; CHECK-LABEL: test_objc_autoreleasePoolPush +; CHECK: callq _objc_autoreleasePoolPush +entry: + %0 = call i8* @llvm.objc.autoreleasePoolPush() + ret i8* %0 +} + +define i8* @test_objc_autoreleaseReturnValue(i8* %arg0) { +; CHECK-LABEL: test_objc_autoreleaseReturnValue +; CHECK: callq _objc_autoreleaseReturnValue +entry: + %0 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %arg0) + ret i8* %0 +} + +define void @test_objc_copyWeak(i8** %arg0, i8** %arg1) { +; CHECK-LABEL: test_objc_copyWeak +; CHECK: callq _objc_copyWeak +entry: + call void @llvm.objc.copyWeak(i8** %arg0, i8** %arg1) + ret void +} + +define void @test_objc_destroyWeak(i8** %arg0) { +; CHECK-LABEL: test_objc_destroyWeak +; CHECK: callq _objc_destroyWeak +entry: + call void @llvm.objc.destroyWeak(i8** %arg0) + ret void +} + +define i8* @test_objc_initWeak(i8** %arg0, i8* %arg1) { +; CHECK-LABEL: test_objc_initWeak +; CHECK: callq _objc_initWeak +entry: + %0 = call i8* @llvm.objc.initWeak(i8** %arg0, i8* %arg1) + ret i8* %0 +} + +define i8* @test_objc_loadWeak(i8** %arg0) { +; CHECK-LABEL: test_objc_loadWeak +; CHECK: callq _objc_loadWeak +entry: + %0 = call i8* @llvm.objc.loadWeak(i8** %arg0) + ret i8* %0 +} + +define i8* @test_objc_loadWeakRetained(i8** %arg0) { +; CHECK-LABEL: test_objc_loadWeakRetained +; CHECK: callq _objc_loadWeakRetained +entry: + %0 = call i8* @llvm.objc.loadWeakRetained(i8** %arg0) + ret i8* %0 +} + +define void @test_objc_moveWeak(i8** %arg0, i8** %arg1) { +; CHECK-LABEL: test_objc_moveWeak +; CHECK: callq _objc_moveWeak +entry: + call void @llvm.objc.moveWeak(i8** %arg0, i8** %arg1) + ret void +} + +define void @test_objc_release(i8* %arg0) { +; CHECK-LABEL: test_objc_release +; CHECK: callq _objc_release +entry: + call void @llvm.objc.release(i8* %arg0) + ret void +} + +define i8* @test_objc_retain(i8* %arg0) { +; CHECK-LABEL: test_objc_retain +; CHECK: callq _objc_retain +entry: + %0 = call i8* @llvm.objc.retain(i8* %arg0) + ret i8* %0 +} + +define i8* @test_objc_retainAutorelease(i8* %arg0) { +; CHECK-LABEL: test_objc_retainAutorelease +; CHECK: callq _objc_retainAutorelease +entry: + %0 = call i8* @llvm.objc.retainAutorelease(i8* %arg0) + ret i8* %0 +} + +define i8* @test_objc_retainAutoreleaseReturnValue(i8* %arg0) { +; CHECK-LABEL: test_objc_retainAutoreleaseReturnValue +; CHECK: callq _objc_retainAutoreleaseReturnValue +entry: + %0 = call i8* @llvm.objc.retainAutoreleaseReturnValue(i8* %arg0) + ret i8* %0 +} + +define i8* @test_objc_retainAutoreleasedReturnValue(i8* %arg0) { +; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue +; CHECK: callq _objc_retainAutoreleasedReturnValue +entry: + %0 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %arg0) + ret i8* %0 +} + +define i8* @test_objc_retainBlock(i8* %arg0) { +; CHECK-LABEL: test_objc_retainBlock +; CHECK: callq _objc_retainBlock +entry: + %0 = call i8* @llvm.objc.retainBlock(i8* %arg0) + ret i8* %0 +} + +define i8* @test_objc_storeStrong(i8** %arg0, i8* %arg1) { +; CHECK-LABEL: test_objc_storeStrong +; CHECK: callq _objc_storeStrong +entry: + %0 = call i8* @llvm.objc.storeStrong(i8** %arg0, i8* %arg1) + ret i8* %0 +} + +define i8* @test_objc_storeWeak(i8** %arg0, i8* %arg1) { +; CHECK-LABEL: test_objc_storeWeak +; CHECK: callq _objc_storeWeak +entry: + %0 = call i8* @llvm.objc.storeWeak(i8** %arg0, i8* %arg1) + ret i8* %0 +} + +declare i8* @llvm.objc.autorelease(i8*) +declare void @llvm.objc.autoreleasePoolPop(i8*) +declare i8* @llvm.objc.autoreleasePoolPush() +declare i8* @llvm.objc.autoreleaseReturnValue(i8*) +declare void @llvm.objc.copyWeak(i8**, i8**) +declare void @llvm.objc.destroyWeak(i8**) +declare i8* @llvm.objc.initWeak(i8**, i8*) +declare i8* @llvm.objc.loadWeak(i8**) +declare i8* @llvm.objc.loadWeakRetained(i8**) +declare void @llvm.objc.moveWeak(i8**, i8**) +declare void @llvm.objc.release(i8*) +declare i8* @llvm.objc.retain(i8*) +declare i8* @llvm.objc.retainAutorelease(i8*) +declare i8* @llvm.objc.retainAutoreleaseReturnValue(i8*) +declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*) +declare i8* @llvm.objc.retainBlock(i8*) +declare i8* @llvm.objc.storeStrong(i8**, i8*) +declare i8* @llvm.objc.storeWeak(i8**, i8*)