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

Reply via email to