[clang] 5524a21 - [CIR] Add cir.coro.intrinsic.resume/destroy/done Ops (#222210)

via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 9 18:13:57 PDT 2026


Author: Andres-Salamanca
Date: 2026-09-09T20:13:52-05:00
New Revision: 5524a2192f6d6b29f5be1ff72947e99bf7e27ad9

URL: https://github.com/llvm/llvm-project/commit/5524a2192f6d6b29f5be1ff72947e99bf7e27ad9
DIFF: https://github.com/llvm/llvm-project/commit/5524a2192f6d6b29f5be1ff72947e99bf7e27ad9.diff

LOG: [CIR] Add cir.coro.intrinsic.resume/destroy/done Ops (#222210)

Adds CoroResumeOp, CoroDestroyOp, and CoroDoneOp, representing
llvm.coro.resume, llvm.coro.destroy, and llvm.coro.done respectively.

Added: 
    

Modified: 
    clang/include/clang/CIR/Dialect/IR/CIROps.td
    clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
    clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
    clang/lib/CIR/CodeGen/CIRGenFunction.h
    clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index d1047ab88b942..449af063cf9ac 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -5019,6 +5019,49 @@ def CIR_CoroPromiseOp : CIR_CoroIntrinsicOp<"promise",
   let llvmOp = "CoroPromiseOp";
 }
 
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic ResumeOp
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroResumeOp : CIR_CoroIntrinsicOp<"resume",
+    (ins CIR_VoidPtrType:$handle), (outs )> {
+  let summary = "Represents llvm.coro.resume";
+  let description = [{
+    Resumes a suspended coroutine identified by `handle`. Resuming a
+    coroutine that is not currently suspended is undefined behavior.
+  }];
+  let llvmOp = "CoroResumeOp";
+}
+
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic DestroyOp
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroDestroyOp : CIR_CoroIntrinsicOp<"destroy",
+    (ins CIR_VoidPtrType:$handle), (outs )> {
+  let summary = "Represents llvm.coro.destroy";
+  let description = [{
+    Destroys a suspended coroutine identified by `handle`. Destroying a
+    coroutine that is not currently suspended is undefined behavior.
+  }];
+  let llvmOp = "CoroDestroyOp";
+}
+
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic DoneOp
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroDoneOp : CIR_CoroIntrinsicOp<"done", (ins CIR_VoidPtrType:$handle),
+    (outs CIR_BoolType:$done)> {
+  let summary = "Represents llvm.coro.done";
+  let description = [{
+    Checks whether the coroutine identified by `handle` is currently
+    suspended at its final suspend point. `handle` must be a handle to a
+    suspended coroutine.
+  }];
+  let llvmOp = "CoroDoneOp";
+}
+
 //===----------------------------------------------------------------------===//
 // CopyOp
 //===----------------------------------------------------------------------===//

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index d4c17d3c5f24f..ee0b4fa49d4c6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1735,18 +1735,19 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
     return RValue::get(emitCoroEndBuiltinCall(e).getResult());
   case Builtin::BI__builtin_coro_promise:
     return RValue::get(emitCoroPromiseBuiltinCall(e).getResult());
-  case Builtin::BI__builtin_coro_resume:
-    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_resume NYI");
-    return getUndefRValue(e->getType());
+  case Builtin::BI__builtin_coro_resume: {
+    emitCoroResumeBuiltinCall(e);
+    return RValue::get(nullptr);
+  }
   case Builtin::BI__builtin_coro_noop:
     cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_noop NYI");
     return getUndefRValue(e->getType());
-  case Builtin::BI__builtin_coro_destroy:
-    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_destroy NYI");
-    return getUndefRValue(e->getType());
+  case Builtin::BI__builtin_coro_destroy: {
+    emitCoroDestroyBuiltinCall(e);
+    return RValue::get(nullptr);
+  }
   case Builtin::BI__builtin_coro_done:
-    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_done NYI");
-    return getUndefRValue(e->getType());
+    return RValue::get(emitCoroDoneBuiltinCall(e).getResult());
   case Builtin::BI__builtin_coro_suspend:
     cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_suspend NYI");
     return getUndefRValue(e->getType());

diff  --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 7004f2d7750e6..6f2c0e33ce1d9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -321,6 +321,25 @@ CIRGenFunction::emitCoroPromiseBuiltinCall(const CallExpr *e) {
   return coroPromise;
 }
 
+cir::CoroDoneOp CIRGenFunction::emitCoroDoneBuiltinCall(const CallExpr *e) {
+  mlir::Location loc = getLoc(e->getBeginLoc());
+  return cir::CoroDoneOp::create(cgm.getBuilder(), loc,
+                                 emitScalarExpr(e->getArg(0)));
+}
+
+cir::CoroResumeOp CIRGenFunction::emitCoroResumeBuiltinCall(const CallExpr *e) {
+  mlir::Location loc = getLoc(e->getBeginLoc());
+  return cir::CoroResumeOp::create(cgm.getBuilder(), loc,
+                                   emitScalarExpr(e->getArg(0)));
+}
+
+cir::CoroDestroyOp
+CIRGenFunction::emitCoroDestroyBuiltinCall(const CallExpr *e) {
+  mlir::Location loc = getLoc(e->getBeginLoc());
+  return cir::CoroDestroyOp::create(cgm.getBuilder(), loc,
+                                    emitScalarExpr(e->getArg(0)));
+}
+
 static mlir::LogicalResult
 coroutineBodyExceptionHelper(CIRGenFunction &cgf, const CoroutineBodyStmt &s) {
 

diff  --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 8547a77e86faf..5a4529821f5ef 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1916,6 +1916,9 @@ class CIRGenFunction : public CIRGenTypeCache {
   cir::CoroAllocOp emitCoroAllocBuiltinCall(const CallExpr *e);
   cir::CoroBeginOp emitCoroBeginBuiltinCall(const CallExpr *e);
   cir::CoroPromiseOp emitCoroPromiseBuiltinCall(const CallExpr *e);
+  cir::CoroDoneOp emitCoroDoneBuiltinCall(const CallExpr *e);
+  cir::CoroResumeOp emitCoroResumeBuiltinCall(const CallExpr *e);
+  cir::CoroDestroyOp emitCoroDestroyBuiltinCall(const CallExpr *e);
 
   cir::CoroSizeOp emitCoroSizeBuiltinCall(const CallExpr *e);
   cir::CoroFreeOp emitCoroFreeBuiltin(const CallExpr *e);

diff  --git a/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp b/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
index 564dc4e49a9cf..db22a0fbaee8b 100644
--- a/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
+++ b/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
@@ -44,14 +44,17 @@ void f(int n) {
   // LLVM: %[[MEM:.*]] = call noundef ptr @_Z7myAllocx(i64 noundef %[[SIZE]])
   // LLVM: %[[FRAME:.*]] = call ptr @llvm.coro.begin(token %[[COROID]], ptr %[[MEM]])
 
-  // TODO(CIR):
-  //__builtin_coro_resume(__builtin_coro_frame());
+  __builtin_coro_resume(__builtin_coro_frame());
+  // CIR: cir.coro.intrinsic.resume(%[[FRAME]]) : (!cir.ptr<!void>)
+  // LLVM-NEXT: call void @llvm.coro.resume(ptr %[[FRAME]])
 
-  // TODO(CIR):
-  //__builtin_coro_destroy(__builtin_coro_frame());
+  __builtin_coro_destroy(__builtin_coro_frame());
+  // CIR: cir.coro.intrinsic.destroy(%[[FRAME]]) : (!cir.ptr<!void>)
+  // LLVM-NEXT: call void @llvm.coro.destroy(ptr %[[FRAME]])
 
-  // TODO(CIR):
-  //__builtin_coro_done(__builtin_coro_frame());
+  __builtin_coro_done(__builtin_coro_frame());
+  // CIR: cir.coro.intrinsic.done(%[[FRAME]]) : (!cir.ptr<!void>) -> !cir.bool
+  // LLVM-NEXT: call i1 @llvm.coro.done(ptr %[[FRAME]])
 
   __builtin_coro_promise(__builtin_coro_frame(), 48, 0);
   // CIR: %[[ALIGN:.*]] = cir.const #cir.int<48> : !s32i


        


More information about the cfe-commits mailing list