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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits