Skip to content

Commit 6edded5

Browse files
committed
[coro] Fix rematerializable instruction sinking to coro.suspend blocks
There is a constraint that coro.suspend instructions need to be in their own blocks. The coro split pass initially creates IR that obeys this constraint (which is later checked). Sinking rematerializable instructions into these blocks breaks that constraint. Instead rematerialize in the predecessor block to the suspend's single predecessor block. Differential Revision: https://reviews.llvm.org/D104051
1 parent f58afc8 commit 6edded5

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

llvm/lib/Transforms/Coroutines/CoroFrame.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,11 +1964,16 @@ static void rewriteMaterializableInstructions(IRBuilder<> &IRB,
19641964
for (Instruction *U : E.second) {
19651965
// If we have not seen this block, materialize the value.
19661966
if (CurrentBlock != U->getParent()) {
1967-
CurrentBlock = U->getParent();
1967+
1968+
bool IsInCoroSuspendBlock = isa<AnyCoroSuspendInst>(U);
1969+
CurrentBlock = IsInCoroSuspendBlock
1970+
? U->getParent()->getSinglePredecessor()
1971+
: U->getParent();
19681972
CurrentMaterialization = cast<Instruction>(Def)->clone();
19691973
CurrentMaterialization->setName(Def->getName());
19701974
CurrentMaterialization->insertBefore(
1971-
&*CurrentBlock->getFirstInsertionPt());
1975+
IsInCoroSuspendBlock ? CurrentBlock->getTerminator()
1976+
: &*CurrentBlock->getFirstInsertionPt());
19721977
}
19731978
if (auto *PN = dyn_cast<PHINode>(U)) {
19741979
assert(PN->getNumIncomingValues() == 1 &&

llvm/test/Transforms/Coroutines/coro-async.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: opt < %s -enable-coroutines -passes='default<O2>' -S | FileCheck --check-prefixes=CHECK %s
2-
2+
; RUN: opt < %s -enable-coroutines -O0 -S
33
target datalayout = "p:64:64:64"
44

55
%async.task = type { i64 }
@@ -212,11 +212,12 @@ entry:
212212
store i8* %async.ctxt, i8** %callee_context.caller_context.addr
213213
%resume_proj_fun = bitcast i8*(i8*)* @resume_context_projection to i8*
214214
%callee = bitcast void(i8*, %async.task*, %async.actor*)* @asyncSuspend to i8*
215+
%task.casted = bitcast i8* %arg0 to %async.task*
215216
%res = call {i8*, i8*, i8*} (i32, i8*, i8*, ...) @llvm.coro.suspend.async(i32 2,
216217
i8* %resume.func_ptr,
217218
i8* %resume_proj_fun,
218219
void (i8*, i8*, %async.task*, %async.actor*)* @my_async_function.my_other_async_function_fp.apply,
219-
i8* %callee, i8* %callee_context, %async.task* %task, %async.actor *%actor), !dbg !9
220+
i8* %callee, i8* %callee_context, %async.task* %task.casted, %async.actor *%actor), !dbg !9
220221

221222
%continuation_task_arg = extractvalue {i8*, i8*, i8*} %res, 0
222223
%task.2 = bitcast i8* %continuation_task_arg to %async.task*
@@ -234,7 +235,7 @@ entry:
234235
i8* %resume.func_ptr.1,
235236
i8* %resume_proj_fun.2,
236237
void (i8*, i8*, %async.task*, %async.actor*)* @my_async_function.my_other_async_function_fp.apply,
237-
i8* %callee.2, i8* %callee_context, %async.task* %task, %async.actor *%actor)
238+
i8* %callee.2, i8* %callee_context, %async.task* %task.casted, %async.actor *%actor)
238239

239240
call void @llvm.coro.async.context.dealloc(i8* %callee_context)
240241
%continuation_actor_arg = extractvalue {i8*, i8*, i8*} %res.2, 1
@@ -542,6 +543,7 @@ declare swiftcc void @asyncReturn(i8*, %async.task*, %async.actor*)
542543
declare swiftcc void @asyncSuspend(i8*, %async.task*, %async.actor*)
543544
declare i8* @llvm.coro.async.resume()
544545
declare void @llvm.coro.async.size.replace(i8*, i8*)
546+
declare i8* @hide(i8*)
545547

546548
!llvm.dbg.cu = !{!2}
547549
!llvm.module.flags = !{!0}

0 commit comments

Comments
 (0)