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..41f25c015202 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 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; }; }