mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add frontend flag for explicitly setting ccc
Adds a new swift-frontend flag to allow users to choose which calling convention is used to make c function calls. This hidden flag is called `-experimental-platform-c-calling-convention`. This behavior is needed to workaround rdar://109431863 (Swift-frontend produces trapping llvm ir for non-trapping sil). The root cause of this issue is that IRGen always emits c function calls with llvm's default C calling convention. However clang may select a different (incompatible) calling convention for the function, eventually resulting--via InstCombine and SimplifyCFG--in a trap instead of the function call. This failure mode is most readily seen with the triple `armv7em-apple-none-macho` when attempting to call functions taking struct arguments. Example unoptimized ir below: ```llvm-ir call void @bar([4 x i32] %17, i32 2), !dbg !109 ... define internal arm_aapcs_vfpcc void @bar( [4 x i32] %bar.coerce, i32 noundef %x) ``` In the future it would be better to use the clang importer or some other tool to determine the calling convention for each function instead of setting the calling convention frontend invocation wide. Note: I don't know for sure whether or not clang should be explicitly annotating these functions with a calling convention instead of aliasing C to mean ARM_AAPCS_VFP for this particular combination of `-target`, `-mfloat-abi`, and `-mcpu`.
This commit is contained in:
@@ -2807,6 +2807,65 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(options::OPT_experimental_platform_c_calling_convention)) {
|
||||
Opts.ExperimentalPlatformCCallingConvention =
|
||||
llvm::StringSwitch<llvm::CallingConv::ID>(A->getValue())
|
||||
.Case("c", llvm::CallingConv::C)
|
||||
.Case("fast", llvm::CallingConv::Fast)
|
||||
.Case("cold", llvm::CallingConv::Cold)
|
||||
.Case("ghc", llvm::CallingConv::GHC)
|
||||
.Case("hipe", llvm::CallingConv::HiPE)
|
||||
.Case("webkit_js", llvm::CallingConv::WebKit_JS)
|
||||
.Case("anyreg", llvm::CallingConv::AnyReg)
|
||||
.Case("preservemost", llvm::CallingConv::PreserveMost)
|
||||
.Case("preserveall", llvm::CallingConv::PreserveAll)
|
||||
.Case("swift", llvm::CallingConv::Swift)
|
||||
.Case("cxx_fast_tls", llvm::CallingConv::CXX_FAST_TLS)
|
||||
.Case("tail", llvm::CallingConv::Tail)
|
||||
.Case("cfguard_check", llvm::CallingConv::CFGuard_Check)
|
||||
.Case("swifttail", llvm::CallingConv::SwiftTail)
|
||||
.Case("firsttargetcc", llvm::CallingConv::FirstTargetCC)
|
||||
.Case("x86_stdcall", llvm::CallingConv::X86_StdCall)
|
||||
.Case("x86_fastcall", llvm::CallingConv::X86_FastCall)
|
||||
.Case("arm_apcs", llvm::CallingConv::ARM_APCS)
|
||||
.Case("arm_aapcs", llvm::CallingConv::ARM_AAPCS)
|
||||
.Case("arm_aapcs_vfp", llvm::CallingConv::ARM_AAPCS_VFP)
|
||||
.Case("msp430_intr", llvm::CallingConv::MSP430_INTR)
|
||||
.Case("x86_thiscall", llvm::CallingConv::X86_ThisCall)
|
||||
.Case("ptx_kernel", llvm::CallingConv::PTX_Kernel)
|
||||
.Case("ptx_device", llvm::CallingConv::PTX_Device)
|
||||
.Case("spir_func", llvm::CallingConv::SPIR_FUNC)
|
||||
.Case("spir_kernel", llvm::CallingConv::SPIR_KERNEL)
|
||||
.Case("intel_ocl_bi", llvm::CallingConv::Intel_OCL_BI)
|
||||
.Case("x86_64_sysv", llvm::CallingConv::X86_64_SysV)
|
||||
.Case("win64", llvm::CallingConv::Win64)
|
||||
.Case("x86_vectorcall", llvm::CallingConv::X86_VectorCall)
|
||||
.Case("x86_intr", llvm::CallingConv::X86_INTR)
|
||||
.Case("avr_intr", llvm::CallingConv::AVR_INTR)
|
||||
.Case("avr_signal", llvm::CallingConv::AVR_SIGNAL)
|
||||
.Case("avr_builtin", llvm::CallingConv::AVR_BUILTIN)
|
||||
.Case("amdgpu_vs", llvm::CallingConv::AMDGPU_VS)
|
||||
.Case("amdgpu_gs", llvm::CallingConv::AMDGPU_GS)
|
||||
.Case("amdgpu_ps", llvm::CallingConv::AMDGPU_PS)
|
||||
.Case("amdgpu_cs", llvm::CallingConv::AMDGPU_CS)
|
||||
.Case("amdgpu_kernel", llvm::CallingConv::AMDGPU_KERNEL)
|
||||
.Case("x86_regcall", llvm::CallingConv::X86_RegCall)
|
||||
.Case("amdgpu_hs", llvm::CallingConv::AMDGPU_HS)
|
||||
.Case("msp430_builtin", llvm::CallingConv::MSP430_BUILTIN)
|
||||
.Case("amdgpu_ls", llvm::CallingConv::AMDGPU_LS)
|
||||
.Case("amdgpu_es", llvm::CallingConv::AMDGPU_ES)
|
||||
.Case("aarch64_vectorcall", llvm::CallingConv::AArch64_VectorCall)
|
||||
.Case("aarch64_sve_vectorcall", llvm::CallingConv::AArch64_SVE_VectorCall)
|
||||
.Case("wasm_emscripteninvoke", llvm::CallingConv::WASM_EmscriptenInvoke)
|
||||
.Case("amdgpu_gfx", llvm::CallingConv::AMDGPU_Gfx)
|
||||
.Case("m68k_intr", llvm::CallingConv::M68k_INTR)
|
||||
.Case("aarch64_sme_abi_support_routines_preservemost_from_x0",
|
||||
llvm::CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
|
||||
.Case("aarch64_sme_abi_support_routines_preservemost_from_x2",
|
||||
llvm::CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
|
||||
.Default(llvm::CallingConv::C);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user