https://github.com/colemancda updated https://github.com/llvm/llvm-project/pull/205457
>From 4c89bc9cf9fd019225be748f544adf3c5fbcdd1e Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller <[email protected]> Date: Wed, 24 Jun 2026 00:05:58 -0400 Subject: [PATCH 1/2] [clang] Support the Swift calling convention on 32-bit PowerPC --- clang/lib/Basic/Targets/PPC.h | 11 +++++++++++ clang/lib/CodeGen/Targets/PPC.cpp | 16 +++++++++++++++- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 7 ++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index e3bf5072d932d..165de12118eb8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -433,6 +433,17 @@ class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo { std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override { return std::make_pair(32, 32); } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + case CC_Swift: + return CCCR_OK; + case CC_SwiftAsync: + return CCCR_Error; + default: + return CCCR_Warning; + } + } }; // Note: ABI differences may eventually require us to have a separate diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index ab069bfbd1b51..9024f9934c37e 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -382,12 +382,26 @@ class PPC32_SVR4_ABIInfo : public DefaultABIInfo { AggValueSlot Slot) const override; }; +/// Swift calling convention ABI for 32-bit PowerPC (SVR4/EABI). +class PPC32SwiftABIInfo : public SwiftABIInfo { +public: + explicit PPC32SwiftABIInfo(CodeGenTypes &CGT) + : SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/false) {} + + bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys, + bool AsReturnValue) const override { + return occupiesMoreThan(ComponentTys, /*total=*/4); + } +}; + class PPC32TargetCodeGenInfo : public TargetCodeGenInfo { public: PPC32TargetCodeGenInfo(CodeGenTypes &CGT, bool SoftFloatABI, bool RetSmallStructInRegABI) : TargetCodeGenInfo(std::make_unique<PPC32_SVR4_ABIInfo>( - CGT, SoftFloatABI, RetSmallStructInRegABI)) {} + CGT, SoftFloatABI, RetSmallStructInRegABI)) { + SwiftInfo = std::make_unique<PPC32SwiftABIInfo>(CGT); + } static bool isStructReturnInRegABI(const llvm::Triple &Triple, const CodeGenOptions &Opts); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 76cc06f2b4ed9..1c30846a3182c 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -5978,9 +5978,10 @@ 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 || + CallConv == CallingConv::SwiftTail) && + "Unknown calling convention!"); const Align PtrAlign(4); >From a57a711abeb99d67fc6ee4a31b0be34e0758f2fa Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller <[email protected]> Date: Wed, 24 Jun 2026 00:06:42 -0400 Subject: [PATCH 2/2] [clang] Add tests for Swift CC on 32-bit PowerPC --- clang/test/CodeGen/ppc-swiftcall.c | 61 ++++++++++++++++++++++ clang/test/Sema/ppc-swiftcall.c | 22 ++++++++ llvm/test/CodeGen/PowerPC/ppc32-swiftcc.ll | 38 ++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 clang/test/CodeGen/ppc-swiftcall.c create mode 100644 clang/test/Sema/ppc-swiftcall.c create mode 100644 llvm/test/CodeGen/PowerPC/ppc32-swiftcc.ll diff --git a/clang/test/CodeGen/ppc-swiftcall.c b/clang/test/CodeGen/ppc-swiftcall.c new file mode 100644 index 0000000000000..f61d30df23d27 --- /dev/null +++ b/clang/test/CodeGen/ppc-swiftcall.c @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -no-enable-noundef-analysis -triple powerpc-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -no-enable-noundef-analysis -triple powerpc-unknown-freebsd -emit-llvm -o - %s | FileCheck %s + +// REQUIRES: powerpc-registered-target + +// Verify that the Swift calling convention is emitted correctly for 32-bit +// PowerPC (SVR4/EABI): functions are 'swiftcc', special parameters map to the +// swiftself/swifterror attributes, and aggregates that occupy more than four +// 32-bit units are passed/returned indirectly. + +#define SWIFTCALL __attribute__((swiftcall)) +#define OUT __attribute__((swift_indirect_result)) +#define ERROR __attribute__((swift_error_result)) +#define CONTEXT __attribute__((swift_context)) + +/*****************************************************************************/ +/****************************** PARAMETER ABIS *******************************/ +/*****************************************************************************/ + +SWIFTCALL void indirect_result_1(OUT int *arg0, OUT float *arg1) {} +// CHECK-LABEL: define{{.*}} void @indirect_result_1(ptr noalias sret(ptr) align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}) + +typedef struct { char array[1024]; } struct_reallybig; +SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } +// CHECK-LABEL: define{{.*}} void @indirect_result_3(ptr{{.*}} sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}) + +SWIFTCALL void context_1(CONTEXT void *self) {} +// CHECK-LABEL: define{{.*}} void @context_1(ptr swiftself + +SWIFTCALL void context_2(void *arg0, CONTEXT void *self) {} +// CHECK-LABEL: define{{.*}} void @context_2(ptr{{.*}}, ptr swiftself + +SWIFTCALL void context_error_1(CONTEXT int *self, ERROR float **error) {} +// CHECK-LABEL: define{{.*}} void @context_error_1(ptr swiftself{{.*}}, ptr swifterror %0) + +void test_context_error_1(void) { + int x; + float *error; + context_error_1(&x, &error); +} +// CHECK-LABEL: define{{.*}} void @test_context_error_1() +// CHECK: [[TEMP:%.*]] = alloca swifterror ptr, align 4 +// CHECK: call [[SWIFTCC:swiftcc]] void @context_error_1(ptr swiftself {{.*}}, ptr swifterror [[TEMP]]) + +/*****************************************************************************/ +/********************************* AGGREGATES ********************************/ +/*****************************************************************************/ + +// A struct that occupies exactly four 32-bit units is passed/returned +// directly (it does not occupy *more than* four units). +typedef struct { int x0, x1, x2, x3; } struct_4i; +SWIFTCALL struct_4i return_struct_4i(void) { struct_4i r = {0,0,0,0}; return r; } +// Returned directly: the result type is non-void and there is no sret +// pointer, so the parameter list is empty. +// CHECK-LABEL: define{{.*}} swiftcc {{.*}}@return_struct_4i() + +// A struct that occupies five 32-bit units occupies more than four and is +// therefore returned indirectly via sret. +typedef struct { int x0, x1, x2, x3, x4; } struct_5i; +SWIFTCALL struct_5i return_struct_5i(void) { struct_5i r = {0,0,0,0,0}; return r; } +// CHECK-LABEL: define{{.*}} swiftcc void @return_struct_5i(ptr{{.*}} sret(%struct.struct_5i) diff --git a/clang/test/Sema/ppc-swiftcall.c b/clang/test/Sema/ppc-swiftcall.c new file mode 100644 index 0000000000000..61b9842419f14 --- /dev/null +++ b/clang/test/Sema/ppc-swiftcall.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fsyntax-only %s -verify +// RUN: %clang_cc1 -triple powerpc-unknown-freebsd -fsyntax-only %s -verify + +// The Swift calling convention is supported on 32-bit PowerPC (SVR4/EABI), +// but the Swift async calling convention is not. + +// 'swiftcc' must be reported as an available extension. +#if !__has_extension(swiftcc) +#error "swiftcc should be supported on 32-bit PowerPC" +#endif + +// 'swiftasynccc' must not be reported as available. +#if __has_extension(swiftasynccc) +#error "swiftasynccc should not be supported on 32-bit PowerPC" +#endif + +// swiftcall is accepted without diagnostics. +void __attribute__((swiftcall)) f(void) {} + +// swiftasynccall is rejected with an error on this target. +// expected-error@+1 {{'swiftasynccall' calling convention is not supported for this target}} +void __attribute__((swiftasynccall)) g(char *__attribute__((swift_async_context)) ctx) {} diff --git a/llvm/test/CodeGen/PowerPC/ppc32-swiftcc.ll b/llvm/test/CodeGen/PowerPC/ppc32-swiftcc.ll new file mode 100644 index 0000000000000..f4a7f72e88408 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/ppc32-swiftcc.ll @@ -0,0 +1,38 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc-unknown-freebsd < %s | FileCheck %s + +; The 32-bit PowerPC SVR4/EABI lowering (LowerCall_32SVR4) must accept the +; swiftcc and swifttailcc calling conventions instead of asserting on an +; "Unknown calling convention". These tests confirm such calls lower cleanly; +; the exact branch mnemonic (bl vs. a tail-call b) is intentionally not pinned. + +declare swiftcc i32 @callee_swift(i32 %x) + +define swiftcc i32 @caller_swift(i32 %x) { +; CHECK-LABEL: caller_swift: +; CHECK: callee_swift +entry: + %r = call swiftcc i32 @callee_swift(i32 %x) + ret i32 %r +} + +declare swifttailcc i32 @callee_swifttail(i32 %x) + +define swifttailcc i32 @caller_swifttail(i32 %x) { +; CHECK-LABEL: caller_swifttail: +; CHECK: callee_swifttail +entry: + %r = call swifttailcc i32 @callee_swifttail(i32 %x) + ret i32 %r +} + +; swiftself is passed through an ordinary argument register on the SVR4 ABI. +declare swiftcc ptr @use_self(ptr swiftself %ctx) + +define swiftcc ptr @caller_swiftself(ptr %ctx) { +; CHECK-LABEL: caller_swiftself: +; CHECK: use_self +entry: + %r = call swiftcc ptr @use_self(ptr swiftself %ctx) + ret ptr %r +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
