[clang] [CIR] Upstream coroutine builtin coro_end (PR #176598)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jan 17 14:29:26 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: None (Andres-Salamanca)
<details>
<summary>Changes</summary>
This PR adds support for emitting the `__builtin_coro_end` builtin in CIR.
---
Full diff: https://github.com/llvm/llvm-project/pull/176598.diff
5 Files Affected:
- (modified) clang/include/clang/CIR/MissingFeatures.h (-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp (+20)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+5-3)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+1)
- (modified) clang/test/CIR/CodeGen/coro-task.cpp (+10)
``````````diff
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 1d066f192d739..e7545626f7ce9 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -149,8 +149,6 @@ struct MissingFeatures {
static bool zeroSizeRecordMembers() { return false; }
// Coroutines
- static bool coroEndBuiltinCall() { return false; }
- static bool emitBodyAndFallthrough() { return false; }
static bool coroOutsideFrameMD() { return false; }
static bool coroutineExceptions() { return false; };
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index f060568e8db61..f4997b6262c2c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -215,6 +215,26 @@ CIRGenFunction::emitCoroBeginBuiltinCall(mlir::Location loc,
mlir::ValueRange{curCoro.data->coroId.getResult(), coroframeAddr});
}
+cir::CallOp CIRGenFunction::emitCoroEndBuiltinCall(mlir::Location loc,
+ mlir::Value nullPtr) {
+ auto 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);
+ }
+
+ return builder.createCallOp(
+ loc, fnOp, mlir::ValueRange{nullPtr, builder.getBool(false, loc)});
+}
+
mlir::LogicalResult
CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) {
mlir::Location openCurlyLoc = getLoc(s.getBeginLoc());
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index ac66d00950f05..f2d73720a9c2b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -355,11 +355,13 @@ void CIRGenFunction::LexicalScope::cleanup() {
cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
CIRGenBuilderTy &builder = cgf.getBuilder();
- // If we are on a coroutine, add the coro_end builtin call.
- assert(!cir::MissingFeatures::coroEndBuiltinCall());
-
auto fn = dyn_cast<cir::FuncOp>(cgf.curFn);
assert(fn && "emitReturn from non-function");
+
+ // If we are on a coroutine, add the coro_end builtin call.
+ if (fn.getCoroutine())
+ cgf.emitCoroEndBuiltinCall(loc,
+ builder.getNullPtr(builder.getVoidPtrTy(), loc));
if (!fn.getFunctionType().hasVoidReturn()) {
// Load the value from `__retval` and return it via the `cir.return` op.
auto value = cir::LoadOp::create(
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index db63a5d636373..9b01ed338f5f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -570,6 +570,7 @@ class CIRGenModule : public CIRGenTypeCache {
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";
/// Given a builtin id for a function like "__builtin_fabsf", return a
/// Function* for "fabsf".
diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGen/coro-task.cpp
index b98c866de524b..549b156b0fdc0 100644
--- a/clang/test/CIR/CodeGen/coro-task.cpp
+++ b/clang/test/CIR/CodeGen/coro-task.cpp
@@ -250,6 +250,16 @@ VoidTask silly_task() {
// CIR: },)
// CIR: }
+// Call builtin coro end and return
+
+// CIR-NEXT: %[[CoroEndArg0:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
+// CIR-NEXT: %[[CoroEndArg1:.*]] = cir.const #false
+// CIR-NEXT: = cir.call @__builtin_coro_end(%[[CoroEndArg0]], %[[CoroEndArg1]])
+
+// CIR: %[[Tmp1:.*]] = cir.load{{.*}} %[[VoidTaskAddr]]
+// CIR-NEXT: cir.return %[[Tmp1]]
+// CIR-NEXT: }
+
folly::coro::Task<int> byRef(const std::string& s) {
co_return s.size();
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/176598
More information about the cfe-commits
mailing list