From 04cebc523fcfd1be499e10aac71bca7da6434b5b Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Thu, 6 Nov 2025 06:27:44 +0000 Subject: [PATCH] [IRGen][wasm] Disable manual indirection for coroutine yielding results `clang::CodeGen::swiftcall::shouldPassIndirectly` now returns true for multiple scalar values on wasm targets because the Wasm MVP does not support multiple return values. For such targets where we can't directly return two pointers, we should not attempt to indirect at this stage because the later MC lowering will also indirect the return. --- lib/IRGen/GenCall.cpp | 30 +++++++++++++++++------------- lib/IRGen/SwiftTargetInfo.cpp | 10 ++++++++-- lib/IRGen/SwiftTargetInfo.h | 3 +++ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 7a7e78e929f29..ddd50269cea32 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -870,22 +870,26 @@ void SignatureExpansion::expandCoroutineResult(bool forContinuation) { } // Find the maximal sequence of the component types that we can - // convince the ABI to pass directly. + // convince the ABI to pass directly if the target supports + // directly returning at least two pointers. // When counting components, ignore the continuation pointer. unsigned numDirectComponents = components.size() - 1; SmallVector overflowTypes; - while (clang::CodeGen::swiftcall:: - shouldPassIndirectly(IGM.ClangCodeGen->CGM(), components, - /*asReturnValue*/ true)) { - // If we added a pointer to the end of components, remove it. - if (!overflowTypes.empty()) components.pop_back(); - - // Remove the last component and add it as an overflow type. - overflowTypes.push_back(components.pop_back_val()); - --numDirectComponents; - - // Add a pointer to the end of components. - components.push_back(IGM.Int8PtrTy); + if (IGM.TargetInfo.SupportsDirectReturningAtLeastTwoPointers) { + while (clang::CodeGen::swiftcall::shouldPassIndirectly( + IGM.ClangCodeGen->CGM(), components, + /*asReturnValue*/ true)) { + // If we added a pointer to the end of components, remove it. + if (!overflowTypes.empty()) + components.pop_back(); + + // Remove the last component and add it as an overflow type. + overflowTypes.push_back(components.pop_back_val()); + --numDirectComponents; + + // Add a pointer to the end of components. + components.push_back(IGM.Int8PtrTy); + } } // We'd better have been able to pass at least two pointers. diff --git a/lib/IRGen/SwiftTargetInfo.cpp b/lib/IRGen/SwiftTargetInfo.cpp index 0119b11cb04d2..41f25c0152029 100644 --- a/lib/IRGen/SwiftTargetInfo.cpp +++ b/lib/IRGen/SwiftTargetInfo.cpp @@ -17,12 +17,13 @@ #include "SwiftTargetInfo.h" #include "IRGenModule.h" -#include "llvm/TargetParser/Triple.h" -#include "llvm/IR/DataLayout.h" #include "swift/ABI/System.h" #include "swift/AST/ASTContext.h" #include "swift/AST/IRGenOptions.h" #include "swift/Basic/Platform.h" +#include "clang/CodeGen/SwiftCallingConv.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/TargetParser/Triple.h" using namespace swift; using namespace irgen; @@ -194,6 +195,11 @@ static void configureWasm32(IRGenModule &IGM, const llvm::Triple &triple, SwiftTargetInfo &target) { target.LeastValidPointerValue = SWIFT_ABI_WASM32_LEAST_VALID_POINTER; + + target.SupportsDirectReturningAtLeastTwoPointers = + clang::CodeGen::swiftcall::shouldPassIndirectly(IGM.getClangCGM(), + {IGM.PtrTy, IGM.PtrTy}, + /*asReturnValue*/ true); } /// Configure a default target. diff --git a/lib/IRGen/SwiftTargetInfo.h b/lib/IRGen/SwiftTargetInfo.h index 2384a81733100..2bd503368a143 100644 --- a/lib/IRGen/SwiftTargetInfo.h +++ b/lib/IRGen/SwiftTargetInfo.h @@ -118,6 +118,9 @@ class SwiftTargetInfo { bool HasSwiftClientRRLibrary = false; bool UsableSwiftAsyncContextAddrIntrinsic = false; + + /// True if the target supports directly returning at least two pointers. + bool SupportsDirectReturningAtLeastTwoPointers = true; }; }