[clang] [clang][MIPS] Support the Swift calling convention (PR #213446)
Alsey Coleman Miller via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 1 06:29:40 PDT 2026
https://github.com/colemancda created https://github.com/llvm/llvm-project/pull/213446
Compiling anything for MIPS with the Swift calling convention currently fails in two places.
`MipsTargetInfo` does not override `checkCallingConvention`, so it inherits the base implementation that accepts only `CC_C`. Sema drops `swiftcall` with `-Wignored-attributes` and substitutes the default convention, after which every `swift_context` parameter is a hard error:
```
error: 'swift_context' parameter can only be used with swiftcall or
swiftasynccall calling convention
```
Past that, `MIPSTargetCodeGenInfo` registers no `SwiftABIInfo`, so CodeGen asserts with "Swift ABI info has not been initialized".
This accepts `CC_Swift` and registers a `SwiftABIInfo`. No separate argument assignment is needed: the convention is lowered like the C convention, and `SwiftErrorInRegister` is false so the error is passed indirectly. The MIPS backend needs no change - it has no calling-convention gate in `LowerFormalArguments` or `LowerCall`.
`CC_SwiftAsync` is deliberately refused, as `SystemZTargetInfo` and `PPC64TargetInfo` refuse it: lowering it needs guaranteed tail calls that the backend does not provide, and `__has_extension(swiftasynccc)` is derived from this check, so callers fall back to `swiftcall` instead of emitting a convention with no lowering.
Found while building the Swift standard library for MIPS with Buildroot.
>From 047a339e277b42b4843ec7b3a597dce98cb077dc Mon Sep 17 00:00:00 2001
From: Alsey Coleman Miller <alseycmiller at gmail.com>
Date: Sat, 1 Aug 2026 09:27:41 -0400
Subject: [PATCH] [clang][MIPS] Support the Swift calling convention
MipsTargetInfo does not override checkCallingConvention, so it inherits
the base implementation that accepts only CC_C: swiftcall is dropped
with a warning and the default convention substituted, which then makes
every swift_context parameter a hard error. Accept CC_Swift, and
register a SwiftABIInfo so CodeGen has one - without it clang asserts
with "Swift ABI info has not been initialized".
Swift errors are passed indirectly rather than in a register, and
CC_SwiftAsync is refused the way SystemZ and PPC64 refuse it, since
lowering it needs guaranteed tail calls the backend does not provide.
---
clang/lib/Basic/Targets/Mips.h | 12 ++++++++++++
clang/lib/CodeGen/Targets/Mips.cpp | 5 ++++-
clang/test/Sema/mips-swiftcall.c | 20 ++++++++++++++++++++
3 files changed, 36 insertions(+), 1 deletion(-)
create mode 100644 clang/test/Sema/mips-swiftcall.c
diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h
index 2f251c7eb8690..30254ff06e401 100644
--- a/clang/lib/Basic/Targets/Mips.h
+++ b/clang/lib/Basic/Targets/Mips.h
@@ -430,6 +430,18 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
bool validateTarget(DiagnosticsEngine &Diags) const override;
bool hasBitIntType() const override { return true; }
+ CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+ switch (CC) {
+ case CC_C:
+ case CC_Swift:
+ return CCCR_OK;
+ case CC_SwiftAsync:
+ return CCCR_Error;
+ default:
+ return CCCR_Warning;
+ }
+ }
+
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index c093cfc668c2e..dbe7e5f8a516d 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -57,7 +57,10 @@ class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
public:
MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32)
: TargetCodeGenInfo(std::make_unique<MipsABIInfo>(CGT, IsO32)),
- SizeOfUnwindException(IsO32 ? 24 : 32) {}
+ SizeOfUnwindException(IsO32 ? 24 : 32) {
+ SwiftInfo =
+ std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
+ }
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
return 29;
diff --git a/clang/test/Sema/mips-swiftcall.c b/clang/test/Sema/mips-swiftcall.c
new file mode 100644
index 0000000000000..ff5c57868dc2f
--- /dev/null
+++ b/clang/test/Sema/mips-swiftcall.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mipsel-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mips64-unknown-linux-gnuabi64 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mips64el-unknown-linux-gnuabi64 -fsyntax-only -verify %s
+
+// swiftcall is supported on MIPS; swiftasynccall is not, because the backend
+// has no guaranteed tail call support for it.
+
+void __attribute__((swiftcall)) f(void *__attribute__((swift_context)) ctx) {}
+
+#if !__has_extension(swiftcc)
+#error swiftcc should be available on MIPS
+#endif
+
+#if __has_extension(swiftasynccc)
+#error swiftasynccc should not be available on MIPS
+#endif
+
+// expected-error at +1 {{'swiftasynccall' calling convention is not supported for this target}}
+void __attribute__((swiftasynccall)) g(void *__attribute__((swift_async_context)) ctx) {}
More information about the cfe-commits
mailing list