https://github.com/colemancda created 
https://github.com/llvm/llvm-project/pull/205469

Upstream version of https://github.com/swiftlang/llvm-project/pull/5551

>From 5ac4600bcfe16d63660ef1fd2236a55f56270218 Mon Sep 17 00:00:00 2001
From: Alsey Coleman Miller <[email protected]>
Date: Tue, 23 Jun 2026 22:18:29 -0400
Subject: [PATCH] [RISCV] Add support for Swift calling conventions and error
 handling

---
 clang/lib/Basic/Targets/RISCV.cpp           |  2 +
 clang/lib/CodeGen/Targets/RISCV.cpp         |  2 +-
 llvm/lib/Target/RISCV/RISCVCallingConv.cpp  | 41 ++++++++++++++++++---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp |  2 +
 llvm/lib/Target/RISCV/RISCVISelLowering.h   |  2 +
 5 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Basic/Targets/RISCV.cpp 
b/clang/lib/Basic/Targets/RISCV.cpp
index 6afef3e2c7c48..6d9a56754835f 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -598,6 +598,8 @@ RISCVTargetInfo::checkCallingConvention(CallingConv CC) 
const {
   switch (CC) {
   default:
     return CCCR_Warning;
+  case CC_Swift:
+  case CC_SwiftAsync:
   case CC_C:
   case CC_RISCVVectorCall:
   case CC_RISCVVLSCall_32:
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp 
b/clang/lib/CodeGen/Targets/RISCV.cpp
index bc3be06d176bc..608d980f5ecad 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -989,7 +989,7 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
       : TargetCodeGenInfo(
             std::make_unique<RISCVABIInfo>(CGT, XLen, FLen, EABI)) {
     SwiftInfo =
-        std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
+        std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/true);
   }
 
   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp 
b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
index 9853644080161..d24d3bddf76b1 100644
--- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
+++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
@@ -377,6 +377,9 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT 
LocVT,
   unsigned XLen = Subtarget.getXLen();
   MVT XLenVT = Subtarget.getXLenVT();
 
+  RISCVABI::ABI ABI = Subtarget.getTargetABI();
+  bool IsEABI = ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E;
+
   if (ArgFlags.isNest()) {
     // Static chain parameter must not be passed in normal argument registers,
     // so we assign t2/t3 for it as done in GCC's
@@ -387,9 +390,7 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT 
LocVT,
     // Normal: t2, Branch control flow protection: t3
     const auto StaticChainReg = HasCFBranch ? RISCV::X28 : RISCV::X7;
 
-    RISCVABI::ABI ABI = Subtarget.getTargetABI();
-    if (HasCFBranch &&
-        (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E))
+    if (HasCFBranch && IsEABI)
       reportFatalUsageError(
           "Nested functions with control flow protection are not "
           "usable with ILP32E or LP64E ABI.");
@@ -399,6 +400,38 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT 
LocVT,
     }
   }
 
+  // Swift calling convention special registers. Use callee-saved s-registers
+  // so they survive across call boundaries without extra save/restore 
overhead.
+  // X18(s2)=SwiftSelf, X19(s3)=SwiftError, X20(s4)=SwiftAsync, 
X21(s5)=SwiftCoro.
+  // X18-X21 exceed the 16-register limit of RVE; fall through to normal
+  // allocation on E-variant ABIs.
+  if (LocVT == XLenVT && !IsEABI) {
+    if (ArgFlags.isSwiftSelf()) {
+      if (MCRegister Reg = State.AllocateReg(RISCV::X18)) {
+        State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+        return false;
+      }
+    }
+    if (ArgFlags.isSwiftError()) {
+      if (MCRegister Reg = State.AllocateReg(RISCV::X19)) {
+        State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+        return false;
+      }
+    }
+    if (ArgFlags.isSwiftAsync()) {
+      if (MCRegister Reg = State.AllocateReg(RISCV::X20)) {
+        State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+        return false;
+      }
+    }
+    if (ArgFlags.isSwiftCoro()) {
+      if (MCRegister Reg = State.AllocateReg(RISCV::X21)) {
+        State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
+        return false;
+      }
+    }
+  }
+
   // Any return value split in to more than two values can't be returned
   // directly. Vectors are returned via the available vector registers.
   if ((!LocVT.isVector() || Subtarget.isPExtPackedType(LocVT)) && IsRet &&
@@ -414,8 +447,6 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT 
LocVT,
   bool AllowFPRForF16_F32 = false;
   // UseFPRForF64 if targeting an FLEN>=64 ABI and the argument isn't variadic.
   bool AllowFPRForF64 = false;
-
-  RISCVABI::ABI ABI = Subtarget.getTargetABI();
   switch (ABI) {
   default:
     llvm_unreachable("Unexpected ABI");
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp 
b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7a2b9611683c6..4d1ca19ed91ef 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -24753,6 +24753,8 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
   default:
     reportFatalUsageError("Unsupported calling convention");
   case CallingConv::C:
+  case CallingConv::Swift:
+  case CallingConv::SwiftTail:
   case CallingConv::Fast:
   case CallingConv::PreserveMost:
   case CallingConv::GRAAL:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h 
b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 4e7912ed815dd..410acb9885c59 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -453,6 +453,8 @@ class RISCVTargetLowering : public TargetLowering {
 
   bool supportKCFIBundles() const override { return true; }
 
+  bool supportSwiftError() const override { return true; }
+
   SDValue expandIndirectJTBranch(const SDLoc &dl, SDValue Value, SDValue Addr,
                                  int JTI, SelectionDAG &DAG) const override;
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to