[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
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index cd2b84f..26dfb62 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -2250,8 +2250,7 @@
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 @@
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.
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 9cd63eb..f31d432 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -2404,10 +2404,8 @@
}
/// 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;
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 1152cab..0df9667 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -163,11 +163,9 @@
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.