diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 10aad2e26938d..93d78783cbea6 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -2415,9 +2415,7 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value, emitAutoreleasedReturnValueMarker(CGF); // Add operand bundle "clang.arc.attachedcall" to the call instead of emitting - // retainRV or claimRV calls in the IR. We currently do this only when the - // optimization level isn't -O0 since global-isel, which is currently run at - // -O0, doesn't know about the operand bundle. + // retainRV or claimRV calls in the IR. ObjCEntrypoints &EPs = CGF.CGM.getObjCEntrypoints(); llvm::Function *&EP = IsRetainRV ? EPs.objc_retainAutoreleasedReturnValue @@ -2429,11 +2427,9 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value, llvm::Triple::ArchType Arch = CGF.CGM.getTriple().getArch(); - // FIXME: Do this on all targets and at -O0 too. This can be enabled only if - // the target backend knows how to handle the operand bundle. - if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && - (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 || - Arch == llvm::Triple::x86_64)) { + if ((CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && + Arch == llvm::Triple::x86_64) || + Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32) { llvm::Value *bundleArgs[] = {EP}; llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs); auto *oldCall = cast(value); diff --git a/clang/test/CodeGenObjC/arc-arm.m b/clang/test/CodeGenObjC/arc-arm.m index 6105644c2d684..ed2ff7e51f047 100644 --- a/clang/test/CodeGenObjC/arc-arm.m +++ b/clang/test/CodeGenObjC/arc-arm.m @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple armv7-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple arm64-apple-ios -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-apple-ios -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s -check-prefix=ARM64-ATTACHED // use an autorelease marker on ARM64. @@ -7,6 +7,11 @@ id test0(void) { extern id test0_helper(void); // CHECK: [[T0:%.*]] = call [[CC:(arm_aapcscc )?]]ptr @test0_helper() // CHECK-NEXT: ret ptr [[T0]] + // ARM64-ATTACHED: %call1 = call ptr @test0_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + // ARM64-ATTACHED: call void asm sideeffect "mov\09fp, fp\09\09// marker for objc_retainAutoreleaseReturnValue", ""() + // ARM64-ATTACHED: call void (...) @llvm.objc.clang.arc.noop.use(ptr %call1) #2 + // ARM64-ATTACHED: %0 = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr %call1) #2 + // ARM64-ATTACHED: ret ptr %0 return test0_helper(); } @@ -18,6 +23,12 @@ void test1(void) { // CHECK-NEXT: store ptr [[T1]], // CHECK-NEXT: call [[CC]]void @llvm.objc.storeStrong( // CHECK-NEXT: ret void + // ARM64-ATTACHED: %call1 = call ptr @test1_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + // ARM64-ATTACHED: call void asm sideeffect "mov\09fp, fp\09\09// marker for objc_retainAutoreleaseReturnValue", ""() + // ARM64-ATTACHED: call void (...) @llvm.objc.clang.arc.noop.use(ptr %call1) #2 + // ARM64-ATTACHED: store ptr %call1, + // ARM64-ATTACHED: call void @llvm.objc.storeStrong( + // ARM64-ATTACHED: ret void id x = test1_helper(); } @@ -26,6 +37,11 @@ void test1(void) { extern A *test2_helper(void); // CHECK: [[T0:%.*]] = call [[CC]]ptr @test2_helper() // CHECK-NEXT: ret ptr [[T0]] + // ARM64-ATTACHED: %call1 = call ptr @test2_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + // ARM64-ATTACHED: call void asm sideeffect "mov\09fp, fp\09\09// marker for objc_retainAutoreleaseReturnValue", ""() + // ARM64-ATTACHED: call void (...) @llvm.objc.clang.arc.noop.use(ptr %call1) #2 + // ARM64-ATTACHED: %0 = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr %call1) #2 + // ARM64-ATTACHED: ret ptr %0 return test2_helper(); } @@ -33,5 +49,10 @@ id test3(void) { extern A *test3_helper(void); // CHECK: [[T0:%.*]] = call [[CC]]ptr @test3_helper() // CHECK-NEXT: ret ptr [[T0]] + // ARM64-ATTACHED: %call1 = call ptr @test3_helper() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + // ARM64-ATTACHED: call void asm sideeffect "mov\09fp, fp\09\09// marker for objc_retainAutoreleaseReturnValue", ""() + // ARM64-ATTACHED: call void (...) @llvm.objc.clang.arc.noop.use(ptr %call1) #2 + // ARM64-ATTACHED: %0 = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr %call1) #2 + // ARM64-ATTACHED: ret ptr %0 return test3_helper(); } diff --git a/clang/test/CodeGenObjC/arc-unsafeclaim.m b/clang/test/CodeGenObjC/arc-unsafeclaim.m index 9c2b215df276f..969dd549b59ce 100644 --- a/clang/test/CodeGenObjC/arc-unsafeclaim.m +++ b/clang/test/CodeGenObjC/arc-unsafeclaim.m @@ -7,7 +7,7 @@ // RUN: %clang_cc1 -triple i386-apple-darwin11 -fobjc-runtime=macosx-fragile-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL // Make sure it works on ARM64. -// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL +// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=ATTACHED-CALL // Make sure it works on ARM. // RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL @@ -41,8 +41,9 @@ void test_assign(void) { // DISABLED-NEXT: [[T2:%.*]] = {{.*}}call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[T0]]) // ATTACHED-CALL-LABEL: define{{.*}} void @test_assign() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_assign_assign(void) { __unsafe_unretained id x, y; @@ -62,8 +63,9 @@ void test_assign_assign(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_assign() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_strong_assign_assign(void) { __strong id x; @@ -88,8 +90,9 @@ void test_strong_assign_assign(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_assign_assign() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_assign_strong_assign(void) { __unsafe_unretained id x; @@ -114,8 +117,9 @@ void test_assign_strong_assign(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_strong_assign() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_init(void) { __unsafe_unretained id x = makeA(); @@ -131,8 +135,9 @@ void test_init(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_init() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_init_assignment(void) { __unsafe_unretained id x; @@ -152,8 +157,9 @@ void test_init_assignment(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_init_assignment() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_strong_init_assignment(void) { __unsafe_unretained id x; @@ -175,8 +181,9 @@ void test_strong_init_assignment(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_init_assignment() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_init_strong_assignment(void) { __strong id x; @@ -200,8 +207,9 @@ void test_init_strong_assignment(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_init_strong_assignment() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_ignored(void) { makeA(); @@ -214,8 +222,9 @@ void test_ignored(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_ignored() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) void test_cast_to_void(void) { (void) makeA(); @@ -228,8 +237,9 @@ void test_cast_to_void(void) { // CHECK-NEXT: ret void // ATTACHED-CALL-LABEL: define{{.*}} void @test_cast_to_void() -// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], -// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) +// ATTACHED-CALL: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] +// ATTACHED-CALL-NEXT: call void asm sideeffect +// ATTACHED-CALL-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(ptr [[T0]]) // This is always at the end of the module. diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index cf344980cbaae..9bce0f19dd219 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/BranchProbabilityInfo.h" +#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/FunctionLoweringInfo.h" @@ -3159,6 +3160,10 @@ bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) { CLI.CB->getOperandBundle(LLVMContext::OB_kcfi)) return false; + // Allow SelectionDAG isel to handle clang.arc.attachedcall operand bundle. + if (CLI.CB && objcarc::hasAttachedCallOpBundle(CLI.CB)) + return false; + // Allow SelectionDAG isel to handle tail calls. if (IsTailCall) return false; diff --git a/llvm/test/CodeGen/AArch64/call-rv-marker.ll b/llvm/test/CodeGen/AArch64/call-rv-marker.ll index 0bc64498da324..b9811b346175b 100644 --- a/llvm/test/CodeGen/AArch64/call-rv-marker.ll +++ b/llvm/test/CodeGen/AArch64/call-rv-marker.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ; RUN: llc -o - %s | FileCheck --check-prefix=SELDAG --check-prefix=CHECK %s ; RUN: llc -global-isel -o - %s | FileCheck --check-prefix=GISEL --check-prefix=CHECK %s +; RUN: llc -O0 -o - %s | FileCheck --check-prefix=O0 --check-prefix=CHECK %s target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "arm64-apple-ios" @@ -49,6 +50,18 @@ define dso_local ptr @rv_marker_1_retain() { ; GISEL-NEXT: bl _objc_retainAutoreleasedReturnValue ; GISEL-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload ; GISEL-NEXT: ret +; +; O0-LABEL: rv_marker_1_retain: +; O0: ; %bb.0: ; %entry +; O0-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 16 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: bl _foo1 +; O0-NEXT: mov x29, x29 +; O0-NEXT: bl _objc_retainAutoreleasedReturnValue +; O0-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload +; O0-NEXT: ret entry: %call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ] ret ptr %call @@ -78,6 +91,18 @@ define dso_local ptr @rv_marker_1_unsafeClaim() { ; GISEL-NEXT: bl _objc_unsafeClaimAutoreleasedReturnValue ; GISEL-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload ; GISEL-NEXT: ret +; +; O0-LABEL: rv_marker_1_unsafeClaim: +; O0: ; %bb.0: ; %entry +; O0-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 16 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: bl _foo1 +; O0-NEXT: mov x29, x29 +; O0-NEXT: bl _objc_unsafeClaimAutoreleasedReturnValue +; O0-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload +; O0-NEXT: ret entry: %call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_unsafeClaimAutoreleasedReturnValue) ] ret ptr %call @@ -113,6 +138,21 @@ define dso_local void @rv_marker_2_select(i32 %c) { ; GISEL-NEXT: bl _objc_retainAutoreleasedReturnValue ; GISEL-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload ; GISEL-NEXT: b _foo2 +; +; O0-LABEL: rv_marker_2_select: +; O0: ; %bb.0: ; %entry +; O0-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 16 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: mov w8, #2 ; =0x2 +; O0-NEXT: subs w9, w0, #0 +; O0-NEXT: csinc w0, w8, wzr, eq +; O0-NEXT: bl _foo0 +; O0-NEXT: mov x29, x29 +; O0-NEXT: bl _objc_retainAutoreleasedReturnValue +; O0-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload +; O0-NEXT: b _foo2 entry: %tobool.not = icmp eq i32 %c, 0 %.sink = select i1 %tobool.not, i32 2, i32 1 @@ -247,6 +287,68 @@ define dso_local void @rv_marker_3() personality ptr @__gxx_personality_v0 { ; GISEL-NEXT: .byte 0 ; On action: cleanup ; GISEL-NEXT: Lcst_end0: ; GISEL-NEXT: .p2align 2, 0x0 +; +; O0-LABEL: rv_marker_3: +; O0: Lfunc_begin0: +; O0-NEXT: .cfi_startproc +; O0-NEXT: .cfi_personality 155, ___gxx_personality_v0 +; O0-NEXT: .cfi_lsda 16, Lexception0 +; O0-NEXT: ; %bb.0: ; %entry +; O0-NEXT: sub sp, sp, #32 +; O0-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 32 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: bl _foo1 +; O0-NEXT: mov x29, x29 +; O0-NEXT: bl _objc_retainAutoreleasedReturnValue +; O0-NEXT: str x0, [sp, #8] ; 8-byte Folded Spill +; O0-NEXT: Ltmp0: ; EH_LABEL +; O0-NEXT: bl _objc_object +; O0-NEXT: Ltmp1: ; EH_LABEL +; O0-NEXT: b LBB3_1 +; O0-NEXT: LBB3_1: ; %invoke.cont +; O0-NEXT: ldr x0, [sp, #8] ; 8-byte Folded Reload +; O0-NEXT: adrp x1, _objc_release@GOTPAGE +; O0-NEXT: ldr x1, [x1, _objc_release@GOTPAGEOFF] +; O0-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload +; O0-NEXT: add sp, sp, #32 +; O0-NEXT: br x1 +; O0-NEXT: LBB3_2: ; %lpad +; O0-NEXT: Ltmp2: ; EH_LABEL +; O0-NEXT: mov x1, x0 +; O0-NEXT: ldr x0, [sp, #8] ; 8-byte Folded Reload +; O0-NEXT: str x1, [sp] ; 8-byte Folded Spill +; O0-NEXT: adrp x8, _objc_release@GOTPAGE +; O0-NEXT: ldr x8, [x8, _objc_release@GOTPAGEOFF] +; O0-NEXT: blr x8 +; O0-NEXT: ldr x0, [sp] ; 8-byte Folded Reload +; O0-NEXT: bl __Unwind_Resume +; O0-NEXT: Lfunc_end0: +; O0-NEXT: .cfi_endproc +; O0-NEXT: .section __TEXT,__gcc_except_tab +; O0-NEXT: .p2align 2, 0x0 +; O0-NEXT: GCC_except_table3: +; O0-NEXT: Lexception0: +; O0-NEXT: .byte 255 ; @LPStart Encoding = omit +; O0-NEXT: .byte 255 ; @TType Encoding = omit +; O0-NEXT: .byte 1 ; Call site Encoding = uleb128 +; O0-NEXT: .uleb128 Lcst_end0-Lcst_begin0 +; O0-NEXT: Lcst_begin0: +; O0-NEXT: .uleb128 Lfunc_begin0-Lfunc_begin0 ; >> Call Site 1 << +; O0-NEXT: .uleb128 Ltmp0-Lfunc_begin0 ; Call between Lfunc_begin0 and Ltmp0 +; O0-NEXT: .byte 0 ; has no landing pad +; O0-NEXT: .byte 0 ; On action: cleanup +; O0-NEXT: .uleb128 Ltmp0-Lfunc_begin0 ; >> Call Site 2 << +; O0-NEXT: .uleb128 Ltmp1-Ltmp0 ; Call between Ltmp0 and Ltmp1 +; O0-NEXT: .uleb128 Ltmp2-Lfunc_begin0 ; jumps to Ltmp2 +; O0-NEXT: .byte 0 ; On action: cleanup +; O0-NEXT: .uleb128 Ltmp1-Lfunc_begin0 ; >> Call Site 3 << +; O0-NEXT: .uleb128 Lfunc_end0-Ltmp1 ; Call between Ltmp1 and Lfunc_end0 +; O0-NEXT: .byte 0 ; has no landing pad +; O0-NEXT: .byte 0 ; On action: cleanup +; O0-NEXT: Lcst_end0: +; O0-NEXT: .p2align 2, 0x0 entry: %call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ] invoke void @objc_object(ptr %call) #5 @@ -419,6 +521,88 @@ define dso_local void @rv_marker_4() personality ptr @__gxx_personality_v0 { ; GISEL-NEXT: .byte 0 ; On action: cleanup ; GISEL-NEXT: Lcst_end1: ; GISEL-NEXT: .p2align 2, 0x0 +; +; O0-LABEL: rv_marker_4: +; O0: Lfunc_begin1: +; O0-NEXT: .cfi_startproc +; O0-NEXT: .cfi_personality 155, ___gxx_personality_v0 +; O0-NEXT: .cfi_lsda 16, Lexception1 +; O0-NEXT: ; %bb.0: ; %entry +; O0-NEXT: sub sp, sp, #64 +; O0-NEXT: stp x29, x30, [sp, #48] ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 64 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: Ltmp3: ; EH_LABEL +; O0-NEXT: bl _foo1 +; O0-NEXT: mov x29, x29 +; O0-NEXT: bl _objc_retainAutoreleasedReturnValue +; O0-NEXT: str x0, [sp, #32] ; 8-byte Folded Spill +; O0-NEXT: Ltmp4: ; EH_LABEL +; O0-NEXT: b LBB4_1 +; O0-NEXT: LBB4_1: ; %invoke.cont +; O0-NEXT: Ltmp6: ; EH_LABEL +; O0-NEXT: ldr x0, [sp, #32] ; 8-byte Folded Reload +; O0-NEXT: bl _objc_object +; O0-NEXT: Ltmp7: ; EH_LABEL +; O0-NEXT: b LBB4_2 +; O0-NEXT: LBB4_2: ; %invoke.cont2 +; O0-NEXT: ldr x0, [sp, #32] ; 8-byte Folded Reload +; O0-NEXT: adrp x8, _objc_release@GOTPAGE +; O0-NEXT: ldr x8, [x8, _objc_release@GOTPAGEOFF] +; O0-NEXT: blr x8 +; O0-NEXT: add x0, sp, #47 +; O0-NEXT: bl __ZN1SD1Ev +; O0-NEXT: ldp x29, x30, [sp, #48] ; 16-byte Folded Reload +; O0-NEXT: add sp, sp, #64 +; O0-NEXT: ret +; O0-NEXT: LBB4_3: ; %lpad +; O0-NEXT: Ltmp5: ; EH_LABEL +; O0-NEXT: str x0, [sp, #24] ; 8-byte Folded Spill +; O0-NEXT: b LBB4_5 +; O0-NEXT: LBB4_4: ; %lpad1 +; O0-NEXT: Ltmp8: ; EH_LABEL +; O0-NEXT: mov x1, x0 +; O0-NEXT: ldr x0, [sp, #32] ; 8-byte Folded Reload +; O0-NEXT: str x1, [sp, #16] ; 8-byte Folded Spill +; O0-NEXT: adrp x8, _objc_release@GOTPAGE +; O0-NEXT: ldr x8, [x8, _objc_release@GOTPAGEOFF] +; O0-NEXT: blr x8 +; O0-NEXT: ldr x0, [sp, #16] ; 8-byte Folded Reload +; O0-NEXT: str x0, [sp, #24] ; 8-byte Folded Spill +; O0-NEXT: b LBB4_5 +; O0-NEXT: LBB4_5: ; %ehcleanup +; O0-NEXT: ldr x8, [sp, #24] ; 8-byte Folded Reload +; O0-NEXT: str x8, [sp, #8] ; 8-byte Folded Spill +; O0-NEXT: add x0, sp, #47 +; O0-NEXT: bl __ZN1SD1Ev +; O0-NEXT: ldr x0, [sp, #8] ; 8-byte Folded Reload +; O0-NEXT: bl __Unwind_Resume +; O0-NEXT: Lfunc_end1: +; O0-NEXT: .cfi_endproc +; O0-NEXT: .section __TEXT,__gcc_except_tab +; O0-NEXT: .p2align 2, 0x0 +; O0-NEXT: GCC_except_table4: +; O0-NEXT: Lexception1: +; O0-NEXT: .byte 255 ; @LPStart Encoding = omit +; O0-NEXT: .byte 255 ; @TType Encoding = omit +; O0-NEXT: .byte 1 ; Call site Encoding = uleb128 +; O0-NEXT: .uleb128 Lcst_end1-Lcst_begin1 +; O0-NEXT: Lcst_begin1: +; O0-NEXT: .uleb128 Ltmp3-Lfunc_begin1 ; >> Call Site 1 << +; O0-NEXT: .uleb128 Ltmp4-Ltmp3 ; Call between Ltmp3 and Ltmp4 +; O0-NEXT: .uleb128 Ltmp5-Lfunc_begin1 ; jumps to Ltmp5 +; O0-NEXT: .byte 0 ; On action: cleanup +; O0-NEXT: .uleb128 Ltmp6-Lfunc_begin1 ; >> Call Site 2 << +; O0-NEXT: .uleb128 Ltmp7-Ltmp6 ; Call between Ltmp6 and Ltmp7 +; O0-NEXT: .uleb128 Ltmp8-Lfunc_begin1 ; jumps to Ltmp8 +; O0-NEXT: .byte 0 ; On action: cleanup +; O0-NEXT: .uleb128 Ltmp7-Lfunc_begin1 ; >> Call Site 3 << +; O0-NEXT: .uleb128 Lfunc_end1-Ltmp7 ; Call between Ltmp7 and Lfunc_end1 +; O0-NEXT: .byte 0 ; has no landing pad +; O0-NEXT: .byte 0 ; On action: cleanup +; O0-NEXT: Lcst_end1: +; O0-NEXT: .p2align 2, 0x0 entry: %s = alloca %struct.S, align 1 call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %s) #2 @@ -501,6 +685,25 @@ define dso_local ptr @rv_marker_5_indirect_call() { ; GISEL-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload ; GISEL-NEXT: ret ; GISEL-NEXT: .loh AdrpLdr Lloh8, Lloh9 +; +; O0-LABEL: rv_marker_5_indirect_call: +; O0: ; %bb.0: ; %entry +; O0-NEXT: sub sp, sp, #32 +; O0-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 32 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: adrp x8, _fptr@PAGE +; O0-NEXT: ldr x8, [x8, _fptr@PAGEOFF] +; O0-NEXT: blr x8 +; O0-NEXT: mov x29, x29 +; O0-NEXT: bl _objc_retainAutoreleasedReturnValue +; O0-NEXT: str x0, [sp, #8] ; 8-byte Folded Spill +; O0-NEXT: bl _foo2 +; O0-NEXT: ldr x0, [sp, #8] ; 8-byte Folded Reload +; O0-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload +; O0-NEXT: add sp, sp, #32 +; O0-NEXT: ret entry: %0 = load ptr, ptr @fptr, align 8 %call = call ptr %0() [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ] @@ -540,6 +743,23 @@ define dso_local void @rv_marker_multiarg(i64 %a, i64 %b, i64 %c) { ; GISEL-NEXT: bl _objc_retainAutoreleasedReturnValue ; GISEL-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload ; GISEL-NEXT: ret +; +; O0-LABEL: rv_marker_multiarg: +; O0: ; %bb.0: +; O0-NEXT: sub sp, sp, #32 +; O0-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 32 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: str x0, [sp, #8] ; 8-byte Folded Spill +; O0-NEXT: mov x0, x2 +; O0-NEXT: ldr x2, [sp, #8] ; 8-byte Folded Reload +; O0-NEXT: bl _foo +; O0-NEXT: mov x29, x29 +; O0-NEXT: bl _objc_retainAutoreleasedReturnValue +; O0-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload +; O0-NEXT: add sp, sp, #32 +; O0-NEXT: ret call ptr @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.attachedcall"(ptr @objc_retainAutoreleasedReturnValue) ] ret void } @@ -566,6 +786,17 @@ define dso_local ptr @rv_marker_claim() { ; GISEL-NEXT: bl _objc_claimAutoreleasedReturnValue ; GISEL-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload ; GISEL-NEXT: ret +; +; O0-LABEL: rv_marker_claim: +; O0: ; %bb.0: ; %entry +; O0-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill +; O0-NEXT: .cfi_def_cfa_offset 16 +; O0-NEXT: .cfi_offset w30, -8 +; O0-NEXT: .cfi_offset w29, -16 +; O0-NEXT: bl _foo1 +; O0-NEXT: bl _objc_claimAutoreleasedReturnValue +; O0-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload +; O0-NEXT: ret entry: %call = call ptr @foo1() [ "clang.arc.attachedcall"(ptr @objc_claimAutoreleasedReturnValue) ] ret ptr %call