llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Andres-Salamanca

<details>
<summary>Changes</summary>

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`.

---
Full diff: https://github.com/llvm/llvm-project/pull/221124.diff


6 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+19) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+1-2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp (+12) 
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+1) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+9) 
- (modified) clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp (+6-2) 


``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 70d34884c70a4..9a0638e24f8e3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4984,6 +4984,25 @@ 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 = [{
+    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.
+  }];
+}
+
 
//===----------------------------------------------------------------------===//
 // 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..7004f2d7750e6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -309,6 +309,18 @@ cir::CoroSizeOp 
CIRGenFunction::emitCoroSizeBuiltinCall(const CallExpr *e) {
   return cir::CoroSizeOp::create(cgm.getBuilder(), loc);
 }
 
+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));
+
+  auto coroPromise = cir::CoroPromiseOp::create(cgm.getBuilder(), loc, args);
+  return coroPromise;
+}
+
 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..c489bf44af784 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -5639,6 +5639,15 @@ mlir::LogicalResult 
CIRToLLVMCoroSizeOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::LogicalResult CIRToLLVMCoroPromiseOpLowering::matchAndRewrite(
+    cir::CoroPromiseOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  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(
     cir::CpuIdOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
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]])

``````````

</details>


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

Reply via email to