From 3c16fbaf5f5ff93349796646ea92287baf133ed3 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 | 12 ++++++++++-- lib/IRGen/SwiftTargetInfo.h | 3 +++ 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 7a7e78e929f2..ddd50269cea3 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 0119b11cb04d..c63b75c1d795 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,13 @@ static void configureWasm32(IRGenModule &IGM, const llvm::Triple &triple, SwiftTargetInfo &target) { target.LeastValidPointerValue = SWIFT_ABI_WASM32_LEAST_VALID_POINTER; + + // Determine whether the target ABI supports returning two pointers directly. + llvm::Type *ptrTy = llvm::PointerType::getUnqual(IGM.getLLVMContext()); + target.SupportsDirectReturningAtLeastTwoPointers = + !clang::CodeGen::swiftcall::shouldPassIndirectly(IGM.getClangCGM(), + {ptrTy, ptrTy}, + /*asReturnValue*/ true); } /// Configure a default target. diff --git a/lib/IRGen/SwiftTargetInfo.h b/lib/IRGen/SwiftTargetInfo.h index 2384a8173310..2bd503368a14 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; }; }