[clang] [CIR] Add cir.coro.intrinsic.promise Op (PR #221124)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 3 20:20:23 PDT 2026
https://github.com/Andres-Salamanca created https://github.com/llvm/llvm-project/pull/221124
This PR adds `cir.coro.intrinsic.promise`, representing `llvm.coro.promise`, to the set of coroutine intrinsic ops. It also adds the corresponding lowering to `llvm.coro.promise`.
>From 41b01dfa12d8b132bd81b9b6ef5f49026c4e1ae1 Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Wed, 2 Sep 2026 19:27:25 -0500
Subject: [PATCH 1/2] Initial commit
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 12 ++++++++++++
clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 3 +--
clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp | 6 ++++++
clang/lib/CIR/CodeGen/CIRGenFunction.h | 1 +
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 6 ++++++
5 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 70d34884c70a4..421d4908f0641 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4984,6 +4984,18 @@ def CIR_CoroSizeOp : CIR_CoroIntrinsicOp<"size", (ins),
}];
}
+//===----------------------------------------------------------------------===//
+// Coroutine intrinsic PromiseOp
+//===----------------------------------------------------------------------===//
+
+def CIR_CoroPromiseOp : CIR_CoroIntrinsicOp<"promise",
+ (ins CIR_VoidPtrType:$coroframe, CIR_AnyIntType:$align, CIR_BoolType:$from),
+ (outs CIR_VoidPtrType:$result)> {
+ let summary = "Represents llvm.coro.promise";
+ let description = [{
+ }];
+}
+
//===----------------------------------------------------------------------===//
// CopyOp
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 61cb04828e272..69a191e8f5171 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1717,8 +1717,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BI__builtin_coro_end:
return RValue::get(emitCoroEndBuiltinCall(e).getResult());
case Builtin::BI__builtin_coro_promise:
- cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_promise NYI");
- return getUndefRValue(e->getType());
+ 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());
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 4fbede0f88ad4..fe8d95f58c526 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -309,6 +309,12 @@ cir::CoroSizeOp CIRGenFunction::emitCoroSizeBuiltinCall(const CallExpr *e) {
return cir::CoroSizeOp::create(cgm.getBuilder(), loc);
}
+cir::CoroPromiseOp
+CIRGenFunction::emitCoroPromiseBuiltinCall(const CallExpr *e) {
+
+ return {};
+}
+
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 e738c3b1fb72d..1eda909f091b6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1907,6 +1907,7 @@ class CIRGenFunction : public CIRGenTypeCache {
cir::CoroIdOp emitCoroIDBuiltinCall(const CallExpr *e);
cir::CoroAllocOp emitCoroAllocBuiltinCall(const CallExpr *e);
cir::CoroBeginOp emitCoroBeginBuiltinCall(const CallExpr *e);
+ cir::CoroPromiseOp emitCoroPromiseBuiltinCall(const CallExpr *e);
cir::CoroSizeOp emitCoroSizeBuiltinCall(const CallExpr *e);
cir::CoroFreeOp emitCoroFreeBuiltin(const CallExpr *e);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 6f7509c363fd3..929233f0e84e8 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -5639,6 +5639,12 @@ mlir::LogicalResult CIRToLLVMCoroSizeOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMCoroPromiseOpLowering::matchAndRewrite(
+ cir::CoroPromiseOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ return mlir::failure();
+}
+
mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite(
cir::CpuIdOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
>From 898152180b584919f478e4cc31911aa4461f5215 Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Thu, 3 Sep 2026 22:18:11 -0500
Subject: [PATCH 2/2] [CIR] Add cir.coro.intrinsic.promise Op
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 7 +++++++
clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp | 8 +++++++-
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 5 ++++-
clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp | 8 ++++++--
4 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 421d4908f0641..9a0638e24f8e3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4993,6 +4993,13 @@ def CIR_CoroPromiseOp : CIR_CoroIntrinsicOp<"promise",
(outs CIR_VoidPtrType:$result)> {
let summary = "Represents llvm.coro.promise";
let description = [{
+ Given a coroutine handle (if `from` is false) or a pointer to a coroutine
+ promise (if `from` is true), obtains a pointer to the coroutine promise or
+ the coroutine handle, respectively. `align` is the alignment requirement
+ of the promise, and `from` indicates the direction of the transformation:
+ `true` recovers the coroutine handle from a promise pointer, `false`
+ recovers the promise pointer from a coroutine handle. Using this op on a
+ coroutine without a coroutine promise is undefined behavior.
}];
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index fe8d95f58c526..7004f2d7750e6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -311,8 +311,14 @@ cir::CoroSizeOp CIRGenFunction::emitCoroSizeBuiltinCall(const CallExpr *e) {
cir::CoroPromiseOp
CIRGenFunction::emitCoroPromiseBuiltinCall(const CallExpr *e) {
+ mlir::Location loc = getLoc(e->getBeginLoc());
+
+ llvm::SmallVector<mlir::Value, 3> args;
+ for (const Expr *arg : e->arguments())
+ args.push_back(emitScalarExpr(arg));
- return {};
+ auto coroPromise = cir::CoroPromiseOp::create(cgm.getBuilder(), loc, args);
+ return coroPromise;
}
static mlir::LogicalResult
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 929233f0e84e8..c489bf44af784 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -5642,7 +5642,10 @@ mlir::LogicalResult CIRToLLVMCoroSizeOpLowering::matchAndRewrite(
mlir::LogicalResult CIRToLLVMCoroPromiseOpLowering::matchAndRewrite(
cir::CoroPromiseOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
- return mlir::failure();
+ rewriter.replaceOpWithNewOp<mlir::LLVM::CoroPromiseOp>(
+ op, mlir::LLVM::LLVMPointerType::get(rewriter.getContext()),
+ adaptor.getCoroframe(), adaptor.getAlign(), adaptor.getFrom());
+ return mlir::success();
}
mlir::LogicalResult CIRToLLVMCpuIdOpLowering::matchAndRewrite(
diff --git a/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp b/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
index e66bfde8dd853..899fa42285f1c 100644
--- a/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
+++ b/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
@@ -53,8 +53,12 @@ void f(int n) {
// TODO(CIR):
//__builtin_coro_done(__builtin_coro_frame());
- // TODO(CIR):
- //__builtin_coro_promise(__builtin_coro_frame(), 48, 0);
+ __builtin_coro_promise(__builtin_coro_frame(), 48, 0);
+ // CIR: %[[ALIGN:.*]] = cir.const #cir.int<48> : !s32i loc(#loc18)
+ // CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i loc(#loc19)
+ // CIR: %[[FALSE:.*]] = cir.cast int_to_bool %13 : !s32i -> !cir.bool loc(#loc19)
+ // CIR: cir.coro.intrinsic.promise(%[[FRAME]], %[[ALIGN]], %[[FALSE]])
+ // LLVM: call ptr @llvm.coro.promise(ptr %[[FRAME]], i32 48, i1 false)
__builtin_coro_free(__builtin_coro_frame());
// CIR: cir.coro.intrinsic.free(%[[COROID]], %[[FRAME]])
More information about the cfe-commits
mailing list