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

Reply via email to