https://github.com/Andres-Salamanca updated 
https://github.com/llvm/llvm-project/pull/211699

>From 9be431ac12acc2483243016805c562261cc3ff91 Mon Sep 17 00:00:00 2001
From: Andres Salamanca <[email protected]>
Date: Thu, 23 Jul 2026 19:07:57 -0500
Subject: [PATCH 1/2] [CIR] Change previous coroutine builtins to have their
 own coro intrinsic ops

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 125 +++++++++++
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       |  48 +++--
 clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp     | 204 +++++++++---------
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  15 +-
 clang/lib/CIR/CodeGen/CIRGenModule.h          |   6 -
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  42 ++++
 clang/test/CIR/CodeGen/coro-builtins-err.cpp  |  10 +
 clang/test/CIR/CodeGen/coro-builtins.cpp      |  51 +++++
 clang/test/CIR/CodeGen/coro-task.cpp          |  22 +-
 9 files changed, 378 insertions(+), 145 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/coro-builtins-err.cpp
 create mode 100644 clang/test/CIR/CodeGen/coro-builtins.cpp

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 762ef56248e4c..8228b89765ede 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4619,6 +4619,131 @@ def CIR_CoReturnOp : CIR_Op<"co_return", [
   let hasLLVMLowering = false;
 }
 
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsics
+//===----------------------------------------------------------------------===//
+
+class CIR_CoroIntrinsicOp<string mnem, dag ins, dag outs,
+                          list<Trait> traits = []>
+                          : CIR_Op<"coro.intrinsic." # mnem, traits> {
+  let hasLLVMLowering = 1;
+  let arguments = ins;
+  let results = outs;
+
+  let assemblyFormat = [{
+    `(` operands `)` `:` functional-type(operands, results) attr-dict
+  }];
+}
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic IdOp
+//===----------------------------------------------------------------------===//
+
+// TODO: This operation should return an MLIR `token` once the type becomes
+// available. `CIR_UInt32` is used as a temporary placeholder.
+def CIR_CoroIntrinsicIdOp : CIR_CoroIntrinsicOp<"id",
+    (ins CIR_AnyIntType:$align, CIR_VoidPtrType:$promise,
+         CIR_VoidPtrType:$coroaddr, CIR_VoidPtrType:$fnaddrs),
+    (outs CIR_UInt32:$result)> {
+  let summary = "Represents llvm.coro.id";
+  let description = [{
+    Marks the beginning of a coroutine's lifetime and identifies it to the
+    rest of the coroutine intrinsics. Takes the required alignment of the
+    coroutine frame, a pointer to the coroutine promise (or null if none),
+    the address of the coroutine function itself, and an opaque pointer used
+    by the frontend to convey additional information to the coroutine
+    lowering passes (or null).
+
+    The result is a token that must be passed to every other
+    `coro.intrinsic.*` operation associated with this coroutine
+    (`coro.alloc`, `coro.begin`, `coro.free`, etc.), tying them all to the
+    same coroutine instance.
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic AllocOp
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroIntrinsicAllocOp : CIR_CoroIntrinsicOp<"alloc",
+    (ins CIR_AnyIntType:$id),
+    (outs CIR_AnyBoolType:$result)> {
+  let summary = "Represents llvm.coro.alloc";
+  let description = [{
+    Queries whether the coroutine identified by `id` needs a dynamically
+    allocated frame. Returns `true` if the coroutine frame must be allocated,
+    or `false` otherwise.
+  }];
+}
+
+// TODO: Replace the `id` operand with MLIR's `token` type once it becomes
+// available. This operand corresponds to the token produced by `llvm.coro.id`.
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic BeginOp
+//===----------------------------------------------------------------------===//
+def CIR_CoroIntrinsicBeginOp : CIR_CoroIntrinsicOp<"begin",
+    (ins CIR_UInt32:$id, CIR_VoidPtrType:$coroframeAddr),
+    (outs CIR_VoidPtrType:$result)> {
+  let summary = "Represents llvm.coro.begin";
+  let description = [{
+    Initializes the coroutine frame using `coroframeAddr`. `id` is the token
+    from `coro.intrinsic.id`, and `coroframeAddr` points to the memory used
+    for the coroutine frame. Returns the coroutine handle.
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic EndOp
+//===----------------------------------------------------------------------===//
+def CIR_CoroIntrinsicEndOp : CIR_CoroIntrinsicOp<"end",
+    (ins CIR_VoidPtrType:$handle, CIR_AnyBoolType:$unwind),
+    (outs CIR_AnyBoolType:$result)> {
+  let summary = "Represents llvm.coro.end";
+  let description = [{
+    Marks a point at which a coroutine must be suspended or destroyed for the
+    last time, e.g. right before the coroutine returns control to its caller
+    for the final time, or along an exceptional unwind path. `handle` is the
+    coroutine handle produced by `coro.intrinsic.begin`, and `unwind`
+    indicates whether this occurrence of `coro.intrinsic.end` lies on the
+    unwind path (`true`) or the normal control-flow path (`false`).
+  }];
+}
+
+// TODO: Replace the `id` operand with MLIR's `token` type once it becomes
+// available. This operand corresponds to the token produced by `llvm.coro.id`.
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic FreeOp
+//===----------------------------------------------------------------------===//
+def CIR_CoroIntrinsicFreeOp : CIR_CoroIntrinsicOp<"free",
+    (ins CIR_AnyIntType:$id, CIR_VoidPtrType:$coroframe),
+    (outs CIR_VoidPtrType:$result)> {
+  let summary = "Represents llvm.coro.free";
+  let description = [{
+    Given the coroutine identified by `id` and its frame pointer `coroframe`
+    (the handle from `coro.intrinsic.begin`), returns the pointer that must
+    be passed to the deallocation function to free the coroutine frame, or a
+    null pointer if the coroutine frame was not dynamically allocated.
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic SizeOp
+//===----------------------------------------------------------------------===//
+def CIR_CoroIntrinsicSizeOp : CIR_CoroIntrinsicOp<"size",
+    (ins), (outs CIR_UInt64:$result)> {
+  let summary = "Represents llvm.coro.size";
+  let description = [{
+    Returns the size, in bytes, of the coroutine frame.
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic IsInRampOp
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroIntrinsicIsInRampOp : CIR_CoroIntrinsicOp<"is_in_ramp",
+    (ins), (outs CIR_AnyBoolType:$result), [Pure]> {
+  let summary = "";
+}
 
 
//===----------------------------------------------------------------------===//
 // CopyOp
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 3c48b8b67d9ee..abaebd1d2d273 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1343,34 +1343,54 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     return emitRotate(e, /*isRotateLeft=*/false);
 
   case Builtin::BI__builtin_coro_id:
+    return RValue::get(emitCoroIDBuiltinCall(e).getResult());
+  case Builtin::BI__builtin_coro_alloc: {
+    cir::CoroIntrinsicAllocOp coroAlloc = emitCoroAllocBuiltinCall(e);
+    return coroAlloc ? RValue::get(coroAlloc.getResult())
+                     : getUndefRValue(e->getType());
+  }
+  case Builtin::BI__builtin_coro_begin: {
+    cir::CoroIntrinsicBeginOp coroBeg = emitCoroBeginBuiltinCall(e);
+    return coroBeg ? RValue::get(coroBeg.getResult())
+                   : getUndefRValue(e->getType());
+  }
+
   case Builtin::BI__builtin_coro_promise:
+    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_promise NYI");
+    return getUndefRValue(e->getType());
   case Builtin::BI__builtin_coro_resume:
+    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_resume NYI");
+    return getUndefRValue(e->getType());
   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_done:
-  case Builtin::BI__builtin_coro_alloc:
-  case Builtin::BI__builtin_coro_begin:
+    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_done NYI");
+    return getUndefRValue(e->getType());
   case Builtin::BI__builtin_coro_end:
+    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_end NYI");
+    return getUndefRValue(e->getType());
   case Builtin::BI__builtin_coro_suspend:
+    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_suspend NYI");
+    return getUndefRValue(e->getType());
   case Builtin::BI__builtin_coro_align:
-    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_id like NYI");
+    cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_align NYI");
     return getUndefRValue(e->getType());
 
   case Builtin::BI__builtin_coro_frame: {
     return emitCoroutineFrame();
   }
-  case Builtin::BI__builtin_coro_free:
-    return RValue::get(emitCoroFreeBuiltin(e).getResult());
+  case Builtin::BI__builtin_coro_free: {
+    cir::CoroIntrinsicFreeOp coroFree = emitCoroFreeBuiltin(e);
+    return coroFree ? RValue::get(coroFree.getResult())
+                    : getUndefRValue(e->getType());
+  }
+
   case Builtin::BI__builtin_coro_size: {
-    GlobalDecl gd{fd};
-    mlir::Type ty = cgm.getTypes().getFunctionType(
-        cgm.getTypes().arrangeGlobalDeclaration(gd));
-    const auto *nd = cast<NamedDecl>(gd.getDecl());
-    cir::FuncOp fnOp =
-        cgm.getOrCreateCIRFunction(nd->getName(), ty, gd, /*ForVTable=*/false);
-    fnOp.setBuiltin(true);
-    return emitCall(e->getCallee()->getType(), CIRGenCallee::forDirect(fnOp), 
e,
-                    returnValue);
+    return RValue::get(emitCoroSizeBuiltinCall(e).getResult());
   }
 
   case Builtin::BI__builtin_constant_p: {
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 3dd71a8ad3b6c..2aa199c347152 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -28,7 +28,7 @@ struct clang::CIRGen::CGCoroData {
   cir::AwaitKind currentAwaitKind = cir::AwaitKind::Init;
   // Stores the __builtin_coro_id emitted in the function so that we can supply
   // it as the first argument to other builtins.
-  cir::CallOp coroId = nullptr;
+  cir::CoroIntrinsicIdOp coroId = nullptr;
 
   // Stores the result of __builtin_coro_begin call.
   mlir::Value coroBegin = nullptr;
@@ -42,13 +42,18 @@ struct clang::CIRGen::CGCoroData {
 
   // Stores the last emitted coro.free for the deallocate expressions, we use 
it
   // to wrap dealloc code with if(auto mem = coro.free) dealloc(mem).
-  cir::CallOp lastCoroFree = nullptr;
+  cir::CoroIntrinsicFreeOp lastCoroFree = nullptr;
 
   // A temporary bool alloca that stores whether 'await_resume' threw an
   // exception. If it did, 'true' is stored in this variable, and the coroutine
   // body must be skipped. If the promise type does not define an exception
   // handler, this is null.
   Address resumeEHVar = Address::invalid();
+  //
+  // If coro.id came from the builtin, remember the expression to give better
+  // diagnostic. If CoroIdExpr is nullptr, the coro.id was created by
+  // EmitCoroutineBody.
+  CallExpr const *coroIdExpr = nullptr;
 };
 
 // Defining these here allows to keep CGCoroData private to this file.
@@ -139,7 +144,7 @@ struct CallCoroDelete final : public EHScopeStack::Cleanup {
     }
 
     CIRGenBuilderTy &builder = cgf.getBuilder();
-    cir::CallOp coroFree = cgf.curCoro.data->lastCoroFree;
+    cir::CoroIntrinsicFreeOp coroFree = cgf.curCoro.data->lastCoroFree;
 
     if (!coroFree) {
       cgf.cgm.error(deallocate->getBeginLoc(),
@@ -182,11 +187,22 @@ RValue CIRGenFunction::emitCoroutineFrame() {
 
 static void createCoroData(CIRGenFunction &cgf,
                            CIRGenFunction::CGCoroInfo &curCoro,
-                           cir::CallOp coroId) {
-  assert(!curCoro.data && "EmitCoroutineBodyStatement called twice?");
+                           cir::CoroIntrinsicIdOp coroId,
+                           CallExpr const *coroIdExpr = nullptr) {
+
+  if (curCoro.data) {
+    if (curCoro.data->coroIdExpr)
+      cgf.cgm.error(coroIdExpr->getBeginLoc(),
+                    "only one __builtin_coro_id can be used in a function");
+    else
+      llvm_unreachable("EmitCoroutineBodyStatement called twice?");
+
+    return;
+  }
 
   curCoro.data = std::make_unique<CGCoroData>();
   curCoro.data->coroId = coroId;
+  curCoro.data->coroIdExpr = coroIdExpr;
 }
 
 static mlir::LogicalResult
@@ -212,113 +228,84 @@ emitBodyAndFallthrough(CIRGenFunction &cgf, const 
CoroutineBodyStmt &s,
   return mlir::success();
 }
 
-cir::CallOp CIRGenFunction::emitCoroIDBuiltinCall(mlir::Location loc,
-                                                  mlir::Value nullPtr) {
-  cir::IntType int32Ty = builder.getUInt32Ty();
-
-  const TargetInfo &ti = cgm.getASTContext().getTargetInfo();
-  unsigned newAlign = ti.getNewAlign() / ti.getCharWidth();
+cir::CoroIntrinsicIdOp
+CIRGenFunction::emitCoroIDBuiltinCall(const CallExpr *e) {
+  mlir::Location loc = getLoc(e->getBeginLoc());
 
-  mlir::Operation *builtin = cgm.getGlobalValue(cgm.builtinCoroId);
-
-  cir::FuncOp fnOp;
-  if (!builtin) {
-    fnOp = cgm.createCIRBuiltinFunction(
-        loc, cgm.builtinCoroId,
-        cir::FuncType::get({int32Ty, voidPtrTy, voidPtrTy, voidPtrTy}, 
int32Ty),
-        /*FD=*/nullptr);
-    assert(fnOp && "should always succeed");
-  } else {
-    fnOp = cast<cir::FuncOp>(builtin);
+  llvm::SmallVector<mlir::Value, 4> args;
+  for (auto const *arg : e->arguments()) {
+    args.push_back(emitScalarExpr(arg));
   }
-
-  return builder.createCallOp(loc, fnOp,
-                              mlir::ValueRange{builder.getUInt32(newAlign, 
loc),
-                                               nullPtr, nullPtr, nullPtr});
+  auto coroId = cir::CoroIntrinsicIdOp::create(cgm.getBuilder(), loc, args);
+  createCoroData(*this, curCoro, coroId, e);
+  return coroId;
 }
 
-cir::CallOp CIRGenFunction::emitCoroAllocBuiltinCall(mlir::Location loc) {
-  cir::BoolType boolTy = builder.getBoolTy();
-
-  mlir::Operation *builtin = cgm.getGlobalValue(cgm.builtinCoroAlloc);
-
-  cir::FuncOp fnOp;
-  if (!builtin) {
-    fnOp = cgm.createCIRBuiltinFunction(loc, cgm.builtinCoroAlloc,
-                                        cir::FuncType::get({uInt32Ty}, boolTy),
-                                        /*fd=*/nullptr);
-    assert(fnOp && "should always succeed");
-  } else {
-    fnOp = cast<cir::FuncOp>(builtin);
+cir::CoroIntrinsicAllocOp
+CIRGenFunction::emitCoroAllocBuiltinCall(const CallExpr *e) {
+  mlir::Location loc = getLoc(e->getBeginLoc());
+  if (!curCoro.data || !curCoro.data->coroId) {
+    cgm.error(e->getBeginLoc(), "this builtin expect that __builtin_coro_id 
has"
+                                " been used earlier in this function");
+    return {};
   }
 
-  return builder.createCallOp(
-      loc, fnOp, mlir::ValueRange{curCoro.data->coroId.getResult()});
+  return cir::CoroIntrinsicAllocOp::create(
+      cgm.getBuilder(), loc,
+      mlir::ValueRange{curCoro.data->coroId.getResult()});
 }
 
-cir::CallOp
-CIRGenFunction::emitCoroBeginBuiltinCall(mlir::Location loc,
-                                         mlir::Value coroframeAddr) {
-  mlir::Operation *builtin = cgm.getGlobalValue(cgm.builtinCoroBegin);
-
-  cir::FuncOp fnOp;
-  if (!builtin) {
-    fnOp = cgm.createCIRBuiltinFunction(
-        loc, cgm.builtinCoroBegin,
-        cir::FuncType::get({uInt32Ty, voidPtrTy}, voidPtrTy),
-        /*fd=*/nullptr);
-    assert(fnOp && "should always succeed");
-  } else {
-    fnOp = cast<cir::FuncOp>(builtin);
-  }
-
-  return builder.createCallOp(
-      loc, fnOp,
-      mlir::ValueRange{curCoro.data->coroId.getResult(), coroframeAddr});
-}
+cir::CoroIntrinsicBeginOp
+CIRGenFunction::emitCoroBeginBuiltinCall(const CallExpr *e) {
 
-cir::CallOp CIRGenFunction::emitCoroEndBuiltinCall(mlir::Location loc,
-                                                   mlir::Value nullPtr) {
-  cir::BoolType boolTy = builder.getBoolTy();
-  mlir::Operation *builtin = cgm.getGlobalValue(cgm.builtinCoroEnd);
-
-  cir::FuncOp fnOp;
-  if (!builtin) {
-    fnOp = cgm.createCIRBuiltinFunction(
-        loc, cgm.builtinCoroEnd,
-        cir::FuncType::get({voidPtrTy, boolTy}, boolTy),
-        /*fd=*/nullptr);
-    assert(fnOp && "should always succeed");
-  } else {
-    fnOp = cast<cir::FuncOp>(builtin);
+  mlir::Location loc = getLoc(e->getBeginLoc());
+  if (!curCoro.data || !curCoro.data->coroId) {
+    cgm.error(e->getBeginLoc(), "this builtin expect that __builtin_coro_id 
has"
+                                " been used earlier in this function");
+    return {};
+  }
+  llvm::SmallVector<mlir::Value, 2> args;
+  args.push_back(curCoro.data->coroId.getResult());
+  for (auto const *arg : e->arguments()) {
+    args.push_back(emitScalarExpr(arg));
   }
+  auto coroBegin =
+      cir::CoroIntrinsicBeginOp::create(cgm.getBuilder(), loc, args);
+  curCoro.data->coroBegin = coroBegin;
+  return coroBegin;
+}
 
-  return builder.createCallOp(
-      loc, fnOp, mlir::ValueRange{nullPtr, builder.getBool(false, loc)});
+cir::CoroIntrinsicEndOp
+CIRGenFunction::emitCoroEndBuiltinCall(mlir::Location loc,
+                                       mlir::Value nullPtr) {
+  return cir::CoroIntrinsicEndOp::create(
+      cgm.getBuilder(), loc,
+      mlir::ValueRange{nullPtr, builder.getBool(false, loc)});
 }
 
-cir::CallOp CIRGenFunction::emitCoroFreeBuiltin(const CallExpr *e) {
-  mlir::Operation *builtin = cgm.getGlobalValue(cgm.builtinCoroFree);
+cir::CoroIntrinsicFreeOp
+CIRGenFunction::emitCoroFreeBuiltin(const CallExpr *e) {
   mlir::Location loc = getLoc(e->getBeginLoc());
-  cir::FuncOp fnOp;
-  if (!builtin) {
-    fnOp = cgm.createCIRBuiltinFunction(
-        loc, cgm.builtinCoroFree,
-        cir::FuncType::get({uInt32Ty, voidPtrTy}, voidPtrTy),
-        /*fd=*/nullptr);
-    assert(fnOp && "should always succeed");
-  } else {
-    fnOp = cast<cir::FuncOp>(builtin);
+  if (!curCoro.data || !curCoro.data->coroId) {
+    cgm.error(e->getBeginLoc(), "this builtin expect that __builtin_coro_id 
has"
+                                " been used earlier in this function");
+    return {};
   }
-  cir::CallOp coroFree =
-      builder.createCallOp(loc, fnOp,
-                           mlir::ValueRange{curCoro.data->coroId.getResult(),
-                                            curCoro.data->coroBegin});
-
-  curCoro.data->lastCoroFree = coroFree;
+  auto coroFree = cir::CoroIntrinsicFreeOp::create(
+      cgm.getBuilder(), loc,
+      mlir::ValueRange{curCoro.data->coroId.getResult(),
+                       curCoro.data->coroBegin});
+  if (curCoro.data)
+    curCoro.data->lastCoroFree = coroFree;
   return coroFree;
 }
 
+cir::CoroIntrinsicSizeOp
+CIRGenFunction::emitCoroSizeBuiltinCall(const CallExpr *e) {
+  mlir::Location loc = getLoc(e->getBeginLoc());
+  return cir::CoroIntrinsicSizeOp::create(cgm.getBuilder(), loc);
+}
+
 static mlir::LogicalResult
 coroutineBodyExceptionHelper(CIRGenFunction &cgf, const CoroutineBodyStmt &s) {
 
@@ -348,12 +335,20 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt 
&s) {
 
   auto fn = mlir::cast<cir::FuncOp>(curFn);
   fn.setCoroutine(true);
-  cir::CallOp coroId = emitCoroIDBuiltinCall(openCurlyLoc, nullPtrCst);
+  const TargetInfo &ti = cgm.getASTContext().getTargetInfo();
+  unsigned newAlign = ti.getNewAlign() / ti.getCharWidth();
+
+  cir::CoroIntrinsicIdOp coroId = cir::CoroIntrinsicIdOp::create(
+      cgm.getBuilder(), openCurlyLoc,
+      mlir::ValueRange{builder.getUInt32(newAlign, openCurlyLoc), nullPtrCst,
+                       nullPtrCst, nullPtrCst});
   createCoroData(*this, curCoro, coroId);
 
   // Backend is allowed to elide memory allocations, to help it, emit
   // auto mem = coro.alloc() ? 0 : ... allocation code ...;
-  cir::CallOp coroAlloc = emitCoroAllocBuiltinCall(openCurlyLoc);
+  cir::CoroIntrinsicAllocOp coroAlloc = cir::CoroIntrinsicAllocOp::create(
+      cgm.getBuilder(), openCurlyLoc,
+      mlir::ValueRange{curCoro.data->coroId.getResult()});
 
   // Initialize address of coroutine frame to null
   CanQualType astVoidPtrTy = cgm.getASTContext().VoidPtrTy;
@@ -373,11 +368,11 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt 
&s) {
             loc, emitScalarExpr(s.getAllocate()), storeAddr);
         cir::YieldOp::create(builder, loc);
       });
-  curCoro.data->coroBegin =
-      emitCoroBeginBuiltinCall(
-          openCurlyLoc,
-          cir::LoadOp::create(builder, openCurlyLoc, allocaTy, storeAddr))
-          .getResult();
+  curCoro.data->coroBegin = cir::CoroIntrinsicBeginOp::create(
+      cgm.getBuilder(), openCurlyLoc,
+      mlir::ValueRange{
+          curCoro.data->coroId.getResult(),
+          cir::LoadOp::create(builder, openCurlyLoc, allocaTy, storeAddr)});
 
   // Handle allocation failure if 'ReturnStmtOnAllocFailure' was provided.
   if (s.getReturnStmtOnAllocFailure())
@@ -511,9 +506,10 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt 
&s) {
       }
     }
   }
-
-  emitCoroEndBuiltinCall(
-      openCurlyLoc, builder.getNullPtr(builder.getVoidPtrTy(), openCurlyLoc));
+  cir::CoroIntrinsicEndOp::create(
+      cgm.getBuilder(), openCurlyLoc,
+      mlir::ValueRange{builder.getNullPtr(builder.getVoidPtrTy(), 
openCurlyLoc),
+                       builder.getBool(false, openCurlyLoc)});
   if (auto *ret = cast_or_null<ReturnStmt>(s.getReturnStmt())) {
     // Since we already emitted the return value above, so we shouldn't
     // emit it again here.
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 322355fde3957..81a85e1971d88 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1797,13 +1797,14 @@ class CIRGenFunction : public CIRGenTypeCache {
   void emitConstructorBody(FunctionArgList &args);
 
   mlir::LogicalResult emitCoroutineBody(const CoroutineBodyStmt &s);
-  cir::CallOp emitCoroEndBuiltinCall(mlir::Location loc, mlir::Value nullPtr);
-  cir::CallOp emitCoroIDBuiltinCall(mlir::Location loc, mlir::Value nullPtr);
-  cir::CallOp emitCoroAllocBuiltinCall(mlir::Location loc);
-  cir::CallOp emitCoroBeginBuiltinCall(mlir::Location loc,
-                                       mlir::Value coroframeAddr);
-
-  cir::CallOp emitCoroFreeBuiltin(const CallExpr *e);
+  cir::CoroIntrinsicEndOp emitCoroEndBuiltinCall(mlir::Location loc,
+                                                 mlir::Value nullPtr);
+  cir::CoroIntrinsicIdOp emitCoroIDBuiltinCall(const CallExpr *e);
+  cir::CoroIntrinsicAllocOp emitCoroAllocBuiltinCall(const CallExpr *e);
+  cir::CoroIntrinsicBeginOp emitCoroBeginBuiltinCall(const CallExpr *e);
+
+  cir::CoroIntrinsicSizeOp emitCoroSizeBuiltinCall(const CallExpr *e);
+  cir::CoroIntrinsicFreeOp emitCoroFreeBuiltin(const CallExpr *e);
   RValue emitCoroutineFrame();
 
   void emitDestroy(Address addr, QualType type, Destroyer *destroyer);
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h 
b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 144f8c7b9f3e7..365a0df17fc46 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -807,12 +807,6 @@ class CIRGenModule : public CIRGenTypeCache {
                                     bool isLocal = false,
                                     bool assumeConvergent = false);
 
-  static constexpr const char *builtinCoroId = "__builtin_coro_id";
-  static constexpr const char *builtinCoroAlloc = "__builtin_coro_alloc";
-  static constexpr const char *builtinCoroBegin = "__builtin_coro_begin";
-  static constexpr const char *builtinCoroEnd = "__builtin_coro_end";
-  static constexpr const char *builtinCoroFree = "__builtin_coro_free";
-
   /// Given a builtin id for a function like "__builtin_fabsf", return a
   /// Function* for "fabsf".
   cir::FuncOp getBuiltinLibFunction(const FunctionDecl *fd, unsigned 
builtinID);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 0e412090a16da..cc31309ce7b3f 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -5029,6 +5029,48 @@ mlir::LogicalResult 
CIRToLLVMAwaitOpLowering::matchAndRewrite(
   return mlir::failure();
 }
 
+mlir::LogicalResult CIRToLLVMCoroIntrinsicIsInRampOpLowering::matchAndRewrite(
+    cir::CoroIntrinsicIsInRampOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  return mlir::failure();
+}
+
+mlir::LogicalResult CIRToLLVMCoroIntrinsicFreeOpLowering::matchAndRewrite(
+    cir::CoroIntrinsicFreeOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  return mlir::failure();
+}
+
+mlir::LogicalResult CIRToLLVMCoroIntrinsicEndOpLowering::matchAndRewrite(
+    cir::CoroIntrinsicEndOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  return mlir::failure();
+}
+
+mlir::LogicalResult CIRToLLVMCoroIntrinsicAllocOpLowering::matchAndRewrite(
+    cir::CoroIntrinsicAllocOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  return mlir::failure();
+}
+
+mlir::LogicalResult CIRToLLVMCoroIntrinsicBeginOpLowering::matchAndRewrite(
+    cir::CoroIntrinsicBeginOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  return mlir::failure();
+}
+
+mlir::LogicalResult CIRToLLVMCoroIntrinsicIdOpLowering::matchAndRewrite(
+    cir::CoroIntrinsicIdOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  return mlir::failure();
+}
+
+mlir::LogicalResult CIRToLLVMCoroIntrinsicSizeOpLowering::matchAndRewrite(
+    cir::CoroIntrinsicSizeOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  return mlir::failure();
+}
+
 mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite(
     cir::CpuIdOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/CodeGen/coro-builtins-err.cpp 
b/clang/test/CIR/CodeGen/coro-builtins-err.cpp
new file mode 100644
index 0000000000000..ffbbd706b61bf
--- /dev/null
+++ b/clang/test/CIR/CodeGen/coro-builtins-err.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines -fclangir 
-emit-cir %s -o %t.cir -verify
+
+void a(void) {
+  __builtin_coro_alloc(); // expected-error {{this builtin expect that 
__builtin_coro_id has been used earlier in this function}}
+  __builtin_coro_begin(0); // expected-error {{this builtin expect that 
__builtin_coro_id has been used earlier in this function}}
+  __builtin_coro_free(0); // expected-error {{this builtin expect that 
__builtin_coro_id has been used earlier in this function}}
+
+  __builtin_coro_id(32, 0, 0, 0);
+  __builtin_coro_id(32, 0, 0, 0); // expected-error {{only one 
__builtin_coro_id}}
+}
diff --git a/clang/test/CIR/CodeGen/coro-builtins.cpp 
b/clang/test/CIR/CodeGen/coro-builtins.cpp
new file mode 100644
index 0000000000000..f92f4d996c460
--- /dev/null
+++ b/clang/test/CIR/CodeGen/coro-builtins.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+
+void *myAlloc(long long);
+
+// CIR: cir.func {{.*}} @_Z1fi
+void f(int n) {
+  int promise;
+  // CIR: %[[ADDR:.*]] = cir.alloca "n"
+  // CIR: %[[PROMISE:.*]] = cir.alloca "promise"
+
+  __builtin_coro_id(32, &promise, 0, 0);
+  // CIR: %[[CORO_ID_ALIGN:.*]] = cir.const #cir.int<32>
+  // CIR: %[[CAS_PROM:.*]] = cir.cast bitcast %[[PROMISE]]
+  // CIR: %[[COROID:.*]] = cir.coro.intrinsic.id(%[[CORO_ID_ALIGN]], 
%[[CAS_PROM]], {{.*}}, {{.*}})
+
+  __builtin_coro_alloc();
+  // CIR: cir.coro.intrinsic.alloc(%[[COROID]])
+
+  // TODO
+  //__builtin_coro_noop();
+
+  __builtin_coro_begin(myAlloc(__builtin_coro_size()));
+  // TODO(CIR): Support both variants of the coroutine size intrinsic, matching
+  // `llvm.coro.size.i32` and `llvm.coro.size.i64`.
+  // CIR: %[[SIZE:.*]] = cir.coro.intrinsic.size()
+  // CIR: %[[CAST_SIZE:.*]] = cir.cast integral %[[SIZE]] : !u64i -> !s64i
+  // CIR: %[[MEM:.*]] = cir.call @_Z7myAllocx(%[[CAST_SIZE]])
+  // CIR: %[[FRAME:.*]] = cir.coro.intrinsic.begin(%[[COROID]], %[[MEM]])
+
+  // TODO(CIR):
+  //__builtin_coro_resume(__builtin_coro_frame());
+
+  // TODO(CIR):
+  //__builtin_coro_destroy(__builtin_coro_frame());
+
+  // TODO(CIR):
+  //__builtin_coro_done(__builtin_coro_frame());
+
+  // TODO(CIR):
+  //__builtin_coro_promise(__builtin_coro_frame(), 48, 0);
+
+  __builtin_coro_free(__builtin_coro_frame());
+  // CIR: cir.coro.intrinsic.free(%[[COROID]], %[[FRAME]])
+
+  // TODO(CIR):
+  //__builtin_coro_end(__builtin_coro_frame(), 0);
+
+  // TODO(CIR):
+  //__builtin_coro_suspend(1);
+}
diff --git a/clang/test/CIR/CodeGen/coro-task.cpp 
b/clang/test/CIR/CodeGen/coro-task.cpp
index 8d093180ae307..e83dca7948554 100644
--- a/clang/test/CIR/CodeGen/coro-task.cpp
+++ b/clang/test/CIR/CodeGen/coro-task.cpp
@@ -138,11 +138,6 @@ co_invoke_fn co_invoke;
 // CIR: module {{.*}} {
 // CIR-NEXT: cir.global external @_ZN5folly4coro9co_invokeE = #cir.zero : 
!rec_folly3A3Acoro3A3Aco_invoke_fn
 
-// CIR: cir.func builtin private @__builtin_coro_id(!u32i, !cir.ptr<!void>, 
!cir.ptr<!void>, !cir.ptr<!void>) -> !u32i
-// CIR:  cir.func builtin private @__builtin_coro_alloc(!u32i) -> !cir.bool
-// CIR:  cir.func builtin private @__builtin_coro_size() -> !u64i
-// CIR:  cir.func builtin private @__builtin_coro_begin(!u32i, 
!cir.ptr<!void>) -> !cir.ptr<!void>
-
 using VoidTask = folly::coro::Task<void>;
 
 VoidTask silly_task() {
@@ -165,22 +160,21 @@ VoidTask silly_task() {
 
 // CIR: %[[NullPtr:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
 // CIR: %[[Align:.*]] = cir.const #cir.int<16> : !u32i
-// CIR: %[[CoroId:.*]] = cir.call @__builtin_coro_id(%[[Align]], %[[NullPtr]], 
%[[NullPtr]], %[[NullPtr]])
-
+// CIR: %[[CoroId:.*]] = cir.coro.intrinsic.id(%[[Align]], %[[NullPtr]], 
%[[NullPtr]], %[[NullPtr]]) : (!u32i, !cir.ptr<!void>, !cir.ptr<!void>, 
!cir.ptr<!void>) -> !u32i
 // OGCG: %[[CoroId:.*]] = call token @llvm.coro.id(i32 16, ptr 
%[[VoidPromisseAddr]], ptr null, ptr null)
 
 // Perform allocation calling operator 'new' depending on __builtin_coro_alloc 
and
 // call __builtin_coro_begin for the final coroutine frame address.
 
-// CIR: %[[ShouldAlloc:.*]] = cir.call @__builtin_coro_alloc(%[[CoroId]]) : 
(!u32i) -> !cir.bool
+// CIR: %[[ShouldAlloc:.*]] = cir.coro.intrinsic.alloc(%[[CoroId]]) : (!u32i) 
-> !cir.bool
 // CIR: cir.store{{.*}} %[[NullPtr]], %[[SavedFrameAddr]] : !cir.ptr<!void>, 
!cir.ptr<!cir.ptr<!void>>
 // CIR: cir.if %[[ShouldAlloc]] {
-// CIR:   %[[CoroSize:.*]] = cir.call @__builtin_coro_size() : () -> (!u64i 
{llvm.noundef})
+// CIR:   %[[CoroSize:.*]] = cir.coro.intrinsic.size() : () -> !u64i
 // CIR:   %[[AllocAddr:.*]] = cir.call @_Znwm(%[[CoroSize]]) {allocsize = 
array<i32: 0>} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, 
llvm.noundef})
 // CIR:   cir.store{{.*}} %[[AllocAddr]], %[[SavedFrameAddr]] : 
!cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
 // CIR: }
 // CIR: %[[Load0:.*]] = cir.load{{.*}} %[[SavedFrameAddr]] : 
!cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
-// CIR: %[[CoroFrameAddr:.*]] = cir.call @__builtin_coro_begin(%[[CoroId]], 
%[[Load0]])
+// CIR: %[[CoroFrameAddr:.*]] = cir.coro.intrinsic.begin(%[[CoroId]], 
%[[Load0]]) : (!u32i, !cir.ptr<!void>) -> !cir.ptr<!void>
 
 // OGCG: %[[ShouldAlloc:.*]]  = call i1 @llvm.coro.alloc(token %[[CoroId]])
 // OGCG: br i1 %[[ShouldAlloc]], label %coro.alloc, label %coro.init
@@ -312,11 +306,11 @@ VoidTask silly_task() {
 // The `if` ensures we only call delete on non-null.
 
 // CIR: } cleanup  normal {
-// CIR:   %[[FreeMem:.*]] = cir.call @__builtin_coro_free(%[[CoroId]], 
%[[CoroFrameAddr]])
+// CIR:   %[[FreeMem:.*]] = cir.coro.intrinsic.free(%[[CoroId]], 
%[[CoroFrameAddr]]) : (!u32i, !cir.ptr<!void>) -> !cir.ptr<!void>
 // CIR:   %[[NullPtr2:.*]] = cir.const #cir.ptr<null>
 // CIR:   %[[Cond:.*]] = cir.cmp ne %[[FreeMem]], %[[NullPtr2]]
 // CIR:   cir.if %[[Cond]] {
-// CIR:     %[[Size:.*]] = cir.call @__builtin_coro_size()
+// CIR:     %[[Size:.*]] = cir.coro.intrinsic.size()
 // CIR:     cir.call @_ZdlPvm(%[[FreeMem]], %[[Size]])
 // CIR:   }
 // CIR:   cir.yield
@@ -336,7 +330,7 @@ VoidTask silly_task() {
 
 // CIR: %[[CoroEndArg0:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
 // CIR: %[[CoroEndArg1:.*]] = cir.const #false
-// CIR: = cir.call @__builtin_coro_end(%[[CoroEndArg0]], %[[CoroEndArg1]])
+// CIR: = cir.coro.intrinsic.end(%[[CoroEndArg0]], %[[CoroEndArg1]]) : 
(!cir.ptr<!void>, !cir.bool) -> !cir.bool
 
 // CIR: %[[Tmp1:.*]] = cir.load{{.*}} %[[VoidTaskAddr]]
 // CIR: cir.return %[[Tmp1]]
@@ -524,7 +518,7 @@ folly::coro::Task<void> yield1() {
 // CIR:   cir.yield
 // CIR: } cleanup  normal {
 // CIR: }
-// CIR: = cir.call @__builtin_coro_end(%{{.*}}, %{{.*}}){{.*}}
+// CIR: = cir.coro.intrinsic.end(%{{.*}}, %{{.*}})
 // CIR: %[[RETLOAD:.*]] = cir.load{{.*}} %[[RETVAL]]
 // CIR: cir.return %[[RETLOAD]]
 // CIR: }

>From a5680da70bbc78d3fb2d0bfe87682d579d53946f Mon Sep 17 00:00:00 2001
From: Andres Salamanca <[email protected]>
Date: Sun, 26 Jul 2026 19:16:04 -0500
Subject: [PATCH 2/2] Address some review comments

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 22 ++++++++-----------
 clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp     | 14 +++++++-----
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  6 -----
 3 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 8228b89765ede..29a88ee7465f6 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4634,6 +4634,7 @@ class CIR_CoroIntrinsicOp<string mnem, dag ins, dag outs,
     `(` operands `)` `:` functional-type(operands, results) attr-dict
   }];
 }
+
 
//===----------------------------------------------------------------------===//
 // Coroutine intrinsic IdOp
 
//===----------------------------------------------------------------------===//
@@ -4675,11 +4676,12 @@ def CIR_CoroIntrinsicAllocOp : 
CIR_CoroIntrinsicOp<"alloc",
   }];
 }
 
-// TODO: Replace the `id` operand with MLIR's `token` type once it becomes
-// available. This operand corresponds to the token produced by `llvm.coro.id`.
 
//===----------------------------------------------------------------------===//
 // Coroutine intrinsic BeginOp
 
//===----------------------------------------------------------------------===//
+
+// TODO: Replace the `id` operand with MLIR's `token` type once it becomes
+// available. This operand corresponds to the token produced by `llvm.coro.id`.
 def CIR_CoroIntrinsicBeginOp : CIR_CoroIntrinsicOp<"begin",
     (ins CIR_UInt32:$id, CIR_VoidPtrType:$coroframeAddr),
     (outs CIR_VoidPtrType:$result)> {
@@ -4694,6 +4696,7 @@ def CIR_CoroIntrinsicBeginOp : 
CIR_CoroIntrinsicOp<"begin",
 
//===----------------------------------------------------------------------===//
 // Coroutine intrinsic EndOp
 
//===----------------------------------------------------------------------===//
+
 def CIR_CoroIntrinsicEndOp : CIR_CoroIntrinsicOp<"end",
     (ins CIR_VoidPtrType:$handle, CIR_AnyBoolType:$unwind),
     (outs CIR_AnyBoolType:$result)> {
@@ -4708,11 +4711,12 @@ def CIR_CoroIntrinsicEndOp : CIR_CoroIntrinsicOp<"end",
   }];
 }
 
-// TODO: Replace the `id` operand with MLIR's `token` type once it becomes
-// available. This operand corresponds to the token produced by `llvm.coro.id`.
 
//===----------------------------------------------------------------------===//
 // Coroutine intrinsic FreeOp
 
//===----------------------------------------------------------------------===//
+
+// TODO: Replace the `id` operand with MLIR's `token` type once it becomes
+// available. This operand corresponds to the token produced by `llvm.coro.id`.
 def CIR_CoroIntrinsicFreeOp : CIR_CoroIntrinsicOp<"free",
     (ins CIR_AnyIntType:$id, CIR_VoidPtrType:$coroframe),
     (outs CIR_VoidPtrType:$result)> {
@@ -4728,6 +4732,7 @@ def CIR_CoroIntrinsicFreeOp : CIR_CoroIntrinsicOp<"free",
 
//===----------------------------------------------------------------------===//
 // Coroutine intrinsic SizeOp
 
//===----------------------------------------------------------------------===//
+
 def CIR_CoroIntrinsicSizeOp : CIR_CoroIntrinsicOp<"size",
     (ins), (outs CIR_UInt64:$result)> {
   let summary = "Represents llvm.coro.size";
@@ -4736,15 +4741,6 @@ def CIR_CoroIntrinsicSizeOp : CIR_CoroIntrinsicOp<"size",
   }];
 }
 
-//===----------------------------------------------------------------------===//
-// Coroutine intrinsic IsInRampOp
-//===----------------------------------------------------------------------===//
-
-def CIR_CoroIntrinsicIsInRampOp : CIR_CoroIntrinsicOp<"is_in_ramp",
-    (ins), (outs CIR_AnyBoolType:$result), [Pure]> {
-  let summary = "";
-}
-
 
//===----------------------------------------------------------------------===//
 // CopyOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 2aa199c347152..ed54661aa3ef7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -233,9 +233,9 @@ CIRGenFunction::emitCoroIDBuiltinCall(const CallExpr *e) {
   mlir::Location loc = getLoc(e->getBeginLoc());
 
   llvm::SmallVector<mlir::Value, 4> args;
-  for (auto const *arg : e->arguments()) {
+  for (const Expr *arg : e->arguments())
     args.push_back(emitScalarExpr(arg));
-  }
+
   auto coroId = cir::CoroIntrinsicIdOp::create(cgm.getBuilder(), loc, args);
   createCoroData(*this, curCoro, coroId, e);
   return coroId;
@@ -266,9 +266,9 @@ CIRGenFunction::emitCoroBeginBuiltinCall(const CallExpr *e) 
{
   }
   llvm::SmallVector<mlir::Value, 2> args;
   args.push_back(curCoro.data->coroId.getResult());
-  for (auto const *arg : e->arguments()) {
+  for (const Expr *arg : e->arguments())
     args.push_back(emitScalarExpr(arg));
-  }
+
   auto coroBegin =
       cir::CoroIntrinsicBeginOp::create(cgm.getBuilder(), loc, args);
   curCoro.data->coroBegin = coroBegin;
@@ -286,17 +286,19 @@ CIRGenFunction::emitCoroEndBuiltinCall(mlir::Location loc,
 cir::CoroIntrinsicFreeOp
 CIRGenFunction::emitCoroFreeBuiltin(const CallExpr *e) {
   mlir::Location loc = getLoc(e->getBeginLoc());
+
   if (!curCoro.data || !curCoro.data->coroId) {
     cgm.error(e->getBeginLoc(), "this builtin expect that __builtin_coro_id 
has"
                                 " been used earlier in this function");
     return {};
   }
+
   auto coroFree = cir::CoroIntrinsicFreeOp::create(
       cgm.getBuilder(), loc,
       mlir::ValueRange{curCoro.data->coroId.getResult(),
                        curCoro.data->coroBegin});
-  if (curCoro.data)
-    curCoro.data->lastCoroFree = coroFree;
+
+  curCoro.data->lastCoroFree = coroFree;
   return coroFree;
 }
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index cc31309ce7b3f..e1912b6559ea0 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -5029,12 +5029,6 @@ mlir::LogicalResult 
CIRToLLVMAwaitOpLowering::matchAndRewrite(
   return mlir::failure();
 }
 
-mlir::LogicalResult CIRToLLVMCoroIntrinsicIsInRampOpLowering::matchAndRewrite(
-    cir::CoroIntrinsicIsInRampOp op, OpAdaptor adaptor,
-    mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
-}
-
 mlir::LogicalResult CIRToLLVMCoroIntrinsicFreeOpLowering::matchAndRewrite(
     cir::CoroIntrinsicFreeOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to