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 <[email protected]> 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 <[email protected]> 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]]) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
