From fe15d04505e9c505dbc3a9c7a1f17f41eb2ca26e Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 10 Sep 2024 13:29:16 -0700 Subject: [PATCH 1/2] IRGen: Async throwing functions with empty error types pass the error indirectly rdar://135304464 --- lib/IRGen/GenCall.cpp | 5 ++++- test/IRGen/typed_throws.sil | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index c8a7bdc8d637f..d6e8596faf07d 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -3030,7 +3030,10 @@ class AsyncCallEmission final : public CallEmission { IGF.IGM.getTypeInfo(silErrorTy).nativeReturnValueSchema(IGF.IGM); if (nativeSchema.requiresIndirect() || - errorSchema.shouldReturnTypedErrorIndirectly()) { + errorSchema.shouldReturnTypedErrorIndirectly() || + errorSchema.empty()) { // direct empty typed errors are passed + // indirectly for compatibility with generic + // functions. // 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 3e5ca9cdc7c09..b1f7d32735ba5 100644 --- a/test/IRGen/typed_throws.sil +++ b/test/IRGen/typed_throws.sil @@ -458,3 +458,34 @@ 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 +} From ede9f33c52889e41089ed86509940d617e58a349 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Wed, 11 Sep 2024 08:20:48 -0700 Subject: [PATCH 2/2] Fix the fix --- lib/IRGen/GenCall.cpp | 2 +- test/IRGen/typed_throws.sil | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index d6e8596faf07d..a201435ce7135 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -3031,7 +3031,7 @@ class AsyncCallEmission final : public CallEmission { if (nativeSchema.requiresIndirect() || errorSchema.shouldReturnTypedErrorIndirectly() || - errorSchema.empty()) { // direct empty typed errors are passed + (errorSchema.empty() && fnConv.hasIndirectSILResults())) { // direct empty typed errors are passed // indirectly for compatibility with generic // functions. // Return the error indirectly. diff --git a/test/IRGen/typed_throws.sil b/test/IRGen/typed_throws.sil index b1f7d32735ba5..8d5caa462ee53 100644 --- a/test/IRGen/typed_throws.sil +++ b/test/IRGen/typed_throws.sil @@ -489,3 +489,30 @@ bb1(%12 : $()): 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 +}