forked from OSchip/llvm-project
[CodeGen][ObjC] Mark calls to objc_unsafeClaimAutoreleasedReturnValue as
notail on x86-64 This is needed because the epilogue code inserted before tail calls on x86-64 breaks the handshake between the caller and callee. Calls to objc_retainAutoreleasedReturnValue used to have the same problem, which was fixed in https://reviews.llvm.org/D59656. rdar://problem/66029552 Differential Revision: https://reviews.llvm.org/D84540
This commit is contained in:
parent
7209f83112
commit
41b1e97b12
|
@ -2250,8 +2250,7 @@ llvm::Value *
|
|||
CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
|
||||
emitAutoreleasedReturnValueMarker(*this);
|
||||
llvm::CallInst::TailCallKind tailKind =
|
||||
CGM.getTargetCodeGenInfo()
|
||||
.shouldSuppressTailCallsOfRetainAutoreleasedReturnValue()
|
||||
CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail()
|
||||
? llvm::CallInst::TCK_NoTail
|
||||
: llvm::CallInst::TCK_None;
|
||||
return emitARCValueOperation(
|
||||
|
@ -2270,9 +2269,14 @@ CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
|
|||
llvm::Value *
|
||||
CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) {
|
||||
emitAutoreleasedReturnValueMarker(*this);
|
||||
return emitARCValueOperation(*this, value, nullptr,
|
||||
CGM.getObjCEntrypoints().objc_unsafeClaimAutoreleasedReturnValue,
|
||||
llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue);
|
||||
llvm::CallInst::TailCallKind tailKind =
|
||||
CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail()
|
||||
? llvm::CallInst::TCK_NoTail
|
||||
: llvm::CallInst::TCK_None;
|
||||
return emitARCValueOperation(
|
||||
*this, value, nullptr,
|
||||
CGM.getObjCEntrypoints().objc_unsafeClaimAutoreleasedReturnValue,
|
||||
llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue, tailKind);
|
||||
}
|
||||
|
||||
/// Release the given object.
|
||||
|
|
|
@ -2404,10 +2404,8 @@ public:
|
|||
}
|
||||
|
||||
/// Disable tail call on x86-64. The epilogue code before the tail jump blocks
|
||||
/// the autoreleaseRV/retainRV optimization.
|
||||
bool shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() const override {
|
||||
return true;
|
||||
}
|
||||
/// autoreleaseRV/retainRV and autoreleaseRV/unsafeClaimRV optimizations.
|
||||
bool markARCOptimizedReturnCallsAsNoTail() const override { return true; }
|
||||
|
||||
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
|
||||
return 7;
|
||||
|
|
|
@ -163,11 +163,9 @@ public:
|
|||
return "";
|
||||
}
|
||||
|
||||
/// Determine whether a call to objc_retainAutoreleasedReturnValue should be
|
||||
/// marked as 'notail'.
|
||||
virtual bool shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() const {
|
||||
return false;
|
||||
}
|
||||
/// Determine whether a call to objc_retainAutoreleasedReturnValue or
|
||||
/// objc_unsafeClaimAutoreleasedReturnValue should be marked as 'notail'.
|
||||
virtual bool markARCOptimizedReturnCallsAsNoTail() const { return false; }
|
||||
|
||||
/// Return a constant used by UBSan as a signature to identify functions
|
||||
/// possessing type information, or 0 if the platform is unsupported.
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// Make sure it works on x86-64.
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=NOTAIL-CALL
|
||||
|
||||
// Make sure it works on x86-32.
|
||||
// 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
|
||||
// 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 ARM.
|
||||
// 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
|
||||
// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
|
||||
// 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 -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED -check-prefix=CALL
|
||||
|
||||
// Make sure it works on ARM64.
|
||||
// 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
|
||||
// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
|
||||
// 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
|
||||
// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED -check-prefix=CALL
|
||||
|
||||
// Make sure that it's implicitly disabled if the runtime version isn't high enough.
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED
|
||||
|
@ -29,7 +29,8 @@ void test_assign() {
|
|||
// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA()
|
||||
// CHECK-MARKED-NEXT: call void asm sideeffect
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CALL-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: store i8* [[T4]], i8** [[X]]
|
||||
|
@ -53,7 +54,8 @@ void test_assign_assign() {
|
|||
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
|
||||
// CHECK-MARKED-NEXT: call void asm sideeffect
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CALL-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: store i8* [[T4]], i8** [[Y]]
|
||||
|
@ -126,7 +128,8 @@ void test_init() {
|
|||
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
|
||||
// CHECK-MARKED-NEXT: call void asm sideeffect
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CALL-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: store i8* [[T4]], i8** [[X]]
|
||||
|
@ -144,7 +147,8 @@ void test_init_assignment() {
|
|||
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
|
||||
// CHECK-MARKED-NEXT: call void asm sideeffect
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CALL-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
|
||||
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
|
||||
// CHECK-NEXT: store i8* [[T4]], i8** [[X]]
|
||||
|
@ -212,7 +216,8 @@ void test_ignored() {
|
|||
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
|
||||
// CHECK-MARKED-NEXT: call void asm sideeffect
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CALL-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CHECK-NEXT: bitcast i8* [[T2]] to [[A]]*
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
|
@ -223,7 +228,8 @@ void test_cast_to_void() {
|
|||
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
|
||||
// CHECK-MARKED-NEXT: call void asm sideeffect
|
||||
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
|
||||
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// NOTAIL-CALL-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CALL-NEXT: [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
|
||||
// CHECK-NEXT: bitcast i8* [[T2]] to [[A]]*
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
|
|
Loading…
Reference in New Issue