Skip to content

Commit 671ce74

Browse files
[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.
1 parent 3f68cca commit 671ce74

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
@@ -4929,7 +4929,15 @@ void irgen::emitAsyncReturn(
49294929
arguments.push_back(arg);
49304930

49314931
Builder.CreateIntrinsicCall(llvm::Intrinsic::coro_end_async, arguments);
4932-
Builder.CreateUnreachable();
4932+
4933+
if (IGF.IGM.AsyncTailCallKind == llvm::CallInst::TCK_MustTail) {
4934+
Builder.CreateUnreachable();
4935+
} else {
4936+
// If target doesn't support musttail (e.g. WebAssembly), the function
4937+
// passed to coro.end.async can return control back to the caller.
4938+
// So use ret void instead of unreachable to allow it.
4939+
Builder.CreateRetVoid();
4940+
}
49334941
}
49344942

49354943
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)