Skip to content

Commit

Permalink
[coro] Async coroutines: Make sure we can handle control flow in susp…
Browse files Browse the repository at this point in the history
…end point dispatch function

Create a valid basic block with a terminator before we call
InlineFunction.

Differential Revision: https://reviews.llvm.org/D91547
  • Loading branch information
aschwaighofer committed Nov 16, 2020
1 parent 15beb4e commit d861cc0
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Coroutines/CoroSplit.cpp
Expand Up @@ -1458,11 +1458,11 @@ static void splitAsyncCoroutine(Function &F, coro::Shape &Shape,
TailCall->setDebugLoc(DbgLoc);
TailCall->setTailCall();
TailCall->setCallingConv(Fn->getCallingConv());
Builder.CreateRetVoid();
InlineFunctionInfo FnInfo;
auto InlineRes = InlineFunction(*TailCall, FnInfo);
assert(InlineRes.isSuccess() && "Expected inlining to succeed");
(void)InlineRes;
Builder.CreateRetVoid();

// Replace the lvm.coro.async.resume intrisic call.
replaceAsyncResumeFunction(Suspend, Continuation);
Expand Down
54 changes: 54 additions & 0 deletions llvm/test/Transforms/Coroutines/coro-async.ll
Expand Up @@ -260,6 +260,60 @@ define swiftcc void @top_level_caller(i8* %ctxt, i8* %task, i8* %actor) {
; CHECK: tail call swiftcc void @asyncSuspend
; CHECK: ret void

@dont_crash_on_cf_fp = constant <{ i32, i32 }>
<{ i32 trunc ( ; Relative pointer to async function
i64 sub (
i64 ptrtoint (void (i8*, %async.task*, %async.actor*)* @my_async_function to i64),
i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @my_async_function_fp, i32 0, i32 1) to i64)
)
to i32),
i32 128 ; Initial async context size without space for frame
}>


define swiftcc void @dont_crash_on_cf_dispatch(i8* %fnPtr, i8* %async.ctxt, %async.task* %task, %async.actor* %actor) {
%isNull = icmp eq %async.task* %task, null
br i1 %isNull, label %is_null, label %is_not_null

is_null:
ret void

is_not_null:
%callee = bitcast i8* %fnPtr to void(i8*, %async.task*, %async.actor*)*
tail call swiftcc void %callee(i8* %async.ctxt, %async.task* %task, %async.actor* %actor)
ret void
}

define swiftcc void @dont_crash_on_cf(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) {
entry:
%id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
i8* bitcast (<{i32, i32}>* @dont_crash_on_cf_fp to i8*))
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)
%arg0 = bitcast %async.task* %task to i8*
%arg1 = bitcast <{ i32, i32}>* @my_other_async_function_fp to i8*
%callee_context = call i8* @llvm.coro.async.context.alloc(i8* %arg0, i8* %arg1)
%callee_context.0 = bitcast i8* %callee_context to %async.ctxt*
%callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, %async.ctxt* %callee_context.0, i32 0, i32 1
%return_to_caller.addr = bitcast void(i8*, %async.task*, %async.actor*)** %callee_context.return_to_caller.addr to i8**
%resume.func_ptr = call i8* @llvm.coro.async.resume()
store i8* %resume.func_ptr, i8** %return_to_caller.addr
%callee_context.caller_context.addr = getelementptr inbounds %async.ctxt, %async.ctxt* %callee_context.0, i32 0, i32 0
store i8* %async.ctxt, i8** %callee_context.caller_context.addr
%resume_proj_fun = bitcast i8*(i8*)* @resume_context_projection to i8*
%callee = bitcast void(i8*, %async.task*, %async.actor*)* @asyncSuspend to i8*
%res = call {i8*, i8*, i8*} (i8*, i8*, ...) @llvm.coro.suspend.async(
i8* %resume.func_ptr,
i8* %resume_proj_fun,
void (i8*, i8*, %async.task*, %async.actor*)* @dont_crash_on_cf_dispatch,
i8* %callee, i8* %callee_context, %async.task* %task, %async.actor *%actor)

call void @llvm.coro.async.context.dealloc(i8* %callee_context)
%continuation_task_arg = extractvalue {i8*, i8*, i8*} %res, 1
%task.2 = bitcast i8* %continuation_task_arg to %async.task*
tail call swiftcc void @asyncReturn(i8* %async.ctxt, %async.task* %task.2, %async.actor* %actor)
call i1 @llvm.coro.end(i8* %hdl, i1 0)
unreachable
}
declare i8* @llvm.coro.prepare.async(i8*)
declare token @llvm.coro.id.async(i32, i32, i32, i8*)
declare i8* @llvm.coro.begin(token, i8*)
Expand Down

0 comments on commit d861cc0

Please sign in to comment.