https://github.com/colemancda created https://github.com/llvm/llvm-project/pull/213447
`PPC64TargetInfo` accepts `CC_Swift`, but `PPC32TargetInfo` overrides `checkCallingConvention` nowhere, so 32-bit targets inherit the base implementation that accepts only `CC_C`. Sema drops `swiftcall` with `-Wignored-attributes` and substitutes the default convention, and every `swift_context` parameter then fails: ``` error: 'swift_context' parameter can only be used with swiftcall or swiftasynccall calling convention ``` This mirrors the 64-bit table for `PPC32TargetInfo`, registers a `SwiftABIInfo` in `PPC32TargetCodeGenInfo`, and lets `LowerCall_32SVR4` accept `CallingConv::Swift` rather than assert "Unknown calling convention!" on it. The convention is lowered like the C convention, and `SwiftErrorInRegister` is false so the error is passed indirectly - no separate argument assignment is required. `CC_SwiftAsync` stays refused, exactly as on PPC64. Found while building the Swift standard library for 32-bit PowerPC with Buildroot. >From bf8951892158757c8a4eb21364018062e487026c Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller <[email protected]> Date: Sat, 1 Aug 2026 09:28:25 -0400 Subject: [PATCH] [clang][PowerPC] Support the Swift calling convention on 32-bit PowerPC PPC64TargetInfo accepts CC_Swift, but PPC32TargetInfo does not override checkCallingConvention at all, so 32-bit targets inherit the base implementation accepting only CC_C: swiftcall is dropped with a warning and every swift_context parameter then fails to compile. Mirror the 64-bit table, register a SwiftABIInfo for CodeGen, and let LowerCall_32SVR4 accept the convention instead of asserting on it. CC_SwiftAsync stays refused, as on PPC64. --- clang/lib/Basic/Targets/PPC.h | 12 +++++++++++ clang/lib/CodeGen/Targets/PPC.cpp | 5 ++++- clang/test/Sema/ppc32-swiftcall.c | 18 ++++++++++++++++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 6 +++--- llvm/test/CodeGen/PowerPC/swiftcc.ll | 24 +++++++++++++++++++++ 5 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 clang/test/Sema/ppc32-swiftcall.c create mode 100644 llvm/test/CodeGen/PowerPC/swiftcc.ll diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 22880e5a04a3f..e3d5a0fb99364 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -432,6 +432,18 @@ class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { return TargetInfo::PowerABIBuiltinVaList; } + 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/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 5109567212adb..785fdc4555470 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -388,7 +388,10 @@ class PPC32TargetCodeGenInfo : public TargetCodeGenInfo { PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI, bool RetSmallStructInRegABI) : TargetCodeGenInfo(std::make_unique<PPC32_SVR4_ABIInfo>( - CGT, SoftFloatABI, RetSmallStructInRegABI)) {} + CGT, SoftFloatABI, RetSmallStructInRegABI)) { + SwiftInfo = + std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); + } static bool isStructReturnInRegABI(const llvm::Triple &Triple, const CodeGenOptions &Opts); diff --git a/clang/test/Sema/ppc32-swiftcall.c b/clang/test/Sema/ppc32-swiftcall.c new file mode 100644 index 0000000000000..76dcbcecd3721 --- /dev/null +++ b/clang/test/Sema/ppc32-swiftcall.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple powerpcle-unknown-linux-gnu -fsyntax-only -verify %s + +// swiftcall is supported on 32-bit PowerPC, matching the 64-bit target; +// swiftasynccall is not, for the same reason it is refused there. + +void __attribute__((swiftcall)) f(void *__attribute__((swift_context)) ctx) {} + +#if !__has_extension(swiftcc) +#error swiftcc should be available on 32-bit PowerPC +#endif + +#if __has_extension(swiftasynccc) +#error swiftasynccc should not be available on 32-bit PowerPC +#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/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 1a80d0a05655a..2623f9600fb7c 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -5980,9 +5980,9 @@ SDValue PPCTargetLowering::LowerCall_32SVR4( const bool IsVarArg = CFlags.IsVarArg; const bool IsTailCall = CFlags.IsTailCall; - assert((CallConv == CallingConv::C || - CallConv == CallingConv::Cold || - CallConv == CallingConv::Fast) && "Unknown calling convention!"); + assert((CallConv == CallingConv::C || CallConv == CallingConv::Cold || + CallConv == CallingConv::Fast || CallConv == CallingConv::Swift) && + "Unknown calling convention!"); const Align PtrAlign(4); diff --git a/llvm/test/CodeGen/PowerPC/swiftcc.ll b/llvm/test/CodeGen/PowerPC/swiftcc.ll new file mode 100644 index 0000000000000..06e679861c176 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/swiftcc.ll @@ -0,0 +1,24 @@ +; RUN: llc -mtriple=powerpc-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s + +; swiftcc is lowered like the C convention on 32-bit PowerPC. Check that it +; is accepted at all: LowerCall_32SVR4 used to assert on it. + +define swiftcc i32 @swiftcc_param(i32 %a, i32 %b) { +; CHECK-LABEL: swiftcc_param: +; CHECK: blr + %r = add i32 %a, %b + ret i32 %r +} + +define swiftcc i32 @call_swiftcc(i32 %a, i32 %b) { +; CHECK-LABEL: call_swiftcc: +; CHECK: bl 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: blr + ret ptr %addr +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
