[clang] [CIR] Add structured control flow for coroutine suspend points (PR #213191)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 31 09:55:01 PDT 2026


================
@@ -4818,13 +4702,107 @@ def CIR_CoReturnOp : CIR_Op<"co_return", [
   let hasLLVMLowering = false;
 }
 
+//===----------------------------------------------------------------------===//
+// CoroSuspendPoint
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroSuspendPoint : CIR_Op<"coro.suspend_point", [
+  Pure, Terminator, HasParent<"AwaitOp">, HasAncestor<"CoroRetPointOp">
+]> {
+  let summary = "Marks the point where a coroutine actually suspends";
+  let description = [{
+    Terminates the `suspend` region of a `cir.await` op, marking the exact
+    point where control returns to the caller/resumer if the coroutine
+    decides to suspend.
+
+    This op must appear inside the `suspend` region of a `cir.await`, and
+    that `cir.await` must in turn be nested within a `cir.coro.ret_point`.
+    During lowering to FlattenCFG, `cir.coro.suspend_point` becomes the
+    branch target that routes control to one of three destinations
+    depending on how the coroutine resumes: the resume block (normal
+    continuation), the cleanup/destroy block, or the ret/exit block that
+    hands control back to the caller.
+
+    Example:
+    ```mlir
+    cir.await(user, ready : {
+      ...
+      cir.condition(%ready)
+    }, suspend : {
+      ...
+      cir.coro.suspend_point
+    }, resume : {
+      ...
+      cir.yield
+    },)
+    ```
+  }];
+
+  let assemblyFormat = [{
+    attr-dict
+  }];
+
+  let hasLLVMLowering = false;
+}
+
+//===----------------------------------------------------------------------===//
+// CoroRetPoint
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroRetPointOp : CIR_Op<"coro.ret_point", [
----------------
andykaylor wrote:

I don't like the name of this operation. How can a "point" have regions?

Would it be possible to achieve this by extending the existing `coro.body` operation? Maybe something like this:

```
cir.coroutine :  prolog{
} body {
  cir.await(user, ready : {
     cir.condition(%arg0)
   }, suspend : {
     cir.coro.suspend_point
   }, resume : {
     cir.yield
   },)
   cir.co_return
} epilog {
  cir.yield
}
```

https://github.com/llvm/llvm-project/pull/213191


More information about the cfe-commits mailing list