@@ -151,8 +151,8 @@ lowerings:
151151- In yield-once returned-continuation lowering, the coroutine must
152152 suspend itself exactly once (or throw an exception). The ramp
153153 function returns a continuation function pointer and yielded
154- values, but the continuation function simply returns ` void `
155- when the coroutine has run to completion.
154+ values, the continuation function may optionally return ordinary
155+ results when the coroutine has run to completion.
156156
157157The coroutine frame is maintained in a fixed-size buffer that is
158158passed to the `coro.id ` intrinsic, which guarantees a certain size
@@ -303,7 +303,7 @@ The LLVM IR for this coroutine looks like this:
303303 call void @free(ptr %mem)
304304 br label %suspend
305305 suspend:
306- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false)
306+ %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none )
307307 ret ptr %hdl
308308 }
309309
@@ -630,7 +630,7 @@ store the current value produced by a coroutine.
630630 call void @free(ptr %mem)
631631 br label %suspend
632632 suspend:
633- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false)
633+ %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none )
634634 ret ptr %hdl
635635 }
636636
@@ -1312,8 +1312,8 @@ Arguments:
13121312""""""""""
13131313
13141314As for ``llvm.core.id.retcon ``, except that the return type of the
1315- continuation prototype must be ` void ` instead of matching the
1316- coroutine's return type.
1315+ continuation prototype must represent the normal return type of the continuation
1316+ (instead of matching the coroutine's return type) .
13171317
13181318Semantics:
13191319""""""""""
@@ -1326,7 +1326,7 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine.
13261326^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13271327::
13281328
1329- declare i1 @llvm.coro.end(ptr <handle>, i1 <unwind>)
1329+ declare i1 @llvm.coro.end(ptr <handle>, i1 <unwind>, token <result.token> )
13301330
13311331Overview:
13321332"""""""""
@@ -1347,6 +1347,12 @@ The second argument should be `true` if this coro.end is in the block that is
13471347part of the unwind sequence leaving the coroutine body due to an exception and
13481348`false ` otherwise.
13491349
1350+ Non-trivial (non-none) token argument can only be specified for unique-suspend
1351+ returned-continuation coroutines where it must be a token value produced by
1352+ '``llvm.coro.end.results ``' intrinsic.
1353+
1354+ Only none token is allowed for coro.end calls in unwind sections
1355+
13501356Semantics:
13511357""""""""""
13521358The purpose of this intrinsic is to allow frontends to mark the cleanup and
@@ -1378,7 +1384,7 @@ For landingpad based exception model, it is expected that frontend uses the
13781384.. code-block :: llvm
13791385
13801386 ehcleanup:
1381- %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true)
1387+ %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true, token none )
13821388 br i1 %InResumePart, label %eh.resume, label %cleanup.cont
13831389
13841390 cleanup.cont:
@@ -1403,7 +1409,7 @@ referring to an enclosing cleanuppad as follows:
14031409
14041410 ehcleanup:
14051411 %tok = cleanuppad within none []
1406- %unused = call i1 @llvm.coro.end(ptr null, i1 true) [ "funclet"(token %tok) ]
1412+ %unused = call i1 @llvm.coro.end(ptr null, i1 true, token none ) [ "funclet"(token %tok) ]
14071413 cleanupret from %tok unwind label %RestOfTheCleanup
14081414
14091415 The `CoroSplit ` pass, if the funclet bundle is present, will insert
@@ -1428,6 +1434,53 @@ The following table summarizes the handling of `coro.end`_ intrinsic.
14281434| | Landingpad | mark coroutine as done | mark coroutine done |
14291435+------------+-------------+------------------------+---------------------------------+
14301436
1437+ .. _coro.end.results :
1438+
1439+ 'llvm.coro.end.results' Intrinsic
1440+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1441+ ::
1442+
1443+ declare token @llvm.coro.end.results(...)
1444+
1445+ Overview:
1446+ """""""""
1447+
1448+ The '``llvm.coro.end.results ``' intrinsic captures values to be returned from
1449+ unique-suspend returned-continuation coroutines.
1450+
1451+ Arguments:
1452+ """"""""""
1453+
1454+ The number of arguments must match the return type of the continuation function:
1455+
1456+ - if the return type of the continuation function is ``void `` there must be no
1457+ arguments
1458+
1459+ - if the return type of the continuation function is a ``struct ``, the arguments
1460+ will be of element types of that ``struct `` in order;
1461+
1462+ - otherwise, it is just the return value of the continuation function.
1463+
1464+ .. code-block :: llvm
1465+
1466+ define {ptr, ptr} @g(ptr %buffer, ptr %ptr, i8 %val) presplitcoroutine {
1467+ entry:
1468+ %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer,
1469+ ptr @prototype,
1470+ ptr @allocate, ptr @deallocate)
1471+ %hdl = call ptr @llvm.coro.begin(token %id, ptr null)
1472+
1473+ ...
1474+
1475+ cleanup:
1476+ %tok = call token (...) @llvm.coro.end.results(i8 %val)
1477+ call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok)
1478+ unreachable
1479+
1480+ ...
1481+
1482+ declare i8 @prototype(ptr, i1 zeroext)
1483+
14311484
14321485 'llvm.coro.end.async' Intrinsic
14331486^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0 commit comments