[clang] [CIR] Add coroutine cleanup handling and update co_return semantics (PR #189281)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 6 13:54:51 PDT 2026
================
@@ -4120,6 +4120,67 @@ def CIR_AwaitOp : CIR_Op<"await",[
let hasVerifier = 1;
}
+//===----------------------------------------------------------------------===//
+// CoroBody
+//===----------------------------------------------------------------------===//
+def CIR_CoroBodyOp : CIR_Op<"coro.body", [
+ DeclareOpInterfaceMethods<RegionBranchOpInterface, ["getSuccessorInputs"]>,
+ RecursivelySpeculatable, AutomaticAllocationScope, NoRegionArguments,
+ RecursiveMemoryEffects
+]> {
+ let summary = "Region containing the user-authored coroutine body";
+ let description = [{
+ The `cir.coro.body` operation models the region where the user-authored
+ coroutine code is emitted.
+
+ This operation serves as a structural boundary separating the coroutine
+ setup and teardown logic (e.g. initial suspend, final suspend, and cleanup)
+ from the user-provided statements inside the coroutine.
+
+ The body region contains the code corresponding to the original function
+ body, including `co_await` and `co_return` expressions. In particular,
+ `cir.co_return` operations inside this region mark coroutine exit points
+ and introduce structured control flow that transfers execution to the
+ final suspend point of the coroutine.
+ }];
+
+ let regions = (region AnyRegion:$bodyRegion);
+
+ let skipDefaultBuilders = 1;
+
+ let builders = [
+ OpBuilder<(ins "BuilderCallbackRef":$bodyBuilder)>
+ ];
+
+ let assemblyFormat = [{
+ $bodyRegion attr-dict
+ }];
+
+ let hasLLVMLowering = false;
+ let hasVerifier = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// CoReturnOp
+//===----------------------------------------------------------------------===//
+
+def CIR_CoReturnOp : CIR_Op<"co_return", [
+ NoMemoryEffect, Pure, Terminator
----------------
Andres-Salamanca wrote:
Regarding the `HasParent` trait, I didn’t use it intentionally because it only checks the direct parent of the op. In our case, that is too restrictive.
For example, in scenarios like:
```mlir
"cir.coro.body"() ({
"cir.scope"() ({
...
"cir.if"(%0) ({
...
"cir.co_return"()
}, {
})
"cir.yield"()
})
...
})
```
Here, `cir.co_return` is inside the `cir.if`, so using `HasParent` would fail with:
`'cir.co_return' op expects parent op 'cir.coro.body'`.
That’s why I didn’t use `HasParent`. Instead, the verifier allows the operation to be nested, as you mentioned in this comment https://github.com/llvm/llvm-project/pull/189281#discussion_r3019122125.
https://github.com/llvm/llvm-project/pull/189281
More information about the cfe-commits
mailing list