llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-risc-v Author: Alsey Coleman Miller (colemancda) <details> <summary>Changes</summary> `RISCVTargetCodeGenInfo` already registers a `SwiftABIInfo`, so RISC-V looks like it supports the Swift calling convention, but nothing ever reaches CodeGen: `RISCVTargetInfo::checkCallingConvention` does not accept `CC_Swift`, so sema drops the attribute and substitutes the default convention. Every `swift_context` parameter then fails: ``` error: 'swift_context' parameter can only be used with swiftcall or swiftasynccall calling convention ``` Reproducer: ``` echo '__attribute__((swiftcall)) void f(__attribute__((swift_context)) void *c);' > sc.c clang -target riscv64-unknown-linux-gnu -fsyntax-only sc.c ``` Past sema, `RISCVTargetLowering::LowerFormalArguments` has no case for `CallingConv::Swift` and reports "Unsupported calling convention". This accepts `CC_Swift` and lowers it. It needs no separate argument assignment: `CC_RISCV` is what the C convention already uses, and `SwiftErrorInRegister` is false, so the error is passed indirectly rather than pinned to a register. `CC_SwiftAsync` is refused, as `SystemZTargetInfo` and `PPC64TargetInfo` refuse it - lowering it needs guaranteed tail calls the backend does not provide. Since `__has_extension(swiftasynccc)` is derived from this check, callers fall back to `swiftcall` rather than emitting a convention with no lowering. `clang/test/Sema/swift-call-conv.c` asserted that RISC-V supports neither convention; that line is replaced by a dedicated test covering both. Found while building the Swift standard library for riscv64 with Buildroot. Supersedes the RISC-V half of https://github.com/swiftlang/llvm-project/pull/5551, which was filed against the Swift fork. --- Full diff: https://github.com/llvm/llvm-project/pull/213448.diff 5 Files Affected: - (modified) clang/lib/Basic/Targets/RISCV.cpp (+3) - (added) clang/test/Sema/riscv-swiftcall.c (+18) - (modified) clang/test/Sema/swift-call-conv.c (-2) - (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+1) - (added) llvm/test/CodeGen/RISCV/swiftcc.ll (+26) ``````````diff diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 6afef3e2c7c48..801cfe9e60cd1 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -612,7 +612,10 @@ RISCVTargetInfo::checkCallingConvention(CallingConv CC) const { case CC_RISCVVLSCall_16384: case CC_RISCVVLSCall_32768: case CC_RISCVVLSCall_65536: + case CC_Swift: return CCCR_OK; + case CC_SwiftAsync: + return CCCR_Error; } } diff --git a/clang/test/Sema/riscv-swiftcall.c b/clang/test/Sema/riscv-swiftcall.c new file mode 100644 index 0000000000000..e9ebbbef91745 --- /dev/null +++ b/clang/test/Sema/riscv-swiftcall.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple riscv32-unknown-elf -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple riscv64-unknown-linux-gnu -fsyntax-only -verify %s + +// swiftcall is supported on RISC-V; swiftasynccall is not, because lowering +// it needs guaranteed tail calls the backend does not provide. + +void __attribute__((swiftcall)) f(void *__attribute__((swift_context)) ctx) {} + +#if !__has_extension(swiftcc) +#error swiftcc should be available on RISC-V +#endif + +#if __has_extension(swiftasynccc) +#error swiftasynccc should not be available on RISC-V +#endif + +// expected-error@+1 {{'swiftasynccall' calling convention is not supported for this target}} +void __attribute__((swiftasynccall)) g(void *__attribute__((swift_async_context)) ctx) {} diff --git a/clang/test/Sema/swift-call-conv.c b/clang/test/Sema/swift-call-conv.c index 2c9be84055848..42351f7e85d61 100644 --- a/clang/test/Sema/swift-call-conv.c +++ b/clang/test/Sema/swift-call-conv.c @@ -1,8 +1,6 @@ // RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -fsyntax-only %s -verify // RUN: %clang_cc1 -triple thumbv7-unknown-windows-msvc -fsyntax-only %s -verify // RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fsyntax-only %s -verify -// RISC-V does not support swiftcall -// RUN: %clang_cc1 -triple riscv32-unknown-elf -fsyntax-only %s -verify #if __has_extension(swiftcc) // expected-no-diagnostics diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index aad62e7d40c54..99b908f2ea6b9 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -25738,6 +25738,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments( case CallingConv::PreserveMost: case CallingConv::GRAAL: case CallingConv::RISCV_VectorCall: + case CallingConv::Swift: #define CC_VLS_CASE(ABI_VLEN) case CallingConv::RISCV_VLSCall_##ABI_VLEN: CC_VLS_CASE(32) CC_VLS_CASE(64) diff --git a/llvm/test/CodeGen/RISCV/swiftcc.ll b/llvm/test/CodeGen/RISCV/swiftcc.ll new file mode 100644 index 0000000000000..0d505fd4d5862 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/swiftcc.ll @@ -0,0 +1,26 @@ +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s | FileCheck %s + +; swiftcc is lowered like the C convention on RISC-V. Check that it is +; accepted at all: LowerFormalArguments used to reject it with +; "Unsupported calling convention". + +define swiftcc i32 @swiftcc_param(i32 %a, i32 %b) { +; CHECK-LABEL: swiftcc_param: +; CHECK: ret + %r = add i32 %a, %b + ret i32 %r +} + +define swiftcc i32 @call_swiftcc(i32 %a, i32 %b) { +; CHECK-LABEL: call_swiftcc: +; CHECK: call swiftcc_param + %r = call swiftcc i32 @swiftcc_param(i32 %a, i32 %b) + ret i32 %r +} + +define swiftcc ptr @swiftself_param(ptr swiftself %addr) { +; CHECK-LABEL: swiftself_param: +; CHECK: ret + ret ptr %addr +} `````````` </details> https://github.com/llvm/llvm-project/pull/213448 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
