From 617a089115f8aee4a52dd5787c4813383c994f7b Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 10:31:26 -0700 Subject: [PATCH 01/13] Revert "Merge pull request #76396 from aschwaighofer/async_typed_throws_empty_errors" This reverts commit ba8b7e44b82b377556df84e813e441a0ce85f8cb, reversing changes made to 4693a4765f04f222422452d1da542a61017c0bce. --- lib/IRGen/GenCall.cpp | 5 +--- test/IRGen/typed_throws.sil | 58 ------------------------------------- 2 files changed, 1 insertion(+), 62 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index a201435ce7135..c8a7bdc8d637f 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -3030,10 +3030,7 @@ class AsyncCallEmission final : public CallEmission { IGF.IGM.getTypeInfo(silErrorTy).nativeReturnValueSchema(IGF.IGM); if (nativeSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly() || - (errorSchema.empty() && fnConv.hasIndirectSILResults())) { // direct empty typed errors are passed - // indirectly for compatibility with generic - // functions. + errorSchema.shouldReturnTypedErrorIndirectly()) { // Return the error indirectly. auto buf = IGF.getCalleeTypedErrorResultSlot(silErrorTy); Args[--LastArgWritten] = buf.getAddress(); diff --git a/test/IRGen/typed_throws.sil b/test/IRGen/typed_throws.sil index 8d5caa462ee53..3e5ca9cdc7c09 100644 --- a/test/IRGen/typed_throws.sil +++ b/test/IRGen/typed_throws.sil @@ -458,61 +458,3 @@ bb6: %t = tuple() return %t : $() } - -sil @callee : $@convention(thin) @async (Int64) -> (@out (), @error Never) { -bb0(%0 : $*(), %1: $Int64): - %17 = tuple () - return %17 : $() -} - -// CHECK: define{{.*}} swifttailcc void @callee(ptr {{.*}} %0, ptr swiftasync %1, i64 %2, ptr %3) - -// CHECK: define{{.*}} swifttailcc void @caller(ptr swiftasync %0) {{.*}} { -// CHECK-NOT: define -// CHECK: [[CTXT:%.*]] = call swiftcc ptr @swift_task_alloc -// CHECK-NOT: define -// CHECK: call {{.*}} @llvm.coro.suspend.async.sl_p0p0s(i32 256, ptr {{.*}}, ptr @__swift_async_resume_project_context, ptr @caller.0, ptr @callee, ptr undef, ptr [[CTXT]], i64 66, ptr %swifterror) - -sil @caller : $@convention(thin) @async () -> () { -bb0: - %5 = integer_literal $Builtin.Int64, 66 - %6 = struct $Int64 (%5 : $Builtin.Int64) - %9 = alloc_stack $() - %10 = function_ref @callee : $@convention(thin) @async (Int64) -> (@out (), @error Never) - try_apply %10(%9, %6) : $@convention(thin) @async (Int64) -> (@out (), @error Never), normal bb1, error bb2 - -bb1(%12 : $()): - dealloc_stack %9 : $*() - %17 = tuple () - return %17 : $() - -bb2(%19 : $Never): - unreachable -} - -sil @callee2 : $@convention(thin) @async (Int) -> (Int, @error Never) { -bb0(%0 : $Int): - %5 = integer_literal $Builtin.Int64, 66 - %6 = struct $Int (%5 : $Builtin.Int64) - return %6 : $Int -} - -// CHECK: define{{.*}} swifttailcc void @callee2(ptr swiftasync %0, i64 %1) - -// CHECK: define{{.*}} swifttailcc void @caller2(ptr swiftasync %0) -// CHECK: [[CTXT:%.*]] = call swiftcc ptr @swift_task_alloc -// CHECK: @llvm.coro.suspend.async.sl_p0i64p0s({{.*}} ptr @callee2, ptr [[CTXT]], i64 67) -sil @caller2 : $@convention(thin) @async () -> () { -bb0: - %5 = integer_literal $Builtin.Int64, 67 - %6 = struct $Int (%5 : $Builtin.Int64) - %10 = function_ref @callee2 : $@convention(thin) @async (Int) -> (Int, @error Never) - try_apply %10(%6) : $@convention(thin) @async (Int) -> (Int, @error Never), normal bb1, error bb2 - -bb1(%12 : $Int): - %17 = tuple () - return %17 : $() - -bb2(%19 : $Never): - unreachable -} From 55252e5f0befd59959ac25a7618ba11b4e61957e Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 10:33:20 -0700 Subject: [PATCH 02/13] Revert "Merge pull request #76302 from drexin/wip-typed-throws-empty" This reverts commit cf2af6809ecd52c8d49520309011e439df8e45c6, reversing changes made to 0c30f5532ed595ee5c2ba7256c2c3b0a2510a21e. --- lib/IRGen/GenCall.cpp | 17 ++++++++++------- test/IRGen/typed_throws.swift | 15 --------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index c8a7bdc8d637f..5fa7115bb2caf 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -2330,14 +2330,17 @@ void SignatureExpansion::expandAsyncAwaitType() { if (!nativeError.shouldReturnTypedErrorIndirectly()) { auto combined = combineResultAndTypedErrorType(IGM, native, nativeError); - if (!combined.combinedTy->isVoidTy()) { - if (auto *structTy = dyn_cast(combined.combinedTy)) { - for (auto *elem : structTy->elements()) { - components.push_back(elem); - } - } else { - components.push_back(combined.combinedTy); + if (combined.combinedTy->isVoidTy()) { + addErrorResult(); + return; + } + + if (auto *structTy = dyn_cast(combined.combinedTy)) { + for (auto *elem : structTy->elements()) { + components.push_back(elem); } + } else { + components.push_back(combined.combinedTy); } addErrorResult(); ResultIRType = llvm::StructType::get(IGM.getLLVMContext(), components); diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index 4766849a3c905..65871c5d31b01 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -6,8 +6,6 @@ // RUN: %target-swift-frontend -primary-file %s -emit-ir -enable-library-evolution -// RUN: %target-swift-frontend -primary-file %s -emit-ir -O - // XFAIL: CPU=arm64e // REQUIRES: PTRSIZE=64 @@ -234,16 +232,3 @@ protocol Proto { // This used to crash. static func f2() throws(SP) -> Int64 } - -@inline(never) -@available(SwiftStdlib 6.0, *) -public func passthroughAsync(f: () async throws(E) -> T) async throws(E) -> T { - try await f() -} - -@available(SwiftStdlib 6.0, *) -public func reabstractAsyncVoidThrowsNever() async { - await passthroughAsync { - () - } -} From 66586a69ad3b5cabe20733cdcc79d82cf78fd6b8 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 10:33:33 -0700 Subject: [PATCH 03/13] Revert "Merge pull request #76129 from aschwaighofer/irgen_typed_throws_irgenthunk" This reverts commit dd0de58b52fc0bd629fc192a5921e213f63c6625, reversing changes made to 74b32210425dd8aebbc6bdfad5285da386b5cd66. --- lib/IRGen/GenCall.cpp | 43 -------------------------------- lib/IRGen/GenCall.h | 5 ---- lib/IRGen/GenThunk.cpp | 19 ++------------ lib/IRGen/IRGenSIL.cpp | 47 ++++++++++++++++++++++++++++++++--- test/IRGen/typed_throws.swift | 16 ------------ 5 files changed, 46 insertions(+), 84 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 5fa7115bb2caf..cb7b4f51705ec 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -6507,46 +6507,3 @@ llvm::FunctionType *FunctionPointer::getFunctionType() const { return Sig.getType(); } - -void irgen::buildDirectError(IRGenFunction &IGF, - const CombinedResultAndErrorType &combined, - const NativeConventionSchema &errorSchema, - SILType silErrorTy, Explosion &errorResult, - bool forAsync, Explosion &out) { - if (combined.combinedTy->isVoidTy()) { - return; - } - - llvm::Value *expandedResult = llvm::UndefValue::get(combined.combinedTy); - auto *structTy = dyn_cast(combined.combinedTy); - - if (!errorSchema.getExpandedType(IGF.IGM)->isVoidTy()) { - auto nativeError = - errorSchema.mapIntoNative(IGF.IGM, IGF, errorResult, silErrorTy, false); - - if (structTy) { - for (unsigned i : combined.errorValueMapping) { - llvm::Value *elt = nativeError.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, - /*forExtraction*/ false); - expandedResult = IGF.Builder.CreateInsertValue(expandedResult, elt, i); - } - if (forAsync) { - IGF.emitAllExtractValues(expandedResult, structTy, out); - } else { - out = expandedResult; - } - } else if (!errorSchema.getExpandedType(IGF.IGM)->isVoidTy()) { - out = convertForDirectError(IGF, nativeError.claimNext(), - combined.combinedTy, - /*forExtraction*/ false); - } - } else { - if (forAsync && structTy) { - IGF.emitAllExtractValues(expandedResult, structTy, out); - } else { - out = expandedResult; - } - } -} diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index 8584d7c35f8fa..84b68041a0efd 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -278,11 +278,6 @@ namespace irgen { llvm::Value *convertForDirectError(IRGenFunction &IGF, llvm::Value *value, llvm::Type *toTy, bool forExtraction); - void buildDirectError(IRGenFunction &IGF, - const CombinedResultAndErrorType &combined, - const NativeConventionSchema &errorSchema, - SILType silErrorTy, Explosion &errorResult, - bool forAsync, Explosion &out); } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/GenThunk.cpp b/lib/IRGen/GenThunk.cpp index ff93d672be400..82e1e1829eb8c 100644 --- a/lib/IRGen/GenThunk.cpp +++ b/lib/IRGen/GenThunk.cpp @@ -153,8 +153,7 @@ void IRGenThunk::prepareArguments() { auto &resultSchema = resultTI.nativeReturnValueSchema(IGF.IGM); if (resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly() || - conv.hasIndirectSILResults()) { + errorSchema.shouldReturnTypedErrorIndirectly()) { auto directTypedErrorAddr = original.takeLast(); IGF.setCalleeTypedErrorResultSlot(Address(directTypedErrorAddr, errorTI.getStorageType(), @@ -406,21 +405,7 @@ void IRGenThunk::emit() { errorArgValues.add(errorValue); emitAsyncReturn(IGF, *asyncLayout, origTy, errorArgValues.claimAll()); } else { - if (!error->empty()) { - // Map the direct error explosion from the call back to the native - // explosion for the return. - SILType silErrorTy = conv.getSILErrorType(expansionContext); - auto &errorTI = IGF.IGM.getTypeInfo(silErrorTy); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGF.IGM); - auto combined = - combineResultAndTypedErrorType(IGF.IGM, schema, errorSchema); - Explosion nativeAgg; - buildDirectError(IGF, combined, errorSchema, silErrorTy, *error, - /*forAsync*/ false, nativeAgg); - IGF.emitScalarReturn(IGF.CurFn->getReturnType(), nativeAgg); - } else { - IGF.emitScalarReturn(IGF.CurFn->getReturnType(), *error); - } + IGF.emitScalarReturn(IGF.CurFn->getReturnType(), *error); } IGF.Builder.emitBlock(successBB); } else { diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index c9ce17e0ab245..ce2e0de96fef6 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -4426,6 +4426,48 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { getSILModule()); assert(!conv.hasIndirectSILErrorResults()); + auto buildDirectError = [=](const CombinedResultAndErrorType &combined, + const NativeConventionSchema &errorSchema, + SILType silErrorTy, Explosion &errorResult, + bool forAsync, Explosion &out) { + if (combined.combinedTy->isVoidTy()) { + return; + } + + llvm::Value *expandedResult = llvm::UndefValue::get(combined.combinedTy); + auto *structTy = dyn_cast(combined.combinedTy); + + if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { + auto nativeError = + errorSchema.mapIntoNative(IGM, *this, errorResult, silErrorTy, false); + + if (structTy) { + for (unsigned i : combined.errorValueMapping) { + llvm::Value *elt = nativeError.claimNext(); + auto *nativeTy = structTy->getElementType(i); + elt = convertForDirectError(*this, elt, nativeTy, + /*forExtraction*/ false); + expandedResult = Builder.CreateInsertValue(expandedResult, elt, i); + } + if (forAsync) { + emitAllExtractValues(expandedResult, structTy, out); + } else { + out = expandedResult; + } + } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { + out = + convertForDirectError(*this, nativeError.claimNext(), + combined.combinedTy, /*forExtraction*/ false); + } + } else { + if (forAsync && structTy) { + emitAllExtractValues(expandedResult, structTy, out); + } else { + out = expandedResult; + } + } + }; + if (!isAsync()) { auto fnTy = CurFn->getFunctionType(); auto retTy = fnTy->getReturnType(); @@ -4458,8 +4500,7 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { auto combined = combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); Explosion nativeAgg; - buildDirectError(*this, combined, errorSchema, silErrorTy, - errorResult, + buildDirectError(combined, errorSchema, silErrorTy, errorResult, /*forAsync*/ false, nativeAgg); emitScalarReturn(combined.combinedTy, nativeAgg); @@ -4509,7 +4550,7 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { Explosion nativeAgg; auto combined = combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - buildDirectError(*this, combined, errorSchema, silErrorTy, exn, + buildDirectError(combined, errorSchema, silErrorTy, exn, /*forAsync*/ true, nativeAgg); assert(exn.empty() && "Unclaimed typed error results"); diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index 65871c5d31b01..c4fd0a260f701 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -4,8 +4,6 @@ // RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK -// RUN: %target-swift-frontend -primary-file %s -emit-ir -enable-library-evolution - // XFAIL: CPU=arm64e // REQUIRES: PTRSIZE=64 @@ -218,17 +216,3 @@ func mayThrowEmptyErrorAsync(x: Bool) async throws(EmptyError) -> String? { return "" } - - -enum SP: Error { - case a - case b(Int32) -} - -protocol Proto { - // This used to crash. - static func f() throws(SP) -> Self - - // This used to crash. - static func f2() throws(SP) -> Int64 -} From 291abb6255ce20903593d548d56410713fc87df5 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:17:55 -0700 Subject: [PATCH 04/13] Revert "Merge pull request #75677 from drexin/wip-133006541" This reverts commit 739c7192ae3371eb4e51af67ff7fc0c722d82c6a, reversing changes made to 7d1c505ae166851a73ec479e397b38d248bf9773. --- lib/IRGen/GenCall.cpp | 25 ++++++++++++++----------- lib/IRGen/GenCall.h | 4 ++-- lib/IRGen/GenThunk.cpp | 4 ++-- lib/IRGen/IRGenSIL.cpp | 4 ++-- test/IRGen/typed_throws_32_bit.swift | 27 --------------------------- 5 files changed, 20 insertions(+), 44 deletions(-) delete mode 100644 test/IRGen/typed_throws_32_bit.swift diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index cb7b4f51705ec..f766caae5a21e 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -4511,12 +4511,12 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError( for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { llvm::Value *elt = values[combined.errorValueMapping[i]]; auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, /*forExtraction*/ true); + elt = convertForAsyncDirect(IGF, elt, nativeTy, /*forExtraction*/ true); errorExplosion.add(elt); } } else { auto *converted = - convertForDirectError(IGF, values[combined.errorValueMapping[0]], + convertForAsyncDirect(IGF, values[combined.errorValueMapping[0]], combined.combinedTy, /*forExtraction*/ true); errorExplosion.add(converted); } @@ -4534,12 +4534,12 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError( dyn_cast(nativeSchema.getExpandedType(IGF.IGM))) { for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { auto *nativeTy = structTy->getElementType(i); - auto *converted = convertForDirectError(IGF, values[i], nativeTy, + auto *converted = convertForAsyncDirect(IGF, values[i], nativeTy, /*forExtraction*/ true); resultExplosion.add(converted); } } else { - auto *converted = convertForDirectError( + auto *converted = convertForAsyncDirect( IGF, values[0], combined.combinedTy, /*forExtraction*/ true); resultExplosion.add(converted); } @@ -5407,7 +5407,7 @@ llvm::Value* IRGenFunction::coerceValue(llvm::Value *value, llvm::Type *toTy, return loaded; } -llvm::Value *irgen::convertForDirectError(IRGenFunction &IGF, +llvm::Value *irgen::convertForAsyncDirect(IRGenFunction &IGF, llvm::Value *value, llvm::Type *toTy, bool forExtraction) { auto &Builder = IGF.Builder; @@ -5417,9 +5417,12 @@ llvm::Value *irgen::convertForDirectError(IRGenFunction &IGF, if (toTy->isPointerTy()) { if (fromTy->isPointerTy()) return Builder.CreateBitCast(value, toTy); - return Builder.CreateIntToPtr(value, toTy); + if (fromTy == IGF.IGM.IntPtrTy) + return Builder.CreateIntToPtr(value, toTy); } else if (fromTy->isPointerTy()) { - return Builder.CreatePtrToInt(value, toTy); + if (toTy == IGF.IGM.IntPtrTy) { + return Builder.CreatePtrToInt(value, toTy); + } } if (forExtraction) { @@ -5877,12 +5880,12 @@ void IRGenFunction::emitScalarReturn(SILType returnResultType, for (unsigned i = 0, e = native.size(); i != e; ++i) { llvm::Value *elt = native.claimNext(); auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(*this, elt, nativeTy, + elt = convertForAsyncDirect(*this, elt, nativeTy, /*forExtraction*/ false); nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); } } else { - nativeAgg = convertForDirectError(*this, native.claimNext(), combinedTy, + nativeAgg = convertForAsyncDirect(*this, native.claimNext(), combinedTy, /*forExtraction*/ false); } } @@ -6214,7 +6217,7 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout, for (unsigned i = 0, e = result.size(); i != e; ++i) { llvm::Value *elt = result.claimNext(); auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, + elt = convertForAsyncDirect(IGF, elt, nativeTy, /*forExtraction*/ false); nativeAgg = IGF.Builder.CreateInsertValue(nativeAgg, elt, i); } @@ -6224,7 +6227,7 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout, nativeResultsStorage.push_back(out.claimNext()); } } else { - auto *converted = convertForDirectError( + auto *converted = convertForAsyncDirect( IGF, result.claimNext(), combinedTy, /*forExtraction*/ false); nativeResultsStorage.push_back(converted); } diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index 84b68041a0efd..e1e4a58f12da9 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -274,8 +274,8 @@ namespace irgen { void forwardAsyncCallResult(IRGenFunction &IGF, CanSILFunctionType fnType, AsyncContextLayout &layout, llvm::CallInst *call); - /// Converts a value for direct error return. - llvm::Value *convertForDirectError(IRGenFunction &IGF, llvm::Value *value, + /// Converts a value for async direct errors. + llvm::Value *convertForAsyncDirect(IRGenFunction &IGF, llvm::Value *value, llvm::Type *toTy, bool forExtraction); } // end namespace irgen diff --git a/lib/IRGen/GenThunk.cpp b/lib/IRGen/GenThunk.cpp index 82e1e1829eb8c..fe584375bf515 100644 --- a/lib/IRGen/GenThunk.cpp +++ b/lib/IRGen/GenThunk.cpp @@ -384,14 +384,14 @@ void IRGenThunk::emit() { for (unsigned i : combined.errorValueMapping) { llvm::Value *elt = nativeError.claimNext(); auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(IGF, elt, nativeTy, + elt = convertForAsyncDirect(IGF, elt, nativeTy, /*forExtraction*/ false); expandedResult = IGF.Builder.CreateInsertValue(expandedResult, elt, i); } IGF.emitAllExtractValues(expandedResult, structTy, errorArgValues); } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - errorArgValues = convertForDirectError(IGF, nativeError.claimNext(), + errorArgValues = convertForAsyncDirect(IGF, nativeError.claimNext(), combined.combinedTy, /*forExtraction*/ false); } diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index ce2e0de96fef6..41a14e40d013e 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -4445,7 +4445,7 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { for (unsigned i : combined.errorValueMapping) { llvm::Value *elt = nativeError.claimNext(); auto *nativeTy = structTy->getElementType(i); - elt = convertForDirectError(*this, elt, nativeTy, + elt = convertForAsyncDirect(*this, elt, nativeTy, /*forExtraction*/ false); expandedResult = Builder.CreateInsertValue(expandedResult, elt, i); } @@ -4456,7 +4456,7 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { } } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { out = - convertForDirectError(*this, nativeError.claimNext(), + convertForAsyncDirect(*this, nativeError.claimNext(), combined.combinedTy, /*forExtraction*/ false); } } else { diff --git a/test/IRGen/typed_throws_32_bit.swift b/test/IRGen/typed_throws_32_bit.swift deleted file mode 100644 index e5927e0c8b756..0000000000000 --- a/test/IRGen/typed_throws_32_bit.swift +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %target-swift-frontend -emit-ir -primary-file %s - -// REQUIRES: CPU=arm64_32 || CPU=armv7k - -public class MyClass { - let x: Int64 - init(x: Int64) { - self.x = x - } -} - -public struct MyError: Error { - let x: MyClass -} - -@inline(never) -public func foo(f: () throws(MyError) -> Int64) throws(MyError) -> Int64 { - return try f() -} - -public func bar(f: () throws(MyError) -> Int64) -> Int64 { - do { - return try foo(f: f) - } catch { - return error.x.x - } -} From 2bc788c1025a34dc6863f3aac65afef9dc833fba Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:20:14 -0700 Subject: [PATCH 05/13] Revert "Merge pull request #75379 from drexin/wip-132122011" This reverts commit 618a9bf7c5b49a8e686b1ff15a7eeec7f44206e1, reversing changes made to 448596c03eca2dc19063ab65857eb446fceadf0b. --- lib/IRGen/IRGenSIL.cpp | 10 ++-------- test/IRGen/typed_throws.swift | 11 ----------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 41a14e40d013e..b2931091f288f 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -4385,7 +4385,6 @@ static void emitReturnInst(IRGenSILFunction &IGF, if (fnType->hasErrorResult()) { error.add(getNullErrorValue()); } - emitAsyncReturn(IGF, asyncLayout, funcResultType, fnType, result, error); } else { auto funcLang = IGF.CurSILFn->getLoweredFunctionType()->getLanguage(); @@ -4435,13 +4434,12 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { } llvm::Value *expandedResult = llvm::UndefValue::get(combined.combinedTy); - auto *structTy = dyn_cast(combined.combinedTy); if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { auto nativeError = errorSchema.mapIntoNative(IGM, *this, errorResult, silErrorTy, false); - if (structTy) { + if (auto *structTy = dyn_cast(combined.combinedTy)) { for (unsigned i : combined.errorValueMapping) { llvm::Value *elt = nativeError.claimNext(); auto *nativeTy = structTy->getElementType(i); @@ -4460,11 +4458,7 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { combined.combinedTy, /*forExtraction*/ false); } } else { - if (forAsync && structTy) { - emitAllExtractValues(expandedResult, structTy, out); - } else { - out = expandedResult; - } + out = expandedResult; } }; diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index c4fd0a260f701..c0c976ba71dc5 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -205,14 +205,3 @@ func mayThrowAsyncTiny(x: Bool) async throws(TinyError) -> Bool { func callsMayThrowAsyncTiny(x: Bool) async { _ = try! await mayThrowAsyncTiny(x: x) } - -struct EmptyError: Error {} - -@available(SwiftStdlib 6.0, *) -func mayThrowEmptyErrorAsync(x: Bool) async throws(EmptyError) -> String? { - guard x else { - throw EmptyError() - } - - return "" -} From 8be107735ec405708a2418503ef24f821ce44526 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:22:14 -0700 Subject: [PATCH 06/13] Revert "Merge pull request #75316 from drexin/wip-131960281" This reverts commit e3577ed26652024dc90560572fb6dec58f27d947, reversing changes made to f3acbb079fa766eb357b16b5925cb4bd729b1e6f. --- lib/IRGen/GenCall.cpp | 14 +------------- test/IRGen/typed_throws.swift | 17 ----------------- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index f766caae5a21e..c3b7e19651fe4 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -3232,19 +3232,7 @@ class AsyncCallEmission final : public CallEmission { bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly(); if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect()) { - llvm::Value *resultAgg; - if (resultTys.size() == 1) { - resultAgg = Builder.CreateExtractValue(result, numAsyncContextParams); - } else { - auto resultTy = llvm::StructType::get(IGM.getLLVMContext(), resultTys); - resultAgg = llvm::UndefValue::get(resultTy); - for (unsigned i = 0, e = resultTys.size(); i != e; ++i) { - llvm::Value *elt = - Builder.CreateExtractValue(result, numAsyncContextParams + i); - resultAgg = Builder.CreateInsertValue(resultAgg, elt, i); - } - } - return emitToUnmappedExplosionWithDirectTypedError(resultType, resultAgg, + return emitToUnmappedExplosionWithDirectTypedError(resultType, result, out); } else if (resultTys.size() == 1) { result = Builder.CreateExtractValue(result, numAsyncContextParams); diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index c0c976ba71dc5..af8af43dc7488 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -188,20 +188,3 @@ func throwsGenericAsync(x: Bool, y: T) async throws(T) -> Int { return 32 } - -enum TinyError: Error { - case a -} - -@available(SwiftStdlib 6.0, *) -func mayThrowAsyncTiny(x: Bool) async throws(TinyError) -> Bool { - guard x else { - throw .a - } - return false -} - -@available(SwiftStdlib 6.0, *) -func callsMayThrowAsyncTiny(x: Bool) async { - _ = try! await mayThrowAsyncTiny(x: x) -} From 9bebe11183cf664847d29f10dc89d433e4769899 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:22:55 -0700 Subject: [PATCH 07/13] Revert "Merge pull request #75221 from drexin/wip-129359370" This reverts commit c11b301188b039938dc1f96f6c95c9977add226e, reversing changes made to 1921b60ff479a6b943eed946e3a4b24e998e8d59. --- lib/IRGen/GenCall.cpp | 259 +++++++-------------------- lib/IRGen/GenCall.h | 4 - lib/IRGen/GenFunc.cpp | 19 +- lib/IRGen/GenThunk.cpp | 65 ++----- lib/IRGen/IRGenSIL.cpp | 134 ++++++-------- test/IRGen/typed_throws.sil | 31 ++-- test/IRGen/typed_throws.swift | 38 +--- test/IRGen/typed_throws_thunks.swift | 4 +- 8 files changed, 144 insertions(+), 410 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index c3b7e19651fe4..abb7e1e99076a 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -2125,40 +2125,10 @@ void SignatureExpansion::expandAsyncReturnType() { } }; - auto fnConv = getSILFuncConventions(); - - auto resultType = - fnConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); + auto resultType = getSILFuncConventions().getSILResultType( + IGM.getMaximalTypeExpansionContext()); auto &ti = IGM.getTypeInfo(resultType); auto &native = ti.nativeReturnValueSchema(IGM); - - if (!fnConv.hasIndirectSILResults() && !fnConv.hasIndirectSILErrorResults() && - !native.requiresIndirect() && fnConv.funcTy->hasErrorResult() && - fnConv.isTypedError()) { - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - auto &errorTi = IGM.getTypeInfo(errorType); - auto &nativeError = errorTi.nativeReturnValueSchema(IGM); - if (!nativeError.shouldReturnTypedErrorIndirectly()) { - auto combined = combineResultAndTypedErrorType(IGM, native, nativeError); - - if (combined.combinedTy->isVoidTy()) { - addErrorResult(); - return; - } - - if (auto *structTy = dyn_cast(combined.combinedTy)) { - for (auto *elem : structTy->elements()) { - ParamIRTypes.push_back(elem); - } - } else { - ParamIRTypes.push_back(combined.combinedTy); - } - } - addErrorResult(); - return; - } - if (native.requiresIndirect() || native.empty()) { addErrorResult(); return; @@ -2176,23 +2146,11 @@ void SignatureExpansion::expandAsyncReturnType() { void SignatureExpansion::addIndirectThrowingResult() { if (getSILFuncConventions().funcTy->hasErrorResult() && getSILFuncConventions().isTypedError()) { - auto resultType = getSILFuncConventions().getSILResultType( - IGM.getMaximalTypeExpansionContext()); - auto &ti = IGM.getTypeInfo(resultType); - auto &native = ti.nativeReturnValueSchema(IGM); - - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - const TypeInfo &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - - if (getSILFuncConventions().hasIndirectSILResults() || - getSILFuncConventions().hasIndirectSILErrorResults() || - native.requiresIndirect() || - nativeError.shouldReturnTypedErrorIndirectly()) { - auto errorStorageTy = errorTI.getStorageType(); - ParamIRTypes.push_back(errorStorageTy->getPointerTo()); - } + auto resultType = getSILFuncConventions().getSILErrorType( + IGM.getMaximalTypeExpansionContext()); + const TypeInfo &resultTI = IGM.getTypeInfo(resultType); + auto storageTy = resultTI.getStorageType(); + ParamIRTypes.push_back(storageTy->getPointerTo()); } } @@ -2318,36 +2276,6 @@ void SignatureExpansion::expandAsyncAwaitType() { IGM.getMaximalTypeExpansionContext()); auto &ti = IGM.getTypeInfo(resultType); auto &native = ti.nativeReturnValueSchema(IGM); - - if (!getSILFuncConventions().hasIndirectSILResults() && - !getSILFuncConventions().hasIndirectSILErrorResults() && - getSILFuncConventions().funcTy->hasErrorResult() && - !native.requiresIndirect() && getSILFuncConventions().isTypedError()) { - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - auto &errorTi = IGM.getTypeInfo(errorType); - auto &nativeError = errorTi.nativeReturnValueSchema(IGM); - if (!nativeError.shouldReturnTypedErrorIndirectly()) { - auto combined = combineResultAndTypedErrorType(IGM, native, nativeError); - - if (combined.combinedTy->isVoidTy()) { - addErrorResult(); - return; - } - - if (auto *structTy = dyn_cast(combined.combinedTy)) { - for (auto *elem : structTy->elements()) { - components.push_back(elem); - } - } else { - components.push_back(combined.combinedTy); - } - addErrorResult(); - ResultIRType = llvm::StructType::get(IGM.getLLVMContext(), components); - return; - } - } - if (native.requiresIndirect() || native.empty()) { addErrorResult(); ResultIRType = llvm::StructType::get(IGM.getLLVMContext(), components); @@ -2361,6 +2289,7 @@ void SignatureExpansion::expandAsyncAwaitType() { }); addErrorResult(); + ResultIRType = llvm::StructType::get(IGM.getLLVMContext(), components); } @@ -3022,22 +2951,9 @@ class AsyncCallEmission final : public CallEmission { setIndirectTypedErrorResultSlotArgsIndex(--LastArgWritten); Args[LastArgWritten] = nullptr; } else { - auto silResultTy = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto silErrorTy = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - - auto &nativeSchema = - IGF.IGM.getTypeInfo(silResultTy).nativeReturnValueSchema(IGF.IGM); - auto &errorSchema = - IGF.IGM.getTypeInfo(silErrorTy).nativeReturnValueSchema(IGF.IGM); - - if (nativeSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - // Return the error indirectly. - auto buf = IGF.getCalleeTypedErrorResultSlot(silErrorTy); - Args[--LastArgWritten] = buf.getAddress(); - } + auto buf = IGF.getCalleeTypedErrorResultSlot( + fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext())); + Args[--LastArgWritten] = buf.getAddress(); } } @@ -3219,22 +3135,7 @@ class AsyncCallEmission final : public CallEmission { errorType = substConv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - - // Get the natural IR type in the body of the function that makes - // the call. This may be different than the IR type returned by the - // call itself due to ABI type coercion. - auto resultType = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &nativeSchema = - IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); - - bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly(); - if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect()) { - return emitToUnmappedExplosionWithDirectTypedError(resultType, result, - out); - } else if (resultTys.size() == 1) { + if (resultTys.size() == 1) { result = Builder.CreateExtractValue(result, numAsyncContextParams); if (hasError) { Address errorAddr = IGF.getCalleeErrorResultSlot(errorType, @@ -3266,6 +3167,17 @@ class AsyncCallEmission final : public CallEmission { result = resultAgg; } + SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), + IGF.getSILModule()); + + // Get the natural IR type in the body of the function that makes + // the call. This may be different than the IR type returned by the + // call itself due to ABI type coercion. + auto resultType = + fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); + auto &nativeSchema = + IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); + // For ABI reasons the result type of the call might not actually match the // expected result type. // @@ -3404,7 +3316,7 @@ void CallEmission::emitToUnmappedMemory(Address result) { #ifndef NDEBUG LastArgWritten = 0; // appease an assert #endif - + auto call = emitCallSite(); // Async calls need to store the error result that is passed as a parameter. @@ -4492,6 +4404,19 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError( extractScalarResults(IGF, result->getType(), result, nativeExplosion); auto values = nativeExplosion.claimAll(); + auto convertIfNecessary = [&](llvm::Type *nativeTy, + llvm::Value *elt) -> llvm::Value * { + auto *eltTy = elt->getType(); + if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && + nativeTy->getPrimitiveSizeInBits() != eltTy->getPrimitiveSizeInBits()) { + if (nativeTy->isPointerTy() && eltTy == IGF.IGM.IntPtrTy) { + return IGF.Builder.CreateIntToPtr(elt, nativeTy); + } + return IGF.Builder.CreateTruncOrBitCast(elt, nativeTy); + } + return elt; + }; + Explosion errorExplosion; if (!errorSchema.empty()) { if (auto *structTy = @@ -4499,14 +4424,12 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError( for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { llvm::Value *elt = values[combined.errorValueMapping[i]]; auto *nativeTy = structTy->getElementType(i); - elt = convertForAsyncDirect(IGF, elt, nativeTy, /*forExtraction*/ true); + elt = convertIfNecessary(nativeTy, elt); errorExplosion.add(elt); } } else { - auto *converted = - convertForAsyncDirect(IGF, values[combined.errorValueMapping[0]], - combined.combinedTy, /*forExtraction*/ true); - errorExplosion.add(converted); + errorExplosion.add(convertIfNecessary( + combined.combinedTy, values[combined.errorValueMapping[0]])); } typedErrorExplosion = @@ -4522,14 +4445,10 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError( dyn_cast(nativeSchema.getExpandedType(IGF.IGM))) { for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { auto *nativeTy = structTy->getElementType(i); - auto *converted = convertForAsyncDirect(IGF, values[i], nativeTy, - /*forExtraction*/ true); - resultExplosion.add(converted); + resultExplosion.add(convertIfNecessary(nativeTy, values[i])); } } else { - auto *converted = convertForAsyncDirect( - IGF, values[0], combined.combinedTy, /*forExtraction*/ true); - resultExplosion.add(converted); + resultExplosion.add(convertIfNecessary(combined.combinedTy, values[0])); } out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, resultType); } @@ -5395,33 +5314,6 @@ llvm::Value* IRGenFunction::coerceValue(llvm::Value *value, llvm::Type *toTy, return loaded; } -llvm::Value *irgen::convertForAsyncDirect(IRGenFunction &IGF, - llvm::Value *value, llvm::Type *toTy, - bool forExtraction) { - auto &Builder = IGF.Builder; - auto *fromTy = value->getType(); - if (toTy->isIntOrPtrTy() && fromTy->isIntOrPtrTy() && toTy != fromTy) { - - if (toTy->isPointerTy()) { - if (fromTy->isPointerTy()) - return Builder.CreateBitCast(value, toTy); - if (fromTy == IGF.IGM.IntPtrTy) - return Builder.CreateIntToPtr(value, toTy); - } else if (fromTy->isPointerTy()) { - if (toTy == IGF.IGM.IntPtrTy) { - return Builder.CreatePtrToInt(value, toTy); - } - } - - if (forExtraction) { - return Builder.CreateTruncOrBitCast(value, toTy); - } else { - return Builder.CreateZExtOrBitCast(value, toTy); - } - } - return value; -} - void IRGenFunction::emitScalarReturn(llvm::Type *resultType, Explosion &result) { if (result.empty()) { @@ -5863,18 +5755,32 @@ void IRGenFunction::emitScalarReturn(SILType returnResultType, return; } + auto convertIfNecessary = [&](llvm::Type *nativeTy, + llvm::Value *elt) -> llvm::Value * { + auto *eltTy = elt->getType(); + if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && + nativeTy->getPrimitiveSizeInBits() != + eltTy->getPrimitiveSizeInBits()) { + assert(nativeTy->getPrimitiveSizeInBits() > + eltTy->getPrimitiveSizeInBits()); + if (eltTy->isPointerTy()) { + return Builder.CreatePtrToInt(elt, nativeTy); + } + return Builder.CreateZExt(elt, nativeTy); + } + return elt; + }; + if (auto *structTy = dyn_cast(combinedTy)) { nativeAgg = llvm::UndefValue::get(combinedTy); for (unsigned i = 0, e = native.size(); i != e; ++i) { llvm::Value *elt = native.claimNext(); auto *nativeTy = structTy->getElementType(i); - elt = convertForAsyncDirect(*this, elt, nativeTy, - /*forExtraction*/ false); + elt = convertIfNecessary(nativeTy, elt); nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); } } else { - nativeAgg = convertForAsyncDirect(*this, native.claimNext(), combinedTy, - /*forExtraction*/ false); + nativeAgg = convertIfNecessary(combinedTy, native.claimNext()); } } @@ -6184,51 +6090,6 @@ void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout, SILFunctionConventions conv(fnType, IGF.getSILModule()); auto &nativeSchema = IGM.getTypeInfo(funcResultTypeInContext).nativeReturnValueSchema(IGM); - - if (fnType->hasErrorResult() && !conv.hasIndirectSILResults() && - !conv.hasIndirectSILErrorResults() && !nativeSchema.requiresIndirect() && - conv.isTypedError()) { - auto errorType = conv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - if (!nativeError.shouldReturnTypedErrorIndirectly()) { - assert(!error.empty() && "Direct error return must have error value"); - auto *combinedTy = - combineResultAndTypedErrorType(IGM, nativeSchema, nativeError) - .combinedTy; - - if (combinedTy->isVoidTy()) { - assert(result.empty() && "Unexpected result values"); - } else { - if (auto *structTy = dyn_cast(combinedTy)) { - llvm::Value *nativeAgg = llvm::UndefValue::get(structTy); - for (unsigned i = 0, e = result.size(); i != e; ++i) { - llvm::Value *elt = result.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForAsyncDirect(IGF, elt, nativeTy, - /*forExtraction*/ false); - nativeAgg = IGF.Builder.CreateInsertValue(nativeAgg, elt, i); - } - Explosion out; - IGF.emitAllExtractValues(nativeAgg, structTy, out); - while (!out.empty()) { - nativeResultsStorage.push_back(out.claimNext()); - } - } else { - auto *converted = convertForAsyncDirect( - IGF, result.claimNext(), combinedTy, /*forExtraction*/ false); - nativeResultsStorage.push_back(converted); - } - } - - nativeResultsStorage.push_back(error.claimNext()); - nativeResults = nativeResultsStorage; - - emitAsyncReturn(IGF, asyncLayout, fnType, nativeResults); - return; - } - } - if (result.empty() && !nativeSchema.empty()) { if (!nativeSchema.requiresIndirect()) // When we throw, we set the return values to undef. diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index e1e4a58f12da9..a912f14b39751 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -274,10 +274,6 @@ namespace irgen { void forwardAsyncCallResult(IRGenFunction &IGF, CanSILFunctionType fnType, AsyncContextLayout &layout, llvm::CallInst *call); - /// Converts a value for async direct errors. - llvm::Value *convertForAsyncDirect(IRGenFunction &IGF, llvm::Value *value, - llvm::Type *toTy, bool forExtraction); - } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 72e4c7c9e81f6..933e85a5c3bc9 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -1365,21 +1365,8 @@ class AsyncPartialApplicationForwarderEmission // The error result pointer is already in the appropriate position but the // type error address is not. if (origConv.isTypedError()) { - auto errorType = - origConv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto silResultTy = - origConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &resultTI = IGM.getTypeInfo(silResultTy); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - if (resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly() || - outConv.hasIndirectSILErrorResults()) { - auto *typedErrorResultPtr = origParams.claimNext(); - args.add(typedErrorResultPtr); - } + auto *typedErrorResultPtr = origParams.claimNext(); + args.add(typedErrorResultPtr); } } llvm::CallInst *createCall(FunctionPointer &fnPtr) override { @@ -2917,11 +2904,9 @@ IRGenFunction::createAsyncDispatchFn(const FunctionPointer &fnPtr, : originalAuthInfo; auto callee = FunctionPointer::createSigned( fnPtr.getKind(), fnPtrArg, newAuthInfo, fnPtr.getSignature()); - auto call = Builder.CreateCall(callee, callArgs); call->setTailCallKind(IGM.AsyncTailCallKind); Builder.CreateRetVoid(); - return dispatch; } diff --git a/lib/IRGen/GenThunk.cpp b/lib/IRGen/GenThunk.cpp index fe584375bf515..d31c3be9dadf8 100644 --- a/lib/IRGen/GenThunk.cpp +++ b/lib/IRGen/GenThunk.cpp @@ -152,7 +152,7 @@ void IRGenThunk::prepareArguments() { auto &resultTI = cast(IGF.getTypeInfo(resultType)); auto &resultSchema = resultTI.nativeReturnValueSchema(IGF.IGM); - if (resultSchema.requiresIndirect() || + if (isAsync || resultSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly()) { auto directTypedErrorAddr = original.takeLast(); IGF.setCalleeTypedErrorResultSlot(Address(directTypedErrorAddr, @@ -363,60 +363,16 @@ void IRGenThunk::emit() { IGF.Builder.CreateCondBr(hasError, errorBB, successBB); IGF.Builder.emitBlock(errorBB); - if (isAsync) { - auto &IGM = IGF.IGM; - SILType silErrorTy = conv.getSILErrorType(expansionContext); - auto &errorTI = IGF.IGM.getTypeInfo(silErrorTy); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGF.IGM); - auto combined = combineResultAndTypedErrorType(IGM, schema, errorSchema); - - Explosion errorArgValues; - - if (!combined.combinedTy->isVoidTy()) { - llvm::Value *expandedResult = - llvm::UndefValue::get(combined.combinedTy); - if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - auto nativeError = - errorSchema.mapIntoNative(IGM, IGF, *error, silErrorTy, false); - - if (auto *structTy = - dyn_cast(combined.combinedTy)) { - for (unsigned i : combined.errorValueMapping) { - llvm::Value *elt = nativeError.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForAsyncDirect(IGF, elt, nativeTy, - /*forExtraction*/ false); - expandedResult = - IGF.Builder.CreateInsertValue(expandedResult, elt, i); - } - IGF.emitAllExtractValues(expandedResult, structTy, errorArgValues); - } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - errorArgValues = convertForAsyncDirect(IGF, nativeError.claimNext(), - combined.combinedTy, - /*forExtraction*/ false); - } - } else if (auto *structTy = - dyn_cast(combined.combinedTy)) { - IGF.emitAllExtractValues(expandedResult, structTy, errorArgValues); - } else { - errorArgValues = expandedResult; - } - } - errorArgValues.add(errorValue); - emitAsyncReturn(IGF, *asyncLayout, origTy, errorArgValues.claimAll()); - } else { - IGF.emitScalarReturn(IGF.CurFn->getReturnType(), *error); - } + IGF.emitScalarReturn(IGF.CurFn->getReturnType(), *error); IGF.Builder.emitBlock(successBB); - } else { - if (isAsync) { - Explosion error; - if (errorValue) - error.add(errorValue); - emitAsyncReturn(IGF, *asyncLayout, directResultType, origTy, result, - error); - return; - } + } + + if (isAsync) { + Explosion error; + if (errorValue) + error.add(errorValue); + emitAsyncReturn(IGF, *asyncLayout, directResultType, origTy, result, error); + return; } // Return the result. @@ -431,6 +387,7 @@ void IRGenThunk::emit() { auto resultTy = conv.getSILResultType(expansionContext); resultTy = resultTy.subst(IGF.getSILModule(), subMap); + IGF.emitScalarReturn(resultTy, resultTy, result, /*swiftCCReturn=*/false, /*isOutlined=*/false); diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index b2931091f288f..48c5c9463d36a 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -2183,7 +2183,8 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, auto &errorTI = cast(IGF.getTypeInfo(inContextErrorType)); auto &native = resultTI.nativeReturnValueSchema(IGF.IGM); auto &nativeError = errorTI.nativeReturnValueSchema(IGF.IGM); - if (fnConv.hasIndirectSILResults() || native.requiresIndirect() || + if (funcTy->isAsync() || fnConv.hasIndirectSILResults() || + native.requiresIndirect() || nativeError.shouldReturnTypedErrorIndirectly()) { IGF.setCallerTypedErrorResultSlot( Address(emission->getCallerTypedErrorResultArgument(), @@ -3873,8 +3874,8 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { // See below. Builder.CreateStore(nullError, calleeErrorSlot); } - auto hasTypedDirectError = - substConv.isTypedError() && !substConv.hasIndirectSILErrorResults(); + auto hasTypedDirectError = substConv.isTypedError() && + !substConv.hasIndirectSILErrorResults(); llvm::BasicBlock *typedErrorLoadBB = nullptr; if (hasTypedDirectError) { typedErrorLoadBB = createBasicBlock("typed.error.load"); @@ -3925,7 +3926,7 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - if (substConv.hasIndirectSILResults() || + if (isAsync() || substConv.hasIndirectSILResults() || substConv.hasIndirectSILErrorResults() || resultSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly()) { @@ -4425,43 +4426,6 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { getSILModule()); assert(!conv.hasIndirectSILErrorResults()); - auto buildDirectError = [=](const CombinedResultAndErrorType &combined, - const NativeConventionSchema &errorSchema, - SILType silErrorTy, Explosion &errorResult, - bool forAsync, Explosion &out) { - if (combined.combinedTy->isVoidTy()) { - return; - } - - llvm::Value *expandedResult = llvm::UndefValue::get(combined.combinedTy); - - if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - auto nativeError = - errorSchema.mapIntoNative(IGM, *this, errorResult, silErrorTy, false); - - if (auto *structTy = dyn_cast(combined.combinedTy)) { - for (unsigned i : combined.errorValueMapping) { - llvm::Value *elt = nativeError.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertForAsyncDirect(*this, elt, nativeTy, - /*forExtraction*/ false); - expandedResult = Builder.CreateInsertValue(expandedResult, elt, i); - } - if (forAsync) { - emitAllExtractValues(expandedResult, structTy, out); - } else { - out = expandedResult; - } - } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - out = - convertForAsyncDirect(*this, nativeError.claimNext(), - combined.combinedTy, /*forExtraction*/ false); - } - } else { - out = expandedResult; - } - }; - if (!isAsync()) { auto fnTy = CurFn->getFunctionType(); auto retTy = fnTy->getReturnType(); @@ -4492,12 +4456,53 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { false); } else { auto combined = - combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - Explosion nativeAgg; - buildDirectError(combined, errorSchema, silErrorTy, errorResult, - /*forAsync*/ false, nativeAgg); + combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); + + if (combined.combinedTy->isVoidTy()) { + Builder.CreateRetVoid(); + return; + } + llvm::Value *expandedResult = llvm::UndefValue::get(combined.combinedTy); + + if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { + auto nativeError = errorSchema.mapIntoNative(IGM, *this, errorResult, + silErrorTy, false); + + auto convertIfNecessary = [&](llvm::Type *nativeTy, + llvm::Value *elt) -> llvm::Value * { + auto *eltTy = elt->getType(); + if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && + nativeTy->getPrimitiveSizeInBits() != + eltTy->getPrimitiveSizeInBits()) { + assert(nativeTy->getPrimitiveSizeInBits() > + eltTy->getPrimitiveSizeInBits()); + + if (eltTy->isPointerTy()) { + return elt = Builder.CreatePtrToInt(elt, nativeTy); + } + + return Builder.CreateZExt(elt, nativeTy); + } + return elt; + }; + + if (auto *structTy = dyn_cast(combined.combinedTy)) { + for (unsigned i : combined.errorValueMapping) { + llvm::Value *elt = nativeError.claimNext(); + auto *nativeTy = structTy->getElementType(i); + elt = convertIfNecessary(nativeTy, elt); + expandedResult = Builder.CreateInsertValue(expandedResult, elt, i); + } + } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { + expandedResult = + convertIfNecessary(combined.combinedTy, nativeError.claimNext()); + } + } + + Explosion nativeAgg = Explosion(expandedResult); emitScalarReturn(combined.combinedTy, nativeAgg); + return; } } @@ -4523,44 +4528,11 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { conv.getSILResultType(IGM.getMaximalTypeExpansionContext())); if (conv.isTypedError()) { - auto silErrorTy = - conv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = cast(IGM.getTypeInfo(silErrorTy)); - - auto silResultTy = - conv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &resultTI = cast(IGM.getTypeInfo(silResultTy)); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - + auto &ti = cast(IGM.getTypeInfo(conv.getSILErrorType( + IGM.getMaximalTypeExpansionContext()))); + ti.initialize(*this, exn, getCallerTypedErrorResultSlot(), false); llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1); flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy); - - if (conv.hasIndirectSILResults() || conv.hasIndirectSILErrorResults() || - resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - errorTI.initialize(*this, exn, getCallerTypedErrorResultSlot(), false); - } else { - Explosion nativeAgg; - auto combined = - combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - buildDirectError(combined, errorSchema, silErrorTy, exn, - /*forAsync*/ true, nativeAgg); - assert(exn.empty() && "Unclaimed typed error results"); - - SmallVector nativeResultArgs; - while (!nativeAgg.empty()) { - nativeResultArgs.push_back(nativeAgg.claimNext()); - } - nativeResultArgs.push_back(flag); - - emitAsyncReturn(*this, layout, - i->getFunction()->getLoweredFunctionType(), - nativeResultArgs); - - return; - } - assert(exn.empty() && "Unclaimed typed error results"); exn.reset(); exn.add(flag); diff --git a/test/IRGen/typed_throws.sil b/test/IRGen/typed_throws.sil index 3e5ca9cdc7c09..3049232584c3f 100644 --- a/test/IRGen/typed_throws.sil +++ b/test/IRGen/typed_throws.sil @@ -125,14 +125,13 @@ bb6: return %7 : $() } -// CHECK: define{{.*}} swifttailcc void @does_throw_async(ptr swiftasync %0) -// CHECK: [[ERR:%.*]] = call swiftcc ptr @create_error() -// CHECK: [[INS0:%.*]] = insertvalue { ptr, ptr } undef, ptr [[ERR]], 0 -// CHECK: [[INS1:%.*]] = insertvalue { ptr, ptr } [[INS0]], ptr [[ERR]], 1 -// CHECK: [[P0:%.*]] = extractvalue { ptr, ptr } [[INS1]], 0 -// CHECK: [[P1:%.*]] = extractvalue { ptr, ptr } [[INS1]], 1 -// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{%.*}}, i1 false, ptr @does_throw_async.0, ptr {{%.*}}, ptr {{%.*}}, ptr [[P0]], ptr [[P1]], ptr inttoptr (i64 1 to ptr)) -// CHECK: unreachable +// CHECK: define{{.*}} swifttailcc void @does_throw_async(ptr swiftasync %0, ptr %1) +// CHECK: %.x = getelementptr inbounds %T12typed_throws1SV, ptr %1, i32 0, i32 0 +// CHECK: store ptr {{.*}}, ptr %.x +// CHECK: %.y = getelementptr inbounds %T12typed_throws1SV, ptr %1, i32 0, i32 1 +// CHECK: store ptr {{.*}}, ptr %.y +// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{.*}}, i1 false, ptr @does_throw_async.0, ptr {{.*}}, ptr {{.*}}, ptr inttoptr (i64 1 to ptr)) +// CHECK: ret void sil @does_throw_async : $@convention(thin) @async () -> @error S { %0 = function_ref @create_error : $@convention(thin) () -> @owned A @@ -142,13 +141,10 @@ sil @does_throw_async : $@convention(thin) @async () -> @error S { throw %2 : $S } -// CHECK: define{{.*}} swifttailcc void @does_not_throw_async(ptr swiftasync %0) +// CHECK: define{{.*}} swifttailcc void @does_not_throw_async(ptr swiftasync %0, ptr %1) // CHECK: [[R:%.*]] = call swiftcc ptr @create_error() -// CHECK: [[CMB:%.*]] = insertvalue { ptr, ptr } undef, ptr [[R]], 0 -// CHECK: [[P0:%.*]] = extractvalue { ptr, ptr } [[CMB:%.*]], 0 -// CHECK: [[P1:%.*]] = extractvalue { ptr, ptr } [[CMB]], 1 -// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{.*}}, i1 false, ptr @does_not_throw_async.0, ptr {{.*}}, ptr {{.*}}, ptr [[P0]], ptr [[P1]], ptr null) -// CHECK: unreachable +// CHECK: call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr {{.*}}, i1 false, ptr @does_not_throw_async.0, ptr {{.*}}, ptr {{.*}}, ptr [[R]], ptr null) +// CHECK: ret void sil @does_not_throw_async : $@convention(thin) @async () -> (@owned A, @error S) { %0 = function_ref @create_error : $@convention(thin) () -> @owned A %1 = apply %0() : $@convention(thin) () -> @owned A @@ -220,8 +216,8 @@ entry(%0: $AnyObject): return %36 : $@callee_guaranteed () ->(@owned AnyObject, @error S) } -// CHECK: define{{.*}} internal swifttailcc void @"$s22try_apply_helper_asyncTA"(ptr swiftasync %0, ptr swiftself %1) -// CHECK: call { ptr, ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0p0s(i32 768, ptr {{.*}}, ptr @__swift_async_resume_project_context, ptr @"$s22try_apply_helper_asyncTA.0", ptr @try_apply_helper_async, ptr {{.*}}, ptr {{.*}}) +// CHECK: define{{.*}} internal swifttailcc void @"$s22try_apply_helper_asyncTA"(ptr swiftasync %0, ptr swiftself %1, ptr %2) +// CHECK: call { ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0s(i32 512, ptr {{.*}}, ptr @__swift_async_resume_project_context, ptr @"$s22try_apply_helper_asyncTA.0", ptr @try_apply_helper_async, ptr {{.*}}, ptr {{.*}}, ptr %2) sil @partial_apply_test_async : $@convention(thin) (@owned AnyObject) -> @owned @callee_guaranteed @async () ->(@owned AnyObject, @error S) { entry(%0: $AnyObject): @@ -254,7 +250,8 @@ bb6: } // CHECK: define{{.*}} swifttailcc void @apply_closure_async(ptr swiftasync %0, ptr %1, ptr %2) -// CHECK: call { ptr, ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0p0s(i32 768, ptr %{{[0-9]+}}, ptr @__swift_async_resume_project_context, ptr @apply_closure_async.0, ptr %{{[0-9]+}},{{( i64 [0-9]+,)?}} ptr %{{[0-9]+}}, ptr %2) +// CHECK: %swifterror = alloca %T12typed_throws1SV +// CHECK: call { ptr, ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0p0s(i32 512, ptr %{{[0-9]+}}, ptr @__swift_async_resume_project_context, ptr @apply_closure_async.0, ptr %{{[0-9]+}},{{( i64 [0-9]+,)?}} ptr %{{[0-9]+}}, ptr %2, ptr %swifterror) sil @apply_closure_async : $@convention(thin) @async (@guaranteed @callee_guaranteed @async () -> (@owned AnyObject, @error S)) -> () { entry(%0 : $@callee_guaranteed @async () ->(@owned AnyObject, @error S)): try_apply %0() : $@callee_guaranteed @async () -> (@owned AnyObject, @error S), normal bb4, error bb5 diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index af8af43dc7488..e27a953fee522 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -40,8 +40,8 @@ func buildMetatype() -> Any.Type { return Fn.self } -// // CHECK-NOMANGLE: define linkonce_odr hidden swiftcc %swift.metadata_response @"$sySi12typed_throws10MyBigErrorOYKcMa" -// // CHECK-NOMANGLE: @swift_getExtendedFunctionTypeMetadata({{.*}}@"$s12typed_throws10MyBigErrorOMf" +// CHECK-NOMANGLE: define linkonce_odr hidden swiftcc %swift.metadata_response @"$sySi12typed_throws10MyBigErrorOYKcMa" +// CHECK-NOMANGLE: @swift_getExtendedFunctionTypeMetadata({{.*}}@"$s12typed_throws10MyBigErrorOMf" protocol P { associatedtype A @@ -154,37 +154,3 @@ func genericThrows(x: Bool, y: T) throws(SmallError) -> T { return y } - -func throwsGeneric(x: Bool, y: T) throws(T) -> Int { - guard x else { - throw y - } - - return 32 -} - -@available(SwiftStdlib 6.0, *) -func mayThrowAsync(x: Bool, y: AnyObject) async throws(MyError) -> (Float, Int32, Float) { - guard x else { - throw MyError(x: y) - } - return (3.0, 4, 5.0) -} - -@available(SwiftStdlib 6.0, *) -func genericThrowsAsync(x: Bool, y: T) async throws(SmallError) -> T { - guard x else { - throw SmallError(x: 1) - } - - return y -} - -@available(SwiftStdlib 6.0, *) -func throwsGenericAsync(x: Bool, y: T) async throws(T) -> Int { - guard x else { - throw y - } - - return 32 -} diff --git a/test/IRGen/typed_throws_thunks.swift b/test/IRGen/typed_throws_thunks.swift index 5002cde9a4440..b38c5b8102334 100644 --- a/test/IRGen/typed_throws_thunks.swift +++ b/test/IRGen/typed_throws_thunks.swift @@ -34,9 +34,9 @@ extension P { } } - // CHECK-LABEL: define{{.*}} swifttailcc void @"$s19typed_throws_thunks1PP2g44bodyyyyAA9FixedSizeVYKXE_tYaAGYKFTj"(ptr swiftasync %0, ptr %1, ptr %2, ptr noalias swiftself %3, ptr %4, ptr %5) + // CHECK-LABEL: define{{.*}} swifttailcc void @"$s19typed_throws_thunks1PP2g44bodyyyyAA9FixedSizeVYKXE_tYaAGYKFTj"(ptr swiftasync %0, ptr %1, ptr %2, ptr noalias swiftself %3, ptr %4, ptr %5, ptr %6) // CHECK-NOT: ret - // CHECK: call { ptr, i64, i64, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0i64i64p0s({{.*}} ptr %1, ptr %2, ptr %3, ptr %4, ptr %5) + // CHECK: call { ptr, ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0p0s({{.*}} ptr %1, ptr %2, ptr %3, ptr %4, ptr %5, ptr %6) public func g4(body: () throws(FixedSize) -> Void) async throws(FixedSize) { do { return try await f(body: body) From 85c5648d6d13da72175204b8efd1666b75a3878f Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:23:15 -0700 Subject: [PATCH 08/13] Revert "Merge pull request #75150 from drexin/wip-130971168" This reverts commit 8fca31efde24320f21330f6429594601bb348a9b, reversing changes made to 32af2f6c194a6a7ab9343a83ed5531bd3809d06c. --- lib/IRGen/GenCall.cpp | 13 +++++-------- lib/IRGen/IRGenSIL.cpp | 11 ++++------- test/IRGen/typed_throws.swift | 10 ---------- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index abb7e1e99076a..0c5552f82df52 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -653,7 +653,7 @@ void SignatureExpansion::expandResult( const TypeInfo *directResultTypeInfo; std::tie(ResultIRType, directResultTypeInfo) = expandDirectResult(); - if (!fnConv.hasIndirectSILResults() && !fnConv.hasIndirectSILErrorResults()) { + if (!fnConv.hasIndirectSILErrorResults()) { llvm::Type *directErrorType; const TypeInfo *directErrorTypeInfo; std::tie(directErrorType, directErrorTypeInfo) = expandDirectErrorType(); @@ -2043,8 +2043,7 @@ void SignatureExpansion::expandParameters( auto &errorTI = IGM.getTypeInfo(errorType); auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - if (getSILFuncConventions().hasIndirectSILResults() || - getSILFuncConventions().hasIndirectSILErrorResults() || + if (getSILFuncConventions().hasIndirectSILErrorResults() || native.requiresIndirect() || nativeError.shouldReturnTypedErrorIndirectly()) { ParamIRTypes.push_back(IGM.getStorageType(errorType)->getPointerTo()); @@ -2607,8 +2606,7 @@ class SyncCallEmission final : public CallEmission { auto &errorSchema = IGF.IGM.getTypeInfo(silErrorTy).nativeReturnValueSchema(IGF.IGM); - if (fnConv.hasIndirectSILResults() || - nativeSchema.requiresIndirect() || + if (nativeSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly()) { // Return the error indirectly. auto buf = IGF.getCalleeTypedErrorResultSlot(silErrorTy); @@ -4367,9 +4365,8 @@ bool CallEmission::mayReturnTypedErrorDirectly() const { SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), IGF.getSILModule()); bool mayReturnErrorDirectly = false; - if (!convertDirectToIndirectReturn && !fnConv.hasIndirectSILResults() && - !fnConv.hasIndirectSILErrorResults() && fnConv.funcTy->hasErrorResult() && - fnConv.isTypedError()) { + if (!convertDirectToIndirectReturn && !fnConv.hasIndirectSILErrorResults() && + fnConv.funcTy->hasErrorResult() && fnConv.isTypedError()) { auto errorType = fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); auto &errorSchema = diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 48c5c9463d36a..efa89fa42c485 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -2183,8 +2183,7 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, auto &errorTI = cast(IGF.getTypeInfo(inContextErrorType)); auto &native = resultTI.nativeReturnValueSchema(IGF.IGM); auto &nativeError = errorTI.nativeReturnValueSchema(IGF.IGM); - if (funcTy->isAsync() || fnConv.hasIndirectSILResults() || - native.requiresIndirect() || + if (funcTy->isAsync() || native.requiresIndirect() || nativeError.shouldReturnTypedErrorIndirectly()) { IGF.setCallerTypedErrorResultSlot( Address(emission->getCallerTypedErrorResultArgument(), @@ -3926,8 +3925,7 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - if (isAsync() || substConv.hasIndirectSILResults() || - substConv.hasIndirectSILErrorResults() || + if (isAsync() || substConv.hasIndirectSILErrorResults() || resultSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly()) { Explosion errorValue; @@ -4394,7 +4392,7 @@ static void emitReturnInst(IRGenSILFunction &IGF, funcLang == SILFunctionLanguage::C && "Need to handle all cases"); SILType errorType; if (fnType->hasErrorResult() && conv.isTypedError() && - !conv.hasIndirectSILResults() && !conv.hasIndirectSILErrorResults()) { + !conv.hasIndirectSILErrorResults()) { errorType = conv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); } @@ -4449,8 +4447,7 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); Builder.CreateStore(flag, getCallerErrorResultSlot()); - if (conv.hasIndirectSILResults() || conv.hasIndirectSILErrorResults() || - resultSchema.requiresIndirect() || + if (resultSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly()) { errorTI.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), false); diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index e27a953fee522..bf898ad2752ba 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -144,13 +144,3 @@ func directErrorMergePtrAndInt(x: Bool, y: AnyObject) throws(SmallError) -> (Any return try directErrorMergePtrAndInt(x: !x, y: y) } - -// This used to crash at compile time, because it was trying to use a direct -// error return in combination with an indirect result, which is illegal. -func genericThrows(x: Bool, y: T) throws(SmallError) -> T { - guard x else { - throw SmallError(x: 1) - } - - return y -} From 790c2692d498813cd767cad51128d6c5aa3c2f51 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:23:42 -0700 Subject: [PATCH 09/13] Revert "Merge pull request #75149 from drexin/wip-ptr-cast-tt" This reverts commit 32af2f6c194a6a7ab9343a83ed5531bd3809d06c, reversing changes made to d84a9190a246810823cb29f57c791280d30c1c9a. --- lib/IRGen/GenCall.cpp | 3 --- test/IRGen/typed_throws.swift | 13 ------------- 2 files changed, 16 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 0c5552f82df52..ceaecb4f8c4cf 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -4406,9 +4406,6 @@ void CallEmission::emitToUnmappedExplosionWithDirectTypedError( auto *eltTy = elt->getType(); if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && nativeTy->getPrimitiveSizeInBits() != eltTy->getPrimitiveSizeInBits()) { - if (nativeTy->isPointerTy() && eltTy == IGF.IGM.IntPtrTy) { - return IGF.Builder.CreateIntToPtr(elt, nativeTy); - } return IGF.Builder.CreateTruncOrBitCast(elt, nativeTy); } return elt; diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index bf898ad2752ba..b35083813d4ed 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -131,16 +131,3 @@ func mayThrow(x: Bool, y: AnyObject) throws(MyError) -> (Float, Int32, Float) { } return (3.0, 4, 5.0) } - -// CHECK: define hidden swiftcc { i64, i64 } @"$s12typed_throws25directErrorMergePtrAndInt1x1yyXl_SitSb_yXltAA05SmallD0VYKF" -// CHECK: [[RES:%.*]] = call swiftcc { i64, i64 } @"$s12typed_throws25directErrorMergePtrAndInt1x1yyXl_SitSb_yXltAA05SmallD0VYKF" -// CHECK: [[R0:%.*]] = extractvalue { i64, i64 } [[RES]], 0 -// CHECK: inttoptr i64 [[R0]] to ptr -// CHECK: } -func directErrorMergePtrAndInt(x: Bool, y: AnyObject) throws(SmallError) -> (AnyObject, Int) { - guard x else { - throw SmallError(x: 1) - } - - return try directErrorMergePtrAndInt(x: !x, y: y) -} From 25bc3875faf86f748d5fac2b10e1707a7644f8a4 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:24:10 -0700 Subject: [PATCH 10/13] Revert "Merge pull request #75072 from drexin/wip-refactor-te-callemission" This reverts commit 22b6319c71c3149ed9fa5c18d85f7ea4acb64855, reversing changes made to 4e4d547825e13804fb84e922e51375efbc1dc98f. --- lib/IRGen/CallEmission.h | 5 -- lib/IRGen/GenCall.cpp | 167 ++++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 95 deletions(-) diff --git a/lib/IRGen/CallEmission.h b/lib/IRGen/CallEmission.h index 6c615db50be2d..fbdff0893e9dd 100644 --- a/lib/IRGen/CallEmission.h +++ b/lib/IRGen/CallEmission.h @@ -110,11 +110,6 @@ class CallEmission { TemporarySet &temporaries, bool isOutlined); - bool mayReturnTypedErrorDirectly() const; - void emitToUnmappedExplosionWithDirectTypedError(SILType resultType, - llvm::Value *result, - Explosion &out); - CallEmission(IRGenFunction &IGF, llvm::Value *selfValue, Callee &&callee) : IGF(IGF), selfValue(selfValue), CurCallee(std::move(callee)) {} diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index ceaecb4f8c4cf..d403e8edc04ca 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -2756,7 +2756,17 @@ class SyncCallEmission final : public CallEmission { Explosion &out) override { SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), IGF.getSILModule()); - bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly(); + bool mayReturnErrorDirectly = false; + if (!convertDirectToIndirectReturn && + !fnConv.hasIndirectSILErrorResults() && + fnConv.funcTy->hasErrorResult() && fnConv.isTypedError()) { + auto errorType = + fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); + auto &errorSchema = + IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); + + mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly(); + } // Bail out immediately on a void result. llvm::Value *result = call; @@ -2803,8 +2813,72 @@ class SyncCallEmission final : public CallEmission { // Handle direct return of typed errors if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect()) { - return emitToUnmappedExplosionWithDirectTypedError(resultType, result, - out); + auto errorType = + fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); + auto &errorSchema = + IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); + + auto combined = + combineResultAndTypedErrorType(IGF.IGM, nativeSchema, errorSchema); + + if (combined.combinedTy->isVoidTy()) { + typedErrorExplosion = Explosion(); + return; + } + + Explosion nativeExplosion; + extractScalarResults(IGF, result->getType(), result, nativeExplosion); + auto values = nativeExplosion.claimAll(); + + auto convertIfNecessary = [&](llvm::Type *nativeTy, + llvm::Value *elt) -> llvm::Value * { + auto *eltTy = elt->getType(); + if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && + nativeTy->getPrimitiveSizeInBits() != + eltTy->getPrimitiveSizeInBits()) { + return IGF.Builder.CreateTruncOrBitCast(elt, nativeTy); + } + return elt; + }; + + Explosion errorExplosion; + if (!errorSchema.empty()) { + if (auto *structTy = dyn_cast( + errorSchema.getExpandedType(IGF.IGM))) { + for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { + llvm::Value *elt = values[combined.errorValueMapping[i]]; + auto *nativeTy = structTy->getElementType(i); + elt = convertIfNecessary(nativeTy, elt); + errorExplosion.add(elt); + } + } else { + errorExplosion.add(convertIfNecessary( + combined.combinedTy, values[combined.errorValueMapping[0]])); + } + + typedErrorExplosion = + errorSchema.mapFromNative(IGF.IGM, IGF, errorExplosion, errorType); + } else { + typedErrorExplosion = std::move(errorExplosion); + } + + // If the regular result type is void, there is nothing to explode + if (!resultType.isVoid()) { + Explosion resultExplosion; + if (auto *structTy = dyn_cast( + nativeSchema.getExpandedType(IGF.IGM))) { + for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { + auto *nativeTy = structTy->getElementType(i); + resultExplosion.add(convertIfNecessary(nativeTy, values[i])); + } + } else { + resultExplosion.add( + convertIfNecessary(combined.combinedTy, values[0])); + } + out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, + resultType); + } + return; } if (result->getType()->isVoidTy()) @@ -4361,93 +4435,6 @@ void CallEmission::externalizeArguments(IRGenFunction &IGF, const Callee &callee } } -bool CallEmission::mayReturnTypedErrorDirectly() const { - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - bool mayReturnErrorDirectly = false; - if (!convertDirectToIndirectReturn && !fnConv.hasIndirectSILErrorResults() && - fnConv.funcTy->hasErrorResult() && fnConv.isTypedError()) { - auto errorType = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &errorSchema = - IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); - - mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly(); - } - - return mayReturnErrorDirectly; -} - -void CallEmission::emitToUnmappedExplosionWithDirectTypedError( - SILType resultType, llvm::Value *result, Explosion &out) { - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - auto &nativeSchema = - IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); - auto errorType = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &errorSchema = - IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); - - auto combined = - combineResultAndTypedErrorType(IGF.IGM, nativeSchema, errorSchema); - - if (combined.combinedTy->isVoidTy()) { - typedErrorExplosion = Explosion(); - return; - } - - Explosion nativeExplosion; - extractScalarResults(IGF, result->getType(), result, nativeExplosion); - auto values = nativeExplosion.claimAll(); - - auto convertIfNecessary = [&](llvm::Type *nativeTy, - llvm::Value *elt) -> llvm::Value * { - auto *eltTy = elt->getType(); - if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && - nativeTy->getPrimitiveSizeInBits() != eltTy->getPrimitiveSizeInBits()) { - return IGF.Builder.CreateTruncOrBitCast(elt, nativeTy); - } - return elt; - }; - - Explosion errorExplosion; - if (!errorSchema.empty()) { - if (auto *structTy = - dyn_cast(errorSchema.getExpandedType(IGF.IGM))) { - for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { - llvm::Value *elt = values[combined.errorValueMapping[i]]; - auto *nativeTy = structTy->getElementType(i); - elt = convertIfNecessary(nativeTy, elt); - errorExplosion.add(elt); - } - } else { - errorExplosion.add(convertIfNecessary( - combined.combinedTy, values[combined.errorValueMapping[0]])); - } - - typedErrorExplosion = - errorSchema.mapFromNative(IGF.IGM, IGF, errorExplosion, errorType); - } else { - typedErrorExplosion = std::move(errorExplosion); - } - - // If the regular result type is void, there is nothing to explode - if (!resultType.isVoid()) { - Explosion resultExplosion; - if (auto *structTy = - dyn_cast(nativeSchema.getExpandedType(IGF.IGM))) { - for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { - auto *nativeTy = structTy->getElementType(i); - resultExplosion.add(convertIfNecessary(nativeTy, values[i])); - } - } else { - resultExplosion.add(convertIfNecessary(combined.combinedTy, values[0])); - } - out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, resultType); - } -} - void CallEmission::setKeyPathAccessorArguments(Explosion &in, bool isOutlined, Explosion &out) { auto origCalleeType = CurCallee.getOrigFunctionType(); From 9b10362a090aa00c46947b0564f10d25042831e6 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:35:32 -0700 Subject: [PATCH 11/13] Revert "Merge pull request #74840 from drexin/wip-130781414" This reverts commit 7feb5927dbb169935893fc7ec108499e0eaf74a2, reversing changes made to 4edda08d26601536b0607dc86ba8681c0b238367. --- lib/IRGen/GenCall.cpp | 16 ++++------------ lib/IRGen/IRGenSIL.cpp | 5 ----- test/IRGen/typed_throws.swift | 16 ---------------- 3 files changed, 4 insertions(+), 33 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index d403e8edc04ca..4eff5ac64f86a 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -416,13 +416,10 @@ CombinedResultAndErrorType irgen::combineResultAndTypedErrorType( assert(error->isIntOrPtrTy() && "Direct errors must only consist of int or ptr values"); result.errorValueMapping.push_back(combined.size()); - - if (res == error) { + if (res->getPrimitiveSizeInBits() >= error->getPrimitiveSizeInBits()) { combined.push_back(res); } else { - auto maxSize = std::max(IGM.DataLayout.getTypeSizeInBits(res), - IGM.DataLayout.getTypeSizeInBits(error)); - combined.push_back(llvm::IntegerType::get(IGM.getLLVMContext(), maxSize)); + combined.push_back(error); } ++resIt; @@ -2868,12 +2865,10 @@ class SyncCallEmission final : public CallEmission { if (auto *structTy = dyn_cast( nativeSchema.getExpandedType(IGF.IGM))) { for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { - auto *nativeTy = structTy->getElementType(i); - resultExplosion.add(convertIfNecessary(nativeTy, values[i])); + resultExplosion.add(values[i]); } } else { - resultExplosion.add( - convertIfNecessary(combined.combinedTy, values[0])); + resultExplosion.add(values[0]); } out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, resultType); @@ -5744,9 +5739,6 @@ void IRGenFunction::emitScalarReturn(SILType returnResultType, eltTy->getPrimitiveSizeInBits()) { assert(nativeTy->getPrimitiveSizeInBits() > eltTy->getPrimitiveSizeInBits()); - if (eltTy->isPointerTy()) { - return Builder.CreatePtrToInt(elt, nativeTy); - } return Builder.CreateZExt(elt, nativeTy); } return elt; diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index efa89fa42c485..86b09befd7ed3 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -4474,11 +4474,6 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { eltTy->getPrimitiveSizeInBits()) { assert(nativeTy->getPrimitiveSizeInBits() > eltTy->getPrimitiveSizeInBits()); - - if (eltTy->isPointerTy()) { - return elt = Builder.CreatePtrToInt(elt, nativeTy); - } - return Builder.CreateZExt(elt, nativeTy); } return elt; diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index b35083813d4ed..5b499d396e711 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -115,19 +115,3 @@ func catchesSmallError() -> Int { return error.x } } - -struct MyError: Error { - let x: AnyObject -} - -// CHECK: define hidden swiftcc { float, i64, float } @"$s12typed_throws8mayThrow1x1ySf_s5Int32VSftSb_yXltAA7MyErrorVYKF" -// CHECK: [[CONVERTED:%.*]] = ptrtoint ptr {{%.*}} to i64 -// CHECK: insertvalue { float, i64, float } undef, i64 [[CONVERTED]], 1 -// CHECK: } -@inline(never) -func mayThrow(x: Bool, y: AnyObject) throws(MyError) -> (Float, Int32, Float) { - guard x else { - throw MyError(x: y) - } - return (3.0, 4, 5.0) -} From 7955ba9fc6c0a4d07d310e7868c5521b04336dc8 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:37:01 -0700 Subject: [PATCH 12/13] Revert "Merge pull request #74839 from drexin/wip-130783369" This reverts commit 4edda08d26601536b0607dc86ba8681c0b238367, reversing changes made to ac5763bb50698dc681739733ac2ec4984b9a197d. --- lib/IRGen/GenCall.cpp | 3 +-- test/IRGen/typed_throws.swift | 23 ----------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 4eff5ac64f86a..b750759b082d7 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -2849,8 +2849,7 @@ class SyncCallEmission final : public CallEmission { errorExplosion.add(elt); } } else { - errorExplosion.add(convertIfNecessary( - combined.combinedTy, values[combined.errorValueMapping[0]])); + errorExplosion.add(convertIfNecessary(combined.combinedTy, values[0])); } typedErrorExplosion = diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index 5b499d396e711..7bd4e3ae02e2e 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -92,26 +92,3 @@ func testit() throws (S) { public struct TypeH { public var method: (Int) throws(MyBigError) -> String } - -struct SmallError: Error { - let x: Int -} - -@inline(never) -func throwsSmallError() throws(SmallError) -> (Float, Int) { - throw SmallError(x: 1) -} - -// CHECK: define hidden swiftcc i64 @"$s12typed_throws17catchesSmallErrorSiyF"() -// CHECK: [[RES:%.*]] = call swiftcc { float, i64 } @"$s12typed_throws0B10SmallErrorSf_SityAA0cD0VYKF"(ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable(8) %swifterror) -// CHECK: [[R0:%.*]] = extractvalue { float, i64 } [[RES]], 0 -// CHECK: [[R1:%.*]] = extractvalue { float, i64 } [[RES]], 1 -// CHECK: phi i64 [ [[R1]], %typed.error.load ] -// CHECK: } -func catchesSmallError() -> Int { - do { - return try throwsSmallError().1 - } catch { - return error.x - } -} From c9c45a1e538ef24b2b5b05cb41241936db2c5dae Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 12 Sep 2024 11:42:01 -0700 Subject: [PATCH 13/13] Revert "Merge pull request #74192 from drexin/wip-typed-throws-abi" This reverts commit 35b2b71475a996b65165c8118c480f1fe103066f, reversing changes made to c3b57f24eb35ff97a58262ffef2629d2020f0263. --- lib/IRGen/CallEmission.h | 6 - lib/IRGen/GenCall.cpp | 344 +++------------------------ lib/IRGen/GenCall.h | 9 - lib/IRGen/GenFunc.cpp | 15 +- lib/IRGen/GenThunk.cpp | 49 +--- lib/IRGen/IRGenFunction.h | 2 +- lib/IRGen/IRGenSIL.cpp | 147 ++---------- lib/IRGen/NativeConventionSchema.h | 3 - test/IRGen/typed_throws.sil | 34 +-- test/IRGen/typed_throws.swift | 7 +- test/IRGen/typed_throws_thunks.swift | 4 +- 11 files changed, 91 insertions(+), 529 deletions(-) diff --git a/lib/IRGen/CallEmission.h b/lib/IRGen/CallEmission.h index fbdff0893e9dd..5f189f4c4c705 100644 --- a/lib/IRGen/CallEmission.h +++ b/lib/IRGen/CallEmission.h @@ -19,7 +19,6 @@ #include "Address.h" #include "Callee.h" -#include "Explosion.h" #include "Temporary.h" namespace llvm { @@ -89,7 +88,6 @@ class CallEmission { unsigned IndirectTypedErrorArgIdx = 0; - std::optional typedErrorExplosion; virtual void setFromCallee(); void emitToUnmappedMemory(Address addr); @@ -125,10 +123,6 @@ class CallEmission { return CurCallee.getSubstitutions(); } - std::optional &getTypedErrorExplosion() { - return typedErrorExplosion; - } - virtual void begin(); virtual void end(); virtual SILType getParameterType(unsigned index) = 0; diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index b750759b082d7..89bf71cdccb93 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -377,78 +377,6 @@ static void addIndirectResultAttributes(IRGenModule &IGM, attrs = attrs.addParamAttributes(IGM.getLLVMContext(), paramIndex, b); } -// This function should only be called with directly returnable -// result and error types. Errors can only be returned directly if -// they consists solely of int and ptr values. -CombinedResultAndErrorType irgen::combineResultAndTypedErrorType( - const IRGenModule &IGM, const NativeConventionSchema &resultSchema, - const NativeConventionSchema &errorSchema) { - assert(!resultSchema.requiresIndirect()); - assert(!errorSchema.shouldReturnTypedErrorIndirectly()); - - CombinedResultAndErrorType result; - SmallVector elts; - resultSchema.enumerateComponents( - [&](clang::CharUnits offset, clang::CharUnits end, llvm::Type *type) { - elts.push_back(type); - }); - - SmallVector errorElts; - errorSchema.enumerateComponents( - [&](clang::CharUnits offset, clang::CharUnits end, llvm::Type *type) { - errorElts.push_back(type); - }); - - llvm::SmallVector combined; - - auto resIt = elts.begin(); - auto errorIt = errorElts.begin(); - - while (resIt < elts.end() && errorIt < errorElts.end()) { - auto *res = *resIt; - if (!res->isIntOrPtrTy()) { - combined.push_back(res); - ++resIt; - continue; - } - - auto *error = *errorIt; - assert(error->isIntOrPtrTy() && - "Direct errors must only consist of int or ptr values"); - result.errorValueMapping.push_back(combined.size()); - if (res->getPrimitiveSizeInBits() >= error->getPrimitiveSizeInBits()) { - combined.push_back(res); - } else { - combined.push_back(error); - } - - ++resIt; - ++errorIt; - } - - while (resIt < elts.end()) { - combined.push_back(*resIt); - ++resIt; - } - - while (errorIt < errorElts.end()) { - result.errorValueMapping.push_back(combined.size()); - combined.push_back(*errorIt); - ++errorIt; - } - - if (combined.empty()) { - result.combinedTy = llvm::Type::getVoidTy(IGM.getLLVMContext()); - } else if (combined.size() == 1) { - result.combinedTy = combined[0]; - } else { - result.combinedTy = - llvm::StructType::get(IGM.getLLVMContext(), combined, /*packed*/ false); - } - - return result; -} - void IRGenModule::addSwiftAsyncContextAttributes(llvm::AttributeList &attrs, unsigned argIndex) { llvm::AttrBuilder b(getLLVMContext()); @@ -595,7 +523,6 @@ namespace { /// the direct result of this function. If the result is passed indirectly, /// a void type is returned instead, with a \c null type info. std::pair expandDirectResult(); - std::pair expandDirectErrorType(); void expandIndirectResults(); void expandParameters(SignatureExpansionABIDetails *recordedABIDetails); void expandKeyPathAccessorParameters(); @@ -650,17 +577,6 @@ void SignatureExpansion::expandResult( const TypeInfo *directResultTypeInfo; std::tie(ResultIRType, directResultTypeInfo) = expandDirectResult(); - if (!fnConv.hasIndirectSILErrorResults()) { - llvm::Type *directErrorType; - const TypeInfo *directErrorTypeInfo; - std::tie(directErrorType, directErrorTypeInfo) = expandDirectErrorType(); - if ((directResultTypeInfo || ResultIRType->isVoidTy()) && - directErrorTypeInfo) { - ResultIRType = directErrorType; - directResultTypeInfo = directErrorTypeInfo; - } - } - // Expand the indirect results. expandIndirectResults(); @@ -892,8 +808,9 @@ llvm::Type *NativeConventionSchema::getExpandedType(IRGenModule &IGM) const { if (empty()) return IGM.VoidTy; SmallVector elts; - enumerateComponents([&](clang::CharUnits offset, clang::CharUnits end, - llvm::Type *type) { elts.push_back(type); }); + Lowering.enumerateComponents([&](clang::CharUnits offset, + clang::CharUnits end, + llvm::Type *type) { elts.push_back(type); }); if (elts.size() == 1) return elts[0]; @@ -917,7 +834,7 @@ NativeConventionSchema::getCoercionTypes( unsigned idx = 0; // Mark overlapping ranges. - enumerateComponents( + Lowering.enumerateComponents( [&](clang::CharUnits offset, clang::CharUnits end, llvm::Type *type) { if (offset < lastEnd) { overlappedWithSuccessor.insert(idx); @@ -932,7 +849,7 @@ NativeConventionSchema::getCoercionTypes( lastEnd = clang::CharUnits::Zero(); SmallVector elts; bool packed = false; - enumerateComponents( + Lowering.enumerateComponents( [&](clang::CharUnits begin, clang::CharUnits end, llvm::Type *type) { bool overlapped = overlappedWithSuccessor.count(idx) || (idx && overlappedWithSuccessor.count(idx - 1)); @@ -972,7 +889,7 @@ NativeConventionSchema::getCoercionTypes( lastEnd = clang::CharUnits::Zero(); elts.clear(); packed = false; - enumerateComponents( + Lowering.enumerateComponents( [&](clang::CharUnits begin, clang::CharUnits end, llvm::Type *type) { bool overlapped = overlappedWithSuccessor.count(idx) || (idx && overlappedWithSuccessor.count(idx - 1)); @@ -1037,38 +954,6 @@ SignatureExpansion::expandDirectResult() { llvm_unreachable("Not a valid SILFunctionLanguage."); } -std::pair -SignatureExpansion::expandDirectErrorType() { - if (!getSILFuncConventions().funcTy->hasErrorResult() || - !getSILFuncConventions().isTypedError()) { - return std::make_pair(nullptr, nullptr); - } - - switch (FnType->getLanguage()) { - case SILFunctionLanguage::C: - llvm_unreachable("Expanding C/ObjC parameters in the wrong place!"); - break; - case SILFunctionLanguage::Swift: { - auto resultType = getSILFuncConventions().getSILResultType( - IGM.getMaximalTypeExpansionContext()); - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - const auto &ti = IGM.getTypeInfo(resultType); - auto &native = ti.nativeReturnValueSchema(IGM); - const auto &errorTI = IGM.getTypeInfo(errorType); - auto &errorNative = errorTI.nativeReturnValueSchema(IGM); - if (native.requiresIndirect() || - errorNative.shouldReturnTypedErrorIndirectly()) { - return std::make_pair(nullptr, nullptr); - } - - auto combined = combineResultAndTypedErrorType(IGM, native, errorNative); - - return std::make_pair(combined.combinedTy, &errorTI); - } - } -} - static const clang::FieldDecl * getLargestUnionField(const clang::RecordDecl *record, const clang::ASTContext &ctx) { @@ -2030,21 +1915,10 @@ void SignatureExpansion::expandParameters( if (recordedABIDetails) recordedABIDetails->hasErrorResult = true; if (getSILFuncConventions().isTypedError()) { - - auto resultType = getSILFuncConventions().getSILResultType( - IGM.getMaximalTypeExpansionContext()); - auto &resultTI = IGM.getTypeInfo(resultType); - auto &native = resultTI.nativeReturnValueSchema(IGM); - auto errorType = getSILFuncConventions().getSILErrorType( - IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - - if (getSILFuncConventions().hasIndirectSILErrorResults() || - native.requiresIndirect() || - nativeError.shouldReturnTypedErrorIndirectly()) { - ParamIRTypes.push_back(IGM.getStorageType(errorType)->getPointerTo()); - } + ParamIRTypes.push_back( + IGM.getStorageType(getSILFuncConventions().getSILType( + FnType->getErrorResult(), IGM.getMaximalTypeExpansionContext()) + )->getPointerTo()); } } @@ -2593,22 +2467,10 @@ class SyncCallEmission final : public CallEmission { setIndirectTypedErrorResultSlotArgsIndex(--LastArgWritten); Args[LastArgWritten] = nullptr; } else { - auto silResultTy = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto silErrorTy = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - - auto &nativeSchema = - IGF.IGM.getTypeInfo(silResultTy).nativeReturnValueSchema(IGF.IGM); - auto &errorSchema = - IGF.IGM.getTypeInfo(silErrorTy).nativeReturnValueSchema(IGF.IGM); - - if (nativeSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - // Return the error indirectly. - auto buf = IGF.getCalleeTypedErrorResultSlot(silErrorTy); - Args[--LastArgWritten] = buf.getAddress(); - } + // Return the error indirectly. + auto buf = IGF.getCalleeTypedErrorResultSlot( + fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext())); + Args[--LastArgWritten] = buf.getAddress(); } } Args[--LastArgWritten] = errorResultSlot.getAddress(); @@ -2751,25 +2613,14 @@ class SyncCallEmission final : public CallEmission { } void emitCallToUnmappedExplosion(llvm::CallBase *call, Explosion &out) override { - SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), - IGF.getSILModule()); - bool mayReturnErrorDirectly = false; - if (!convertDirectToIndirectReturn && - !fnConv.hasIndirectSILErrorResults() && - fnConv.funcTy->hasErrorResult() && fnConv.isTypedError()) { - auto errorType = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &errorSchema = - IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); - - mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly(); - } - // Bail out immediately on a void result. llvm::Value *result = call; - if (result->getType()->isVoidTy() && !mayReturnErrorDirectly) + if (result->getType()->isVoidTy()) return; + SILFunctionConventions fnConv(getCallee().getOrigFunctionType(), + IGF.getSILModule()); + // If the result was returned autoreleased, implicitly insert the reclaim. // This is only allowed on a single direct result. if (fnConv.getNumDirectSILResults() == 1 @@ -2808,76 +2659,6 @@ class SyncCallEmission final : public CallEmission { auto &nativeSchema = IGF.IGM.getTypeInfo(resultType).nativeReturnValueSchema(IGF.IGM); - // Handle direct return of typed errors - if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect()) { - auto errorType = - fnConv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &errorSchema = - IGF.IGM.getTypeInfo(errorType).nativeReturnValueSchema(IGF.IGM); - - auto combined = - combineResultAndTypedErrorType(IGF.IGM, nativeSchema, errorSchema); - - if (combined.combinedTy->isVoidTy()) { - typedErrorExplosion = Explosion(); - return; - } - - Explosion nativeExplosion; - extractScalarResults(IGF, result->getType(), result, nativeExplosion); - auto values = nativeExplosion.claimAll(); - - auto convertIfNecessary = [&](llvm::Type *nativeTy, - llvm::Value *elt) -> llvm::Value * { - auto *eltTy = elt->getType(); - if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && - nativeTy->getPrimitiveSizeInBits() != - eltTy->getPrimitiveSizeInBits()) { - return IGF.Builder.CreateTruncOrBitCast(elt, nativeTy); - } - return elt; - }; - - Explosion errorExplosion; - if (!errorSchema.empty()) { - if (auto *structTy = dyn_cast( - errorSchema.getExpandedType(IGF.IGM))) { - for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { - llvm::Value *elt = values[combined.errorValueMapping[i]]; - auto *nativeTy = structTy->getElementType(i); - elt = convertIfNecessary(nativeTy, elt); - errorExplosion.add(elt); - } - } else { - errorExplosion.add(convertIfNecessary(combined.combinedTy, values[0])); - } - - typedErrorExplosion = - errorSchema.mapFromNative(IGF.IGM, IGF, errorExplosion, errorType); - } else { - typedErrorExplosion = std::move(errorExplosion); - } - - // If the regular result type is void, there is nothing to explode - if (!resultType.isVoid()) { - Explosion resultExplosion; - if (auto *structTy = dyn_cast( - nativeSchema.getExpandedType(IGF.IGM))) { - for (unsigned i = 0, e = structTy->getNumElements(); i < e; ++i) { - resultExplosion.add(values[i]); - } - } else { - resultExplosion.add(values[0]); - } - out = nativeSchema.mapFromNative(IGF.IGM, IGF, resultExplosion, - resultType); - } - return; - } - - if (result->getType()->isVoidTy()) - return; - // For ABI reasons the result type of the call might not actually match the // expected result type. // @@ -5340,8 +5121,9 @@ unsigned NativeConventionSchema::size() const { if (empty()) return 0; unsigned size = 0; - enumerateComponents([&](clang::CharUnits offset, clang::CharUnits end, - llvm::Type *type) { ++size; }); + Lowering.enumerateComponents([&](clang::CharUnits offset, + clang::CharUnits end, + llvm::Type *type) { ++size; }); return size; } @@ -5683,16 +5465,8 @@ Explosion IRGenFunction::coerceValueTo(SILType fromTy, Explosion &from, void IRGenFunction::emitScalarReturn(SILType returnResultType, SILType funcResultType, Explosion &result, - bool isSwiftCCReturn, bool isOutlined, - SILType errorType) { - bool mayReturnErrorDirectly = false; - if (errorType) { - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - mayReturnErrorDirectly = !nativeError.shouldReturnTypedErrorIndirectly(); - } - - if (result.empty() && !mayReturnErrorDirectly) { + bool isSwiftCCReturn, bool isOutlined) { + if (result.empty()) { assert(IGM.getTypeInfo(returnResultType) .nativeReturnValueSchema(IGM) .empty() && @@ -5704,74 +5478,24 @@ void IRGenFunction::emitScalarReturn(SILType returnResultType, // In the native case no coercion is needed. if (isSwiftCCReturn) { - auto &resultTI = IGM.getTypeInfo(funcResultType); - auto &nativeSchema = resultTI.nativeReturnValueSchema(IGM); - assert(!nativeSchema.requiresIndirect()); result = coerceValueTo(returnResultType, result, funcResultType); + auto &nativeSchema = + IGM.getTypeInfo(funcResultType).nativeReturnValueSchema(IGM); + assert(!nativeSchema.requiresIndirect()); Explosion native = nativeSchema.mapIntoNative(IGM, *this, result, funcResultType, isOutlined); - llvm::Value *nativeAgg = nullptr; - - if (mayReturnErrorDirectly) { - auto &errorTI = IGM.getTypeInfo(errorType); - auto &nativeError = errorTI.nativeReturnValueSchema(IGM); - auto *combinedTy = - combineResultAndTypedErrorType(IGM, nativeSchema, nativeError) - .combinedTy; - - if (combinedTy->isVoidTy()) { - Builder.CreateRetVoid(); - return; - } - - if (native.empty()) { - Builder.CreateRet(llvm::UndefValue::get(combinedTy)); - return; - } - - auto convertIfNecessary = [&](llvm::Type *nativeTy, - llvm::Value *elt) -> llvm::Value * { - auto *eltTy = elt->getType(); - if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && - nativeTy->getPrimitiveSizeInBits() != - eltTy->getPrimitiveSizeInBits()) { - assert(nativeTy->getPrimitiveSizeInBits() > - eltTy->getPrimitiveSizeInBits()); - return Builder.CreateZExt(elt, nativeTy); - } - return elt; - }; - - if (auto *structTy = dyn_cast(combinedTy)) { - nativeAgg = llvm::UndefValue::get(combinedTy); - for (unsigned i = 0, e = native.size(); i != e; ++i) { - llvm::Value *elt = native.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertIfNecessary(nativeTy, elt); - nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); - } - } else { - nativeAgg = convertIfNecessary(combinedTy, native.claimNext()); - } + if (native.size() == 1) { + Builder.CreateRet(native.claimNext()); + return; } - - if (!nativeAgg) { - if (native.size() == 1) { - Builder.CreateRet(native.claimNext()); - return; - } - - nativeAgg = llvm::UndefValue::get(nativeSchema.getExpandedType(IGM)); - - for (unsigned i = 0, e = native.size(); i != e; ++i) { - llvm::Value *elt = native.claimNext(); - nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); - } + llvm::Value *nativeAgg = + llvm::UndefValue::get(nativeSchema.getExpandedType(IGM)); + for (unsigned i = 0, e = native.size(); i != e; ++i) { + llvm::Value *elt = native.claimNext(); + nativeAgg = Builder.CreateInsertValue(nativeAgg, elt, i); } - Builder.CreateRet(nativeAgg); - return; } diff --git a/lib/IRGen/GenCall.h b/lib/IRGen/GenCall.h index a912f14b39751..7adca3f8afc39 100644 --- a/lib/IRGen/GenCall.h +++ b/lib/IRGen/GenCall.h @@ -121,15 +121,6 @@ namespace irgen { CanSILFunctionType substitutedType, SubstitutionMap substitutionMap); - struct CombinedResultAndErrorType { - llvm::Type *combinedTy; - llvm::SmallVector errorValueMapping; - }; - CombinedResultAndErrorType - combineResultAndTypedErrorType(const IRGenModule &IGM, - const NativeConventionSchema &resultSchema, - const NativeConventionSchema &errorSchema); - /// Given an async function, get the pointer to the function to be called and /// the size of the context to be allocated. /// diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 933e85a5c3bc9..c59cab27a0587 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -1177,19 +1177,8 @@ class SyncPartialApplicationForwarderEmission llvm::Value *errorResultPtr = origParams.claimNext(); args.add(errorResultPtr); if (origConv.isTypedError()) { - auto errorType = - origConv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto silResultTy = - origConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = IGM.getTypeInfo(errorType); - auto &resultTI = IGM.getTypeInfo(silResultTy); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - if (resultSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly() || outConv.hasIndirectSILErrorResults()) { - auto *typedErrorResultPtr = origParams.claimNext(); - args.add(typedErrorResultPtr); - } + auto *typedErrorResultPtr = origParams.claimNext(); + args.add(typedErrorResultPtr); } } llvm::CallInst *createCall(FunctionPointer &fnPtr) override { diff --git a/lib/IRGen/GenThunk.cpp b/lib/IRGen/GenThunk.cpp index d31c3be9dadf8..1c3df3840e0f6 100644 --- a/lib/IRGen/GenThunk.cpp +++ b/lib/IRGen/GenThunk.cpp @@ -143,22 +143,14 @@ void IRGenThunk::prepareArguments() { // Set the typed error value result slot. if (conv.isTypedError() && !conv.hasIndirectSILErrorResults()) { + auto directTypedErrorAddr = original.takeLast(); auto errorType = conv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); auto &errorTI = cast(IGF.getTypeInfo(errorType)); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGF.IGM); - auto resultType = - conv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto &resultTI = cast(IGF.getTypeInfo(resultType)); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGF.IGM); - - if (isAsync || resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - auto directTypedErrorAddr = original.takeLast(); - IGF.setCalleeTypedErrorResultSlot(Address(directTypedErrorAddr, - errorTI.getStorageType(), - errorTI.getFixedAlignment())); - } + + IGF.setCalleeTypedErrorResultSlot(Address(directTypedErrorAddr, + errorTI.getStorageType(), + errorTI.getFixedAlignment())); } else if (conv.isTypedError()) { auto directTypedErrorAddr = original.takeLast(); // Store for later processing when we know the argument index. @@ -335,8 +327,7 @@ void IRGenThunk::emit() { llvm::Value *errorValue = nullptr; - if (emission->getTypedErrorExplosion() || - (isAsync && origTy->hasErrorResult())) { + if (isAsync && origTy->hasErrorResult()) { SILType errorType = conv.getSILErrorType(expansionContext); Address calleeErrorSlot = emission->getCalleeErrorSlot( errorType, /*isCalleeAsync=*/origTy->isAsync()); @@ -345,28 +336,6 @@ void IRGenThunk::emit() { emission->end(); - // FIXME: we shouldn't have to generate all of this. We should just forward - // the value as is - if (auto &error = emission->getTypedErrorExplosion()) { - llvm::BasicBlock *successBB = IGF.createBasicBlock("success"); - llvm::BasicBlock *errorBB = IGF.createBasicBlock("failure"); - - llvm::Value *nil = llvm::ConstantPointerNull::get( - cast(errorValue->getType())); - auto *hasError = IGF.Builder.CreateICmpNE(errorValue, nil); - - // Predict no error is thrown. - hasError = - IGF.IGM.getSILModule().getOptions().EnableThrowsPrediction ? - IGF.Builder.CreateExpectCond(IGF.IGM, hasError, false) : hasError; - - IGF.Builder.CreateCondBr(hasError, errorBB, successBB); - - IGF.Builder.emitBlock(errorBB); - IGF.emitScalarReturn(IGF.CurFn->getReturnType(), *error); - IGF.Builder.emitBlock(successBB); - } - if (isAsync) { Explosion error; if (errorValue) @@ -377,11 +346,7 @@ void IRGenThunk::emit() { // Return the result. if (result.empty()) { - if (emission->getTypedErrorExplosion()) { - IGF.Builder.CreateRet(llvm::UndefValue::get(IGF.CurFn->getReturnType())); - } else { - IGF.Builder.CreateRetVoid(); - } + IGF.Builder.CreateRetVoid(); return; } diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index 266347e3a1633..f85666cf2f0cf 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -102,7 +102,7 @@ class IRGenFunction { Explosion collectParameters(); void emitScalarReturn(SILType returnResultType, SILType funcResultType, Explosion &scalars, bool isSwiftCCReturn, - bool isOutlined, SILType errorType = {}); + bool isOutlined); void emitScalarReturn(llvm::Type *resultTy, Explosion &scalars); void emitBBForReturn(); diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 86b09befd7ed3..aa53d1a34f307 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -2163,7 +2163,7 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, // Remap the entry block. IGF.LoweredBBs[&*IGF.CurSILFn->begin()] = LoweredBB(IGF.Builder.GetInsertBlock(), {}); } - } + } // Bind the error result by popping it off the parameter list. if (funcTy->hasErrorResult()) { @@ -2175,21 +2175,14 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, bool isIndirectError = fnConv.hasIndirectSILErrorResults(); if (isTypedError && !isIndirectError) { - auto resultType = - fnConv.getSILResultType(IGF.IGM.getMaximalTypeExpansionContext()); - auto inContextResultType = IGF.CurSILFn->mapTypeIntoContext(resultType); - auto &resultTI = - cast(IGF.getTypeInfo(inContextResultType)); - auto &errorTI = cast(IGF.getTypeInfo(inContextErrorType)); - auto &native = resultTI.nativeReturnValueSchema(IGF.IGM); - auto &nativeError = errorTI.nativeReturnValueSchema(IGF.IGM); - if (funcTy->isAsync() || native.requiresIndirect() || - nativeError.shouldReturnTypedErrorIndirectly()) { - IGF.setCallerTypedErrorResultSlot( - Address(emission->getCallerTypedErrorResultArgument(), - errorTI.getStorageType(), errorTI.getFixedAlignment())); - } + auto &errorTI = cast(IGF.getTypeInfo(errorType)); + IGF.setCallerTypedErrorResultSlot(Address( + emission->getCallerTypedErrorResultArgument(), + errorTI.getStorageType(), + errorTI.getFixedAlignment())); + } else if (isTypedError && isIndirectError) { + auto &errorTI = IGF.getTypeInfo(inContextErrorType); auto ptr = emission->getCallerTypedErrorResultArgument(); auto addr = errorTI.getAddressForPointer(ptr); @@ -2336,6 +2329,7 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, return IGF.getLoweredSingletonExplosion(parameter); }); } + assert(allParamValues.empty() && "didn't claim all parameters!"); } @@ -3917,41 +3911,12 @@ void IRGenSILFunction::visitFullApplySite(FullApplySite site) { } else { Builder.emitBlock(typedErrorLoadBB); - auto &errorTI = cast(IGM.getTypeInfo(errorType)); - auto silResultTy = - substConv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - auto &resultTI = cast(IGM.getTypeInfo(silResultTy)); - - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - if (isAsync() || substConv.hasIndirectSILErrorResults() || - resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - Explosion errorValue; - errorTI.loadAsTake(*this, getCalleeTypedErrorResultSlot(errorType), - errorValue); - for (unsigned i = 0, e = errorDest.phis.size(); i != e; ++i) { - errorDest.phis[i]->addIncoming(errorValue.claimNext(), - Builder.GetInsertBlock()); - } - } else { - auto combined = - combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - if (auto &errorValue = emission->getTypedErrorExplosion()) { - if (errorDest.phis.empty()) { - errorValue->reset(); - } else { - for (unsigned i = 0, e = errorDest.phis.size(); i != e; ++i) { - errorDest.phis[i]->addIncoming(errorValue->claimNext(), - Builder.GetInsertBlock()); - } - } - } else { - llvm_unreachable("No explosion set for direct typed error result"); - } + auto &ti = cast(IGM.getTypeInfo(errorType)); + Explosion errorValue; + ti.loadAsTake(*this, getCalleeTypedErrorResultSlot(errorType), errorValue); + for (unsigned i = 0, e = errorDest.phis.size(); i != e; ++i) { + errorDest.phis[i]->addIncoming(errorValue.claimNext(), Builder.GetInsertBlock()); } - Builder.CreateBr(errorDest.bb); } @@ -4390,14 +4355,8 @@ static void emitReturnInst(IRGenSILFunction &IGF, auto swiftCCReturn = funcLang == SILFunctionLanguage::Swift; assert(swiftCCReturn || funcLang == SILFunctionLanguage::C && "Need to handle all cases"); - SILType errorType; - if (fnType->hasErrorResult() && conv.isTypedError() && - !conv.hasIndirectSILErrorResults()) { - errorType = - conv.getSILErrorType(IGF.IGM.getMaximalTypeExpansionContext()); - } - IGF.emitScalarReturn(resultTy, funcResultType, result, swiftCCReturn, false, - errorType); + IGF.emitScalarReturn(resultTy, funcResultType, result, swiftCCReturn, + false); } } @@ -4425,85 +4384,23 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { assert(!conv.hasIndirectSILErrorResults()); if (!isAsync()) { - auto fnTy = CurFn->getFunctionType(); - auto retTy = fnTy->getReturnType(); if (conv.isTypedError()) { llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1); flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy); Explosion errorResult = getLoweredExplosion(i->getOperand()); - auto silErrorTy = - conv.getSILErrorType(IGM.getMaximalTypeExpansionContext()); - auto &errorTI = cast(IGM.getTypeInfo(silErrorTy)); - - auto silResultTy = - conv.getSILResultType(IGM.getMaximalTypeExpansionContext()); - - if (silErrorTy.getASTType()->isNever()) { - emitTrap("Never can't be initialized", true); - return; - } else { - auto &resultTI = cast(IGM.getTypeInfo(silResultTy)); - auto &resultSchema = resultTI.nativeReturnValueSchema(IGM); - auto &errorSchema = errorTI.nativeReturnValueSchema(IGM); - - Builder.CreateStore(flag, getCallerErrorResultSlot()); - if (resultSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { - errorTI.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), - false); - } else { - auto combined = - combineResultAndTypedErrorType(IGM, resultSchema, errorSchema); - - if (combined.combinedTy->isVoidTy()) { - Builder.CreateRetVoid(); - return; - } - - llvm::Value *expandedResult = llvm::UndefValue::get(combined.combinedTy); - - if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - auto nativeError = errorSchema.mapIntoNative(IGM, *this, errorResult, - silErrorTy, false); - - auto convertIfNecessary = [&](llvm::Type *nativeTy, - llvm::Value *elt) -> llvm::Value * { - auto *eltTy = elt->getType(); - if (nativeTy->isIntOrPtrTy() && eltTy->isIntOrPtrTy() && - nativeTy->getPrimitiveSizeInBits() != - eltTy->getPrimitiveSizeInBits()) { - assert(nativeTy->getPrimitiveSizeInBits() > - eltTy->getPrimitiveSizeInBits()); - return Builder.CreateZExt(elt, nativeTy); - } - return elt; - }; - - if (auto *structTy = dyn_cast(combined.combinedTy)) { - for (unsigned i : combined.errorValueMapping) { - llvm::Value *elt = nativeError.claimNext(); - auto *nativeTy = structTy->getElementType(i); - elt = convertIfNecessary(nativeTy, elt); - expandedResult = Builder.CreateInsertValue(expandedResult, elt, i); - } - } else if (!errorSchema.getExpandedType(IGM)->isVoidTy()) { - expandedResult = - convertIfNecessary(combined.combinedTy, nativeError.claimNext()); - } - } - - Explosion nativeAgg = Explosion(expandedResult); - emitScalarReturn(combined.combinedTy, nativeAgg); + auto &ti = cast(IGM.getTypeInfo(conv.getSILErrorType( + IGM.getMaximalTypeExpansionContext()))); + ti.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), false); - return; - } - } + Builder.CreateStore(flag, getCallerErrorResultSlot()); } else { Explosion errorResult = getLoweredExplosion(i->getOperand()); Builder.CreateStore(errorResult.claimNext(), getCallerErrorResultSlot()); } // Create a normal return, but leaving the return value undefined. + auto fnTy = CurFn->getFunctionType(); + auto retTy = fnTy->getReturnType(); if (retTy->isVoidTy()) { Builder.CreateRetVoid(); } else { diff --git a/lib/IRGen/NativeConventionSchema.h b/lib/IRGen/NativeConventionSchema.h index c1230d3f04e5f..218786ceaef47 100644 --- a/lib/IRGen/NativeConventionSchema.h +++ b/lib/IRGen/NativeConventionSchema.h @@ -42,9 +42,6 @@ class NativeConventionSchema { NativeConventionSchema &operator=(const NativeConventionSchema&) = delete; bool requiresIndirect() const { return RequiresIndirect; } - bool shouldReturnTypedErrorIndirectly() const { - return requiresIndirect() || Lowering.shouldReturnTypedErrorIndirectly(); - } bool empty() const { return Lowering.empty(); } llvm::Type *getExpandedType(IRGenModule &IGM) const; diff --git a/test/IRGen/typed_throws.sil b/test/IRGen/typed_throws.sil index 3049232584c3f..3338156abf65d 100644 --- a/test/IRGen/typed_throws.sil +++ b/test/IRGen/typed_throws.sil @@ -18,13 +18,15 @@ sil_vtable A {} sil @create_error : $@convention(thin) () -> @owned A -// CHECK: define{{.*}} swiftcc { ptr, ptr } @throw_error(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1) +// CHECK: define{{.*}} swiftcc void @throw_error(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1, ptr %2) // CHECK: [[ERR:%.*]] = call swiftcc ptr @create_error() // CHECK: call ptr @swift_retain(ptr returned [[ERR]]) +// CHECK: [[F1:%.*]] = getelementptr inbounds %T12typed_throws1SV, ptr %2, i32 0, i32 0 +// CHECK: store ptr [[ERR]], ptr [[F1]] +// CHECK: [[F2:%.*]] = getelementptr inbounds %T12typed_throws1SV, ptr %2, i32 0, i32 1 +// CHECK: store ptr [[ERR]], ptr [[F2]] // CHECK: store ptr inttoptr (i64 1 to ptr), ptr %1 -// CHECK: [[RET_v1:%.*]] = insertvalue { ptr, ptr } undef, ptr [[ERR]], 0 -// CHECK: [[RET_v2:%.*]] = insertvalue { ptr, ptr } [[RET_v1]], ptr [[ERR]], 1 -// CHECK: ret { ptr, ptr } [[RET_v2]] +// CHECK: ret void // CHECK: } sil @throw_error : $@convention(thin) () -> @error S { @@ -47,24 +49,27 @@ sil @try_apply_helper : $@convention(thin) (@owned AnyObject) -> (@owned AnyObje // CHECK: entry: // CHECK: %swifterror = alloca swifterror ptr // CHECK: store ptr null, ptr %swifterror -// CHECK: [[RES:%.*]] = call swiftcc { ptr, ptr } @try_apply_helper(ptr %0, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %swifterror) -// CHECK: [[RES_0:%.*]] = extractvalue { ptr, ptr } [[RES]], 0 -// CHECK: [[RES_1:%.*]] = extractvalue { ptr, ptr } [[RES]], 1 +// CHECK: %swifterror1 = alloca %T12typed_throws1SV +// CHECK: [[RES:%.*]] = call swiftcc ptr @try_apply_helper(ptr %0, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %swifterror, ptr %swifterror1) // CHECK: [[ERRFLAG:%.*]] = load ptr, ptr %swifterror // CHECK: [[C:%.*]] = icmp ne ptr [[ERRFLAG]], null // CHECK: br i1 [[C]], label %[[ERR_B:.*]], label %[[SUCC_B:[0-9]+]] // CHECK: [[ERR_B]]: +// CHECK: %swifterror1.x = getelementptr inbounds %T12typed_throws1SV, ptr %swifterror1, i32 0, i32 0 +// CHECK: [[ERR_v1:%.*]] = load ptr, ptr %swifterror1.x +// CHECK: %swifterror1.y = getelementptr inbounds %T12typed_throws1SV, ptr %swifterror1, i32 0, i32 1 +// CHECK: [[ERR_v2:%.*]] = load ptr, ptr %swifterror1.y // CHECK: br label %[[ERR2_B:[0-9]+]] // CHECK: [[SUCC_B]]: -// CHECK: [[R:%.*]] = phi ptr [ [[RES_0]], %entry ] +// CHECK: [[R:%.*]] = phi ptr [ [[RES]], %entry ] // CHECK: call void @swift_{{.*}}elease(ptr [[R]]) // CHECK: br label %[[RET_B:[0-9]+]] // CHECK: [[ERR2_B]]: -// CHECK: [[E1:%.*]] = phi ptr [ [[RES_0]], %[[ERR_B]] ] -// CHECK: [[E2:%.*]] = phi ptr [ [[RES_1]], %[[ERR_B]] ] +// CHECK: [[E1:%.*]] = phi ptr [ [[ERR_v1]], %[[ERR_B]] ] +// CHECK: [[E2:%.*]] = phi ptr [ [[ERR_v2]], %[[ERR_B]] ] // CHECK: store ptr null, ptr %swifterror // CHECK: call void @swift_release(ptr [[E1]]) // CHECK: call void @swift_release(ptr [[E2]]) @@ -205,9 +210,9 @@ bb6: return %7 : $() } -// CHECK: define{{.*}} internal swiftcc { ptr, ptr } @"$s16try_apply_helperTA"(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1) -// CHECK: tail call swiftcc { ptr, ptr } @try_apply_helper(ptr {{.*}}, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1) -// CHECK: ret { ptr, ptr } +// CHECK: define{{.*}} internal swiftcc ptr @"$s16try_apply_helperTA"(ptr swiftself %0, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1, ptr %2) +// CHECK: tail call swiftcc ptr @try_apply_helper(ptr {{.*}}, ptr swiftself undef, ptr noalias nocapture swifterror dereferenceable({{.*}}) %1, ptr %2) +// CHECK: ret ptr sil @partial_apply_test : $@convention(thin) (@owned AnyObject) -> @owned @callee_guaranteed () ->(@owned AnyObject, @error S) { entry(%0: $AnyObject): @@ -230,7 +235,8 @@ entry(%0: $AnyObject): // CHECK:entry: // CHECK: %swifterror = alloca swifterror ptr // CHECK: store ptr null, ptr %swifterror -// CHECK: call swiftcc { ptr, ptr } %0(ptr swiftself %1, ptr noalias nocapture swifterror dereferenceable({{[0-9]+}}) %swifterror) +// CHECK: %swifterror1 = alloca %T12typed_throws1SV +// CHECK: call swiftcc ptr %0(ptr swiftself %1, ptr noalias nocapture swifterror dereferenceable({{[0-9]+}}) %swifterror, ptr %swifterror1) sil @apply_closure : $@convention(thin) (@guaranteed @callee_guaranteed () -> (@owned AnyObject, @error S)) -> () { entry(%0 : $@callee_guaranteed () ->(@owned AnyObject, @error S)): diff --git a/test/IRGen/typed_throws.swift b/test/IRGen/typed_throws.swift index 7bd4e3ae02e2e..32b37dd34237a 100644 --- a/test/IRGen/typed_throws.swift +++ b/test/IRGen/typed_throws.swift @@ -9,9 +9,9 @@ public enum MyBigError: Error { case epicFail - case evenBiggerFail } + // CHECK-MANGLE: @"$s12typed_throws1XVAA1PAAWP" = hidden global [2 x ptr] [ptr @"$s12typed_throws1XVAA1PAAMc", ptr getelementptr inbounds (i8, ptr @"symbolic ySi_____YKc 12typed_throws10MyBigErrorO", {{i32|i64}} 1)] @available(SwiftStdlib 6.0, *) struct X: P { @@ -56,7 +56,7 @@ func five() -> Int { 5 } func fiveOrBust() throws -> Int { 5 } -func fiveOrTypedBust() throws(MyBigError) -> Int { throw MyBigError.epicFail } +func fiveOrTypedBust() throws(MyBigError) -> Int { 5 } func reabstractAsNonthrowing() -> Int { passthroughCall(five) @@ -73,8 +73,7 @@ func reabstractAsConcreteThrowing() throws -> Int { // CHECK-LABEL: define {{.*}} swiftcc void @"$sSi12typed_throws10MyBigErrorOIgdzo_SiACIegrzr_TR"(ptr noalias nocapture sret(%TSi) %0, ptr %1, ptr %2, ptr swiftself %3, ptr noalias nocapture swifterror dereferenceable(8) %4, ptr %5) // CHECK: call swiftcc {{i32|i64}} %1 -// CHECK: [[CMP:%.*]] = icmp ne ptr {{%.*}}, null -// CHECK: br i1 [[CMP]], label %typed.error.load +// CHECK: br i1 %8, label %typed.error.load, label %10 struct S : Error { } diff --git a/test/IRGen/typed_throws_thunks.swift b/test/IRGen/typed_throws_thunks.swift index b38c5b8102334..8799a3c5acb05 100644 --- a/test/IRGen/typed_throws_thunks.swift +++ b/test/IRGen/typed_throws_thunks.swift @@ -57,9 +57,9 @@ extension P { } } - // CHECK-LABEL: define{{.*}} swiftcc { i64, i64 } @"$s19typed_throws_thunks1PP2g34bodyyyyAA9FixedSizeVYKXE_tAGYKFTj"(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5) + // CHECK-LABEL: define{{.*}} swiftcc void @"$s19typed_throws_thunks1PP2g34bodyyyyAA9FixedSizeVYKXE_tAGYKFTj"(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5, ptr %6) // CHECK-NOT: ret - // CHECK: call swiftcc { i64, i64 } {{.*}}(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5) + // CHECK: call swiftcc void {{.*}}(ptr %0, ptr %1, ptr noalias swiftself %2, ptr noalias nocapture swifterror dereferenceable(8) %3, ptr %4, ptr %5, ptr %6) public func g3(body: () throws(FixedSize) -> Void) throws(FixedSize) {