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
