mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[CXX_FAST_TLS] Disable tail call when calling conventions are mismatched.
Since CXX_FAST_TLS has a bigger set of CSRs, we don't tail call when caller and callee have mismatched calling conventions. llvm-svn: 263856
This commit is contained in:
parent
73603a411f
commit
dfc9be9be5
@ -2817,6 +2817,13 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
|
||||
CallingConv::ID CallerCC = CallerF->getCallingConv();
|
||||
bool CCMatch = CallerCC == CalleeCC;
|
||||
|
||||
// Disable tailcall for CXX_FAST_TLS when callee and caller have different
|
||||
// calling conventions, given that CXX_FAST_TLS has a bigger CSR set.
|
||||
if (!CCMatch &&
|
||||
(CallerCC == CallingConv::CXX_FAST_TLS ||
|
||||
CalleeCC == CallingConv::CXX_FAST_TLS))
|
||||
return false;
|
||||
|
||||
// Byval parameters hand the function a pointer directly into the stack area
|
||||
// we want to reuse during a tail call. Working around this *is* possible (see
|
||||
// X86) but less efficient and uglier in LowerCall.
|
||||
|
@ -2100,6 +2100,13 @@ ARMTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
|
||||
CallingConv::ID CallerCC = CallerF->getCallingConv();
|
||||
bool CCMatch = CallerCC == CalleeCC;
|
||||
|
||||
// Disable tailcall for CXX_FAST_TLS when callee and caller have different
|
||||
// calling conventions, given that CXX_FAST_TLS has a bigger CSR set.
|
||||
if (!CCMatch &&
|
||||
(CallerCC == CallingConv::CXX_FAST_TLS ||
|
||||
CalleeCC == CallingConv::CXX_FAST_TLS))
|
||||
return false;
|
||||
|
||||
assert(Subtarget->supportsTailCall());
|
||||
|
||||
// Look for obvious safe cases to perform tail call optimization that do not
|
||||
|
@ -3767,6 +3767,13 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(
|
||||
if (IsCalleeWin64 != IsCallerWin64)
|
||||
return false;
|
||||
|
||||
// Disable tailcall for CXX_FAST_TLS when callee and caller have different
|
||||
// calling conventions, given that CXX_FAST_TLS has a bigger CSR set.
|
||||
if (!CCMatch &&
|
||||
(CallerCC == CallingConv::CXX_FAST_TLS ||
|
||||
CalleeCC == CallingConv::CXX_FAST_TLS))
|
||||
return false;
|
||||
|
||||
if (DAG.getTarget().Options.GuaranteedTailCallOpt) {
|
||||
if (canGuaranteeTCO(CalleeCC) && CCMatch)
|
||||
return true;
|
||||
|
@ -205,5 +205,18 @@ define cxx_fast_tlscc %class.C* @tls_test2() #1 {
|
||||
call cxx_fast_tlscc void @tls_helper()
|
||||
ret %class.C* @tC
|
||||
}
|
||||
|
||||
; Make sure we do not allow tail call when caller and callee have different
|
||||
; calling conventions.
|
||||
declare %class.C* @_ZN1CD1Ev(%class.C* readnone returned %this)
|
||||
; CHECK-LABEL: tls_test
|
||||
; CHECK: bl __tlv_atexit
|
||||
define cxx_fast_tlscc void @__tls_test() {
|
||||
entry:
|
||||
store i32 0, i32* getelementptr inbounds (%class.C, %class.C* @tC, i64 0, i32 0), align 4
|
||||
%0 = tail call i32 @_tlv_atexit(void (i8*)* bitcast (%class.C* (%class.C*)* @_ZN1CD1Ev to void (i8*)*), i8* bitcast (%class.C* @tC to i8*), i8* nonnull @__dso_handle) #1
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind "no-frame-pointer-elim"="true" }
|
||||
attributes #1 = { nounwind }
|
||||
|
@ -101,5 +101,18 @@ define cxx_fast_tlscc %class.C* @tls_test2() #1 {
|
||||
call cxx_fast_tlscc void @tls_helper()
|
||||
ret %class.C* @tC
|
||||
}
|
||||
|
||||
; Make sure we do not allow tail call when caller and callee have different
|
||||
; calling conventions.
|
||||
declare %class.C* @_ZN1CD1Ev(%class.C* readnone returned %this)
|
||||
; CHECK-LABEL: tls_test
|
||||
; CHECK: bl __tlv_atexit
|
||||
define cxx_fast_tlscc void @__tls_test() {
|
||||
entry:
|
||||
store i32 0, i32* getelementptr inbounds (%class.C, %class.C* @tC, i64 0, i32 0), align 4
|
||||
%0 = tail call i32 @_tlv_atexit(void (i8*)* bitcast (%class.C* (%class.C*)* @_ZN1CD1Ev to void (i8*)*), i8* bitcast (%class.C* @tC to i8*), i8* nonnull @__dso_handle) #1
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind "no-frame-pointer-elim"="true" }
|
||||
attributes #1 = { nounwind }
|
||||
|
@ -138,5 +138,18 @@ define cxx_fast_tlscc %class.C* @tls_test2() #1 {
|
||||
call cxx_fast_tlscc void @tls_helper()
|
||||
ret %class.C* @tC
|
||||
}
|
||||
|
||||
; Make sure we do not allow tail call when caller and callee have different
|
||||
; calling conventions.
|
||||
declare %class.C* @_ZN1CD1Ev(%class.C* readnone returned %this)
|
||||
; CHECK-LABEL: tls_test
|
||||
; CHECK: callq {{.*}}tlv_atexit
|
||||
define cxx_fast_tlscc void @tls_test() {
|
||||
entry:
|
||||
store i32 0, i32* getelementptr inbounds (%class.C, %class.C* @tC, i64 0, i32 0), align 4
|
||||
%0 = tail call i32 @_tlv_atexit(void (i8*)* bitcast (%class.C* (%class.C*)* @_ZN1CD1Ev to void (i8*)*), i8* bitcast (%class.C* @tC to i8*), i8* nonnull @__dso_handle) #1
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind "no-frame-pointer-elim"="true" }
|
||||
attributes #1 = { nounwind }
|
||||
|
Loading…
x
Reference in New Issue
Block a user