https://github.com/Andres-Salamanca created 
https://github.com/llvm/llvm-project/pull/215709

This patch adds CIRToLLVM lowering for coroutine intrinsics and token none:

* `cir.token.none`
* `cir.coro.intrinsic.id`
* `cir.coro.intrinsic.alloc`
* `cir.coro.intrinsic.size`
* `cir.coro.intrinsic.begin`
* `cir.coro.intrinsic.free`
* `cir.coro.intrinsic.end`


>From 6dfbff85f8fcaff0e711208277062cd591f71370 Mon Sep 17 00:00:00 2001
From: Andres Salamanca <[email protected]>
Date: Tue, 11 Aug 2026 21:26:38 -0500
Subject: [PATCH] [CIR] Add lowering for coroutine intrinsics and token none

---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 32 +++++++++++++----
 .../CIR/CodeGenCoroutines/coro-builtins.cpp   | 36 +++++++++++++++++++
 2 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index c8f3cf61c757f..8a7310168f572 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -5417,43 +5417,61 @@ mlir::LogicalResult 
CIRToLLVMIndirectBrOpLowering::matchAndRewrite(
 mlir::LogicalResult CIRToLLVMTokenNoneOpLowering::matchAndRewrite(
     cir::TokenNoneOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
+  rewriter.replaceOpWithNewOp<mlir::LLVM::NoneTokenOp>(
+      op, mlir::TokenType::get(rewriter.getContext()));
+  return mlir::success();
 }
 
 mlir::LogicalResult CIRToLLVMCoroFreeOpLowering::matchAndRewrite(
     cir::CoroFreeOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
+  rewriter.replaceOpWithNewOp<mlir::LLVM::CoroFreeOp>(
+      op, mlir::LLVM::LLVMPointerType::get(rewriter.getContext()),
+      adaptor.getId(), adaptor.getCoroframe());
+  return mlir::success();
 }
 
 mlir::LogicalResult CIRToLLVMCoroEndOpLowering::matchAndRewrite(
     cir::CoroEndOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
+  rewriter.replaceOpWithNewOp<mlir::LLVM::CoroEndOp>(
+      op, mlir::LLVM::LLVMVoidType::get(rewriter.getContext()),
+      adaptor.getHandle(), adaptor.getUnwind(), adaptor.getResultToken());
+  return mlir::success();
 }
 
 mlir::LogicalResult CIRToLLVMCoroAllocOpLowering::matchAndRewrite(
     cir::CoroAllocOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
+  rewriter.replaceOpWithNewOp<mlir::LLVM::CoroAllocOp>(op, 
rewriter.getI1Type(),
+                                                       adaptor.getId());
+  return mlir::success();
 }
 
 mlir::LogicalResult CIRToLLVMCoroBeginOpLowering::matchAndRewrite(
     cir::CoroBeginOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
+  rewriter.replaceOpWithNewOp<mlir::LLVM::CoroBeginOp>(
+      op, mlir::LLVM::LLVMPointerType::get(rewriter.getContext()),
+      adaptor.getId(), adaptor.getCoroframeAddr());
+  return mlir::success();
 }
 
 mlir::LogicalResult CIRToLLVMCoroIdOpLowering::matchAndRewrite(
     cir::CoroIdOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
+  rewriter.replaceOpWithNewOp<mlir::LLVM::CoroIdOp>(
+      op, mlir::TokenType::get(rewriter.getContext()), adaptor.getAlign(),
+      adaptor.getPromise(), adaptor.getCoroaddr(), adaptor.getFnaddrs());
+  return mlir::success();
 }
 
 mlir::LogicalResult CIRToLLVMCoroSizeOpLowering::matchAndRewrite(
     cir::CoroSizeOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  return mlir::failure();
+  rewriter.replaceOpWithNewOp<mlir::LLVM::CoroSizeOp>(op,
+                                                      rewriter.getI64Type());
+  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 de1fe9126eb77..64c69ce4f5806 100644
--- a/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
+++ b/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
@@ -1,22 +1,42 @@
 // 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
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines -fclangir 
-fclangir -emit-llvm -disable-llvm-passes %s -o  %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines -emit-llvm 
-disable-llvm-passes %s -o  %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
 
 void *myAlloc(long long);
 
 // CIR: cir.func {{.*}} @_Z1fi
+// LLVM: void @_Z1fi
+// OGCG: void @_Z1fi
 void f(int n) {
   int promise;
   // CIR: %[[ADDR:.*]] = cir.alloca "n"
   // CIR: %[[PROMISE:.*]] = cir.alloca "promise"
 
+  // LLVM: %[[ADDR:.*]] = alloca i32
+  // LLVM: %[[PROMISE:.*]] = alloca i32
+
+  // OGCG: %n.addr = alloca i32, align 4
+  // OGCG: %promise = alloca i32, align 4
+
   __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]], {{.*}}, {{.*}})
 
+  // LLVM: %[[COROID:.*]] = call token @llvm.coro.id(i32 32, ptr %[[PROMISE]], 
ptr null, ptr null)
+
+  // OGCG: %[[COROID:.*]] = call token @llvm.coro.id(i32 32, ptr %promise, ptr 
null, ptr null)
+
   __builtin_coro_alloc();
   // CIR: cir.coro.intrinsic.alloc(%[[COROID]])
 
+  // LLVM: call i1 @llvm.coro.alloc(token %[[COROID]])
+
+  // OGCG: call i1 @llvm.coro.alloc(token %[[COROID]])
+
   // TODO
   //__builtin_coro_noop();
 
@@ -28,6 +48,14 @@ void f(int n) {
   // CIR: %[[MEM:.*]] = cir.call @_Z7myAllocx(%[[CAST_SIZE]])
   // CIR: %[[FRAME:.*]] = cir.coro.intrinsic.begin(%[[COROID]], %[[MEM]])
 
+  // LLVM: %[[SIZE:.*]] = call i64 @llvm.coro.size.i64()
+  // LLVM: %[[MEM:.*]] = call noundef ptr @_Z7myAllocx(i64 noundef %[[SIZE]])
+  // LLVM: %[[FRAME:.*]] = call ptr @llvm.coro.begin(token %[[COROID]], ptr 
%[[MEM]])
+
+  // OGCG: %[[SIZE:.*]] = call i64 @llvm.coro.size.i64()
+  // OGCG: %[[MEM:.*]] = call noundef ptr @_Z7myAllocx(i64 noundef %[[SIZE]])
+  // OGCG: %[[FRAME:.*]] = call ptr @llvm.coro.begin(token %[[COROID]], ptr 
%[[MEM]])
+
   // TODO(CIR):
   //__builtin_coro_resume(__builtin_coro_frame());
 
@@ -43,11 +71,19 @@ void f(int n) {
   __builtin_coro_free(__builtin_coro_frame());
   // CIR: cir.coro.intrinsic.free(%[[COROID]], %[[FRAME]])
 
+  // LLVM: call ptr @llvm.coro.free(token %[[COROID]], ptr %[[FRAME]])
+
+  // OGCG: call ptr @llvm.coro.free(token %[[COROID]], ptr %[[FRAME]])
+
   __builtin_coro_end(__builtin_coro_frame(), false);
   // CIR: %[[FALSE:.*]] = cir.const #false
   // CIR: %[[TK_NONE:.*]] = cir.token.none
   // CIR: cir.coro.intrinsic.end(%[[FRAME]], %[[FALSE]], %[[TK_NONE]]) : 
(!cir.ptr<!void>, !cir.bool, token)
 
+  // LLVM: call void @llvm.coro.end(ptr %[[FRAME]], i1 false, token none)
+
+  // OGCG: call void @llvm.coro.end(ptr %[[FRAME]], i1 false, token none)
+
   // TODO(CIR):
   //__builtin_coro_suspend(1);
 }

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

Reply via email to