[Mlir-commits] [mlir] Extend `retcon.once` coroutines lowering to optionally produce a normal result (PR #66333)
Anton Korobeynikov
llvmlistbot at llvm.org
Thu Sep 14 19:17:02 PDT 2023
asl wrote:
> > > Out of curiousity, why don't we have the problem in the normal return continuation ABI?
> >
> >
> > The problem happens when the value is directly used in `coro.end` intrinsic. For example, when we're forwarding coroutine argument as a result. Or, when the value itself is computed before the suspend. Everything else is correctly handled by the present code due to BB split (the corresponding instructions appear in `Cleanup` block for example and correctly spilled).
>
> I still don't understand the motivation fully. Do you say we don't have the problem naturally? Or could you show some motivation examples? (In LLVM IR?)
This one is problematic:
```llvm
define {ptr, ptr} @g(ptr %buffer, ptr %ptr, i8 %val) presplitcoroutine {
entry:
%temp = alloca i32, align 4
%id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype2, ptr @allocate, ptr @deallocate)
%hdl = call ptr @llvm.coro.begin(token %id, ptr null)
%oldvalue = load i32, ptr %ptr
store i32 %oldvalue, ptr %temp
%unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %temp)
br i1 %unwind, label %cleanup, label %cont
cont:
%newvalue = load i32, ptr %temp
store i32 %newvalue, ptr %ptr
br label %cleanup
cleanup:
call i1 (ptr, i1, ...) @llvm.coro.end(ptr %hdl, i1 0, i8 %val)
unreachable
}
```
but this one is not:
```llvm
define {ptr, ptr} @g(ptr %buffer, ptr %ptr, i8 %val) presplitcoroutine {
entry:
%temp = alloca i32, align 4
%id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype2, ptr @allocate, ptr @deallocate)
%hdl = call ptr @llvm.coro.begin(token %id, ptr null)
%oldvalue = load i32, ptr %ptr
store i32 %oldvalue, ptr %temp
%unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %temp)
br i1 %unwind, label %cleanup, label %cont
cont:
%newvalue = load i32, ptr %temp
store i32 %newvalue, ptr %ptr
br label %cleanup
cleanup:
%newval = add i8 %val, 42
call i1 (ptr, i1, ...) @llvm.coro.end(ptr %hdl, i1 0, i8 %newval)
unreachable
}
```
This one is problematic as well:
```llvm
define {ptr, ptr} @g(ptr %buffer, ptr %ptr, i8 %val) presplitcoroutine {
entry:
%temp = alloca i32, align 4
%id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer, ptr @prototype2, ptr @allocate, ptr @deallocate)
%hdl = call ptr @llvm.coro.begin(token %id, ptr null)
%oldvalue = load i32, ptr %ptr
store i32 %oldvalue, ptr %temp
%newval = add i8 %val, 42
%unwind = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr %temp)
br i1 %unwind, label %cleanup, label %cont
cont:
%newvalue = load i32, ptr %temp
store i32 %newvalue, ptr %ptr
br label %cleanup
cleanup:
call i1 (ptr, i1, ...) @llvm.coro.end(ptr %hdl, i1 0, i8 %newval)
unreachable
}
```
All these are "new" cases I would say, everything else is handled via current split approach.
https://github.com/llvm/llvm-project/pull/66333
More information about the Mlir-commits
mailing list