Skip to content

Commit 8079b35

Browse files
kateinoigakukuncompnerd
authored andcommitted
[IRGen] Put 'ret void' instead of unreachable for non swiftasync cc
If target doesn't support musttail (e.g. WebAssembly), the function passed to coro.end.async can return control back to the caller. So the frontend should emit 'ret void' instead of unreachable after the coro.end.async intrinsic call to allow such situation. (cherry picked from commit 671ce74)
1 parent 2c007d8 commit 8079b35

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4949,7 +4949,15 @@ void irgen::emitAsyncReturn(
49494949
arguments.push_back(arg);
49504950

49514951
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_async, arguments);
4952-
Builder.CreateUnreachable();
4952+
4953+
if (IGF.IGM.AsyncTailCallKind == llvm::CallInst::TCK_MustTail) {
4954+
Builder.CreateUnreachable();
4955+
} else {
4956+
// If target doesn't support musttail (e.g. WebAssembly), the function
4957+
// passed to coro.end.async can return control back to the caller.
4958+
// So use ret void instead of unreachable to allow it.
4959+
Builder.CreateRetVoid();
4960+
}
49534961
}
49544962

49554963
void irgen::emitAsyncReturn(IRGenFunction &IGF, AsyncContextLayout &asyncLayout,
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Ensure that IRGen don't emit unreachable after coro.end.async for targets that don't support musttail call.
2+
// RUN: %swift -disable-legacy-type-info -parse-stdlib -target wasm32-unknown-wasi %s -disable-llvm-optzns -disable-swift-specific-llvm-optzns -disable-objc-interop -module-name main -emit-ir -o - | %FileCheck %s
3+
// REQUIRES: concurrency
4+
// REQUIRES: CODEGENERATOR=WebAssembly
5+
6+
sil_stage canonical
7+
8+
import Builtin
9+
10+
sil @test_simple : $@async () -> () {
11+
bb0:
12+
%0 = tuple ()
13+
return %0 : $()
14+
// CHECK: call i1 (i8*, i1, ...) @llvm.coro.end.async
15+
// CHECK-NOT: unreachable
16+
// CHECK: ret void
17+
}

0 commit comments

Comments
 (0)