Skip to content

Commit 31f1590

Browse files
committed
[Coroutines] Always set the calling convention of generated resuming call from 'llvm.coro.await.suspend.handle' as fast
See the post commit message in #89751 We met a regression due to a change of calling convention of this patch. Previously, the calling convention of indirect resume calls is always fast. And in this patch, although we tried to take care of it in the cloner, we forget the case that we have to update the resuming calls in the ramp functions. So this is the root cause of the downstream failure. This patch tries to mark the generated resuming calls as fast immediately after they got created to make sure the calling convention is correct.
1 parent 7c137f7 commit 31f1590

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

llvm/lib/Transforms/Coroutines/CoroSplit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ static void lowerAwaitSuspend(IRBuilder<> &Builder, CoroAwaitSuspendInst *CB,
227227
FunctionType *ResumeTy = FunctionType::get(
228228
Type::getVoidTy(Ctx), PointerType::getUnqual(Ctx), false);
229229
auto *ResumeCall = Builder.CreateCall(ResumeTy, ResumeAddr, {NewCall});
230+
ResumeCall->setCallingConv(CallingConv::Fast);
230231

231232
// We can't insert the 'ret' instruction and adjust the cc until the
232233
// function has been split, so remember this for later.
@@ -1088,7 +1089,6 @@ void CoroCloner::create() {
10881089
// Turn symmetric transfers into musttail calls.
10891090
for (CallInst *ResumeCall : Shape.SymmetricTransfers) {
10901091
ResumeCall = cast<CallInst>(VMap[ResumeCall]);
1091-
ResumeCall->setCallingConv(NewF->getCallingConv());
10921092
if (TTI.supportsTailCallFor(ResumeCall)) {
10931093
// FIXME: Could we support symmetric transfer effectively without
10941094
// musttail?
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
; Tests lowerings of different versions of coro.await.suspend
2+
; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split),simplifycfg' -S | FileCheck %s
3+
4+
%Awaiter = type {}
5+
6+
define void @f() presplitcoroutine {
7+
entry:
8+
%awaiter = alloca %Awaiter
9+
%id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
10+
%size = call i32 @llvm.coro.size.i32()
11+
%alloc = call ptr @malloc(i32 %size)
12+
%hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc)
13+
call void @llvm.coro.await.suspend.handle(ptr %awaiter, ptr %hdl, ptr @await_suspend_wrapper_handle)
14+
%suspend.init = call i8 @llvm.coro.suspend(token none, i1 false)
15+
switch i8 %suspend.init, label %ret [
16+
i8 0, label %step
17+
i8 1, label %cleanup
18+
]
19+
20+
; Check the calling convention for resuming function is fastcc
21+
; CHECK: define {{[^@]*}} @f()
22+
; CHECK: entry:
23+
; CHECK: %[[NEXT_HDL:.+]] = call ptr @await_suspend_wrapper_handle(
24+
; CHECK-NEXT: %[[CONT:.+]] = call ptr @llvm.coro.subfn.addr(ptr %[[NEXT_HDL]], i8 0)
25+
; CHECK-NEXT: musttail call fastcc void %[[CONT]](ptr %[[NEXT_HDL]])
26+
step:
27+
br label %cleanup
28+
29+
cleanup:
30+
%mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
31+
call void @free(ptr %mem)
32+
br label %ret
33+
34+
ret:
35+
call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
36+
ret void
37+
}
38+
39+
; check that we were haven't accidentally went out of @f body
40+
; CHECK-LABEL: @f.resume(
41+
; CHECK-LABEL: @f.destroy(
42+
; CHECK-LABEL: @f.cleanup(
43+
44+
declare ptr @await_suspend_wrapper_handle(ptr, ptr)
45+
46+
declare ptr @llvm.coro.free(token, ptr)
47+
declare i32 @llvm.coro.size.i32()
48+
declare i8 @llvm.coro.suspend(token, i1)
49+
declare void @llvm.coro.resume(ptr)
50+
declare void @llvm.coro.destroy(ptr)
51+
52+
declare token @llvm.coro.id(i32, ptr, ptr, ptr)
53+
declare i1 @llvm.coro.alloc(token)
54+
declare ptr @llvm.coro.begin(token, ptr)
55+
declare void @llvm.coro.await.suspend.handle(ptr, ptr, ptr)
56+
declare i1 @llvm.coro.end(ptr, i1, token)
57+
58+
declare noalias ptr @malloc(i32)
59+
declare void @free(ptr)

0 commit comments

Comments
 (0)