[clang] [CIR] Add token.none and fix coro.end signature (PR #214125)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 9 14:57:35 PDT 2026
https://github.com/Andres-Salamanca updated https://github.com/llvm/llvm-project/pull/214125
>From 9a4c6cf642bbc036e39a6a0cea190c1ecece0ab6 Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Tue, 4 Aug 2026 22:24:35 -0500
Subject: [PATCH 1/3] [CIR] Add token.none and fix coro.end signature
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 22 +++++++++++++++++--
clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 6 ++---
clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp | 21 ++++++++++++------
clang/lib/CIR/CodeGen/CIRGenFunction.h | 3 +--
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 6 +++++
.../CIR/CodeGenCoroutines/coro-builtins.cpp | 6 +++--
.../test/CIR/CodeGenCoroutines/coro-task.cpp | 7 +++---
7 files changed, 51 insertions(+), 20 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index d0f3c9ee6715f..6b33c84d78b75 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4906,8 +4906,8 @@ def CIR_CoroBeginOp : CIR_CoroIntrinsicOp<"begin",
//===----------------------------------------------------------------------===//
def CIR_CoroEndOp : CIR_CoroIntrinsicOp<"end",
- (ins CIR_VoidPtrType:$handle, CIR_AnyBoolType:$unwind),
- (outs CIR_AnyBoolType:$result)> {
+ (ins CIR_VoidPtrType:$handle, CIR_AnyBoolType:$unwind, Token:$resultToken),
+ (outs), [TokenConsumerTrait]> {
let summary = "Represents llvm.coro.end";
let description = [{
Marks a point at which a coroutine must be suspended or destroyed for the
@@ -8735,6 +8735,24 @@ def CIR_ConstructCatchParamOp : CIR_Op<"construct_catch_param", [
let hasLLVMLowering = false;
}
+//===----------------------------------------------------------------------===//
+// TokenNoneOp
+//===----------------------------------------------------------------------===//
+
+def CIR_TokenNoneOp : CIR_Op<"token.none", [
+ Pure, TokenProducerTrait
+]> {
+ let summary = "Produces an empty token value.";
+ let description = [{
+ MLIR does not have a way to represent the LLVM IR `none` token literal.
+ Like the LLVM dialect, CIR provides an operation that produces a token
+ value, which can later be lowered to `llvm::ConstantTokenNone`.
+ }];
+
+ let results = (outs Token:$result);
+ let assemblyFormat = "attr-dict";
+}
+
//===----------------------------------------------------------------------===//
// Atomic operations
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 1efe2b81d5cae..fc8ed339ffd88 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1388,7 +1388,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return coroBeg ? RValue::get(coroBeg.getResult())
: getUndefRValue(e->getType());
}
-
+ case Builtin::BI__builtin_coro_end:
+ return RValue::get(emitCoroEndBuiltinCall(e).getResultToken());
case Builtin::BI__builtin_coro_promise:
cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_promise NYI");
return getUndefRValue(e->getType());
@@ -1404,9 +1405,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BI__builtin_coro_done:
cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_done NYI");
return getUndefRValue(e->getType());
- case Builtin::BI__builtin_coro_end:
- cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_end NYI");
- return getUndefRValue(e->getType());
case Builtin::BI__builtin_coro_suspend:
cgm.errorNYI(e->getSourceRange(), "BI__builtin_coro_suspend NYI");
return getUndefRValue(e->getType());
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 9111c2ac98863..8abf9cd999c67 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -274,11 +274,16 @@ cir::CoroBeginOp CIRGenFunction::emitCoroBeginBuiltinCall(const CallExpr *e) {
return coroBegin;
}
-cir::CoroEndOp CIRGenFunction::emitCoroEndBuiltinCall(mlir::Location loc,
- mlir::Value nullPtr) {
- return cir::CoroEndOp::create(
- cgm.getBuilder(), loc,
- mlir::ValueRange{nullPtr, builder.getBool(false, loc)});
+cir::CoroEndOp CIRGenFunction::emitCoroEndBuiltinCall(const CallExpr *e) {
+
+ mlir::Location loc = getLoc(e->getBeginLoc());
+ CIRGenBuilderTy &builder = cgm.getBuilder();
+ llvm::SmallVector<mlir::Value, 3> args;
+ for (const Expr *arg : e->arguments())
+ args.push_back(emitScalarExpr(arg));
+ auto tkNone = cir::TokenNoneOp::create(builder, loc);
+ args.push_back(tkNone.getResult());
+ return cir::CoroEndOp::create(builder, loc, {}, args);
}
cir::CoroFreeOp CIRGenFunction::emitCoroFreeBuiltin(const CallExpr *e) {
@@ -504,10 +509,12 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) {
}
}
}
+
+ auto tkNone = cir::TokenNoneOp::create(cgm.getBuilder(), openCurlyLoc);
cir::CoroEndOp::create(
cgm.getBuilder(), openCurlyLoc,
- mlir::ValueRange{builder.getNullPtr(builder.getVoidPtrTy(), openCurlyLoc),
- builder.getBool(false, openCurlyLoc)});
+ builder.getNullPtr(builder.getVoidPtrTy(), openCurlyLoc),
+ builder.getBool(false, openCurlyLoc), tkNone.getResult());
if (auto *ret = cast_or_null<ReturnStmt>(s.getReturnStmt())) {
// Since we already emitted the return value above, so we shouldn't
// emit it again here.
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 9f8454309f13a..3783cbec3d866 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1887,8 +1887,7 @@ class CIRGenFunction : public CIRGenTypeCache {
void emitConstructorBody(FunctionArgList &args);
mlir::LogicalResult emitCoroutineBody(const CoroutineBodyStmt &s);
- cir::CoroEndOp emitCoroEndBuiltinCall(mlir::Location loc,
- mlir::Value nullPtr);
+ cir::CoroEndOp emitCoroEndBuiltinCall(const CallExpr *e);
cir::CoroIdOp emitCoroIDBuiltinCall(const CallExpr *e);
cir::CoroAllocOp emitCoroAllocBuiltinCall(const CallExpr *e);
cir::CoroBeginOp emitCoroBeginBuiltinCall(const CallExpr *e);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 717bf5e2e741e..dd8847176b92e 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -5414,6 +5414,12 @@ mlir::LogicalResult CIRToLLVMIndirectBrOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMTokenNoneOpLowering::matchAndRewrite(
+ cir::TokenNoneOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ return mlir::failure();
+}
+
mlir::LogicalResult CIRToLLVMCoroFreeOpLowering::matchAndRewrite(
cir::CoroFreeOp 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 f92f4d996c460..de1fe9126eb77 100644
--- a/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
+++ b/clang/test/CIR/CodeGenCoroutines/coro-builtins.cpp
@@ -43,8 +43,10 @@ void f(int n) {
__builtin_coro_free(__builtin_coro_frame());
// CIR: cir.coro.intrinsic.free(%[[COROID]], %[[FRAME]])
- // TODO(CIR):
- //__builtin_coro_end(__builtin_coro_frame(), 0);
+ __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)
// TODO(CIR):
//__builtin_coro_suspend(1);
diff --git a/clang/test/CIR/CodeGenCoroutines/coro-task.cpp b/clang/test/CIR/CodeGenCoroutines/coro-task.cpp
index d0ba8c153bdbb..8335ab0377073 100644
--- a/clang/test/CIR/CodeGenCoroutines/coro-task.cpp
+++ b/clang/test/CIR/CodeGenCoroutines/coro-task.cpp
@@ -212,9 +212,10 @@ VoidTask silly_task() {
// Call builtin coro end and return
-// CIR: %[[CoroEndArg0:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
+// CIR: %[[TK_NONE:.*]] = cir.token.none
// CIR: %[[CoroEndArg1:.*]] = cir.const #false
-// CIR: = cir.coro.intrinsic.end(%[[CoroEndArg0]], %[[CoroEndArg1]]) : (!cir.ptr<!void>, !cir.bool) -> !cir.bool
+// CIR: %[[CoroEndArg0:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
+// CIR: cir.coro.intrinsic.end(%[[CoroEndArg0]], %[[CoroEndArg1]], %[[TK_NONE]]) : (!cir.ptr<!void>, !cir.bool, token)
// CIR: %[[Tmp1:.*]] = cir.load{{.*}} %[[VoidTaskAddr]]
// CIR: cir.return %[[Tmp1]]
@@ -402,7 +403,7 @@ folly::coro::Task<void> yield1() {
// CIR: cir.yield
// CIR: } cleanup normal {
// CIR: }
-// CIR: = cir.coro.intrinsic.end(%{{.*}}, %{{.*}})
+// CIR: cir.coro.intrinsic.end(%{{.*}}, %{{.*}}, %{{.*}})
// CIR: %[[RETLOAD:.*]] = cir.load{{.*}} %[[RETVAL]]
// CIR: cir.return %[[RETLOAD]]
// CIR: }
>From 0e3f02b16a42d6cd0049ae99fde4621dfd73719a Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Sun, 9 Aug 2026 12:05:00 -0500
Subject: [PATCH 2/3] Address review comments
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 5 ++---
clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp | 7 +++----
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 6b33c84d78b75..3092e542fd71c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -8744,9 +8744,8 @@ def CIR_TokenNoneOp : CIR_Op<"token.none", [
]> {
let summary = "Produces an empty token value.";
let description = [{
- MLIR does not have a way to represent the LLVM IR `none` token literal.
- Like the LLVM dialect, CIR provides an operation that produces a token
- value, which can later be lowered to `llvm::ConstantTokenNone`.
+ Produces a `none` token value, mirroring LLVM IR's `none` token
+ literal. Lowers to `llvm::ConstantTokenNone`.
}];
let results = (outs Token:$result);
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 8abf9cd999c67..275f120f812f1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -281,8 +281,7 @@ cir::CoroEndOp CIRGenFunction::emitCoroEndBuiltinCall(const CallExpr *e) {
llvm::SmallVector<mlir::Value, 3> args;
for (const Expr *arg : e->arguments())
args.push_back(emitScalarExpr(arg));
- auto tkNone = cir::TokenNoneOp::create(builder, loc);
- args.push_back(tkNone.getResult());
+ args.push_back(cir::TokenNoneOp::create(builder, loc));
return cir::CoroEndOp::create(builder, loc, {}, args);
}
@@ -510,11 +509,11 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) {
}
}
- auto tkNone = cir::TokenNoneOp::create(cgm.getBuilder(), openCurlyLoc);
cir::CoroEndOp::create(
cgm.getBuilder(), openCurlyLoc,
builder.getNullPtr(builder.getVoidPtrTy(), openCurlyLoc),
- builder.getBool(false, openCurlyLoc), tkNone.getResult());
+ builder.getBool(false, openCurlyLoc),
+ cir::TokenNoneOp::create(cgm.getBuilder(), openCurlyLoc));
if (auto *ret = cast_or_null<ReturnStmt>(s.getReturnStmt())) {
// Since we already emitted the return value above, so we shouldn't
// emit it again here.
>From 8787283514af60e2e5d4d13cff9a6b81586ad45b Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbaritos at gmail.com>
Date: Sun, 9 Aug 2026 16:29:30 -0500
Subject: [PATCH 3/3] fix test.
---
clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp | 5 +-
.../test/CIR/CodeGenCoroutines/coro-task.cpp | 96 +++++++++----------
2 files changed, 51 insertions(+), 50 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 275f120f812f1..dfa0b3d8656ec 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -510,10 +510,11 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) {
}
cir::CoroEndOp::create(
- cgm.getBuilder(), openCurlyLoc,
+ builder, openCurlyLoc,
builder.getNullPtr(builder.getVoidPtrTy(), openCurlyLoc),
builder.getBool(false, openCurlyLoc),
- cir::TokenNoneOp::create(cgm.getBuilder(), openCurlyLoc));
+ cir::TokenNoneOp::create(builder, openCurlyLoc));
+
if (auto *ret = cast_or_null<ReturnStmt>(s.getReturnStmt())) {
// Since we already emitted the return value above, so we shouldn't
// emit it again here.
diff --git a/clang/test/CIR/CodeGenCoroutines/coro-task.cpp b/clang/test/CIR/CodeGenCoroutines/coro-task.cpp
index 8335ab0377073..9ca60075f99d6 100644
--- a/clang/test/CIR/CodeGenCoroutines/coro-task.cpp
+++ b/clang/test/CIR/CodeGenCoroutines/coro-task.cpp
@@ -29,12 +29,12 @@ VoidTask silly_task() {
}
// CIR: cir.func coroutine {{.*}} @_Z10silly_taskv() -> ![[VoidTask]]
-// CIR: %[[VoidTaskAddr:.*]] = cir.alloca "__retval" {{.*}} : !cir.ptr<![[VoidTask]]>
-// CIR: %[[SavedFrameAddr:.*]] = cir.alloca "__coro_frame_addr" {{.*}} : !cir.ptr<!cir.ptr<!void>>
-// CIR: %[[VoidPromisseAddr:.*]] = cir.alloca "__promise" {{.*}} : !cir.ptr<![[VoidPromisse]]>
-// CIR: %[[SuspendAlwaysAddr:.*]] = cir.alloca "ref.tmp0" {{.*}} : !cir.ptr<![[SuspendAlways]]>
-// CIR: %[[CoroHandleVoidAddr:.*]] = cir.alloca "agg.tmp0" {{.*}} : !cir.ptr<![[CoroHandleVoid]]>
-// CIR: %[[CoroHandlePromiseAddr:.*]] = cir.alloca "agg.tmp1" {{.*}} : !cir.ptr<![[CoroHandlePromiseVoid]]>
+// CIR-NEXT: %[[VoidTaskAddr:.*]] = cir.alloca "__retval" {{.*}} : !cir.ptr<![[VoidTask]]>
+// CIR-NEXT: %[[SavedFrameAddr:.*]] = cir.alloca "__coro_frame_addr" {{.*}} : !cir.ptr<!cir.ptr<!void>>
+// CIR-NEXT: %[[VoidPromisseAddr:.*]] = cir.alloca "__promise" {{.*}} : !cir.ptr<![[VoidPromisse]]>
+// CIR-NEXT: %[[SuspendAlwaysAddr:.*]] = cir.alloca "ref.tmp0" {{.*}} : !cir.ptr<![[SuspendAlways]]>
+// CIR-NEXT: %[[CoroHandleVoidAddr:.*]] = cir.alloca "agg.tmp0" {{.*}} : !cir.ptr<![[CoroHandleVoid]]>
+// CIR-NEXT: %[[CoroHandlePromiseAddr:.*]] = cir.alloca "agg.tmp1" {{.*}} : !cir.ptr<![[CoroHandlePromiseVoid]]>
// OGCG: %[[VoidPromisseAddr:.*]] = alloca %[[VoidPromisse]], align 1
// OGCG: %[[VoidTaskAddr:.*]] = alloca %[[VoidTask]], align 1
@@ -43,22 +43,22 @@ VoidTask silly_task() {
// Get coroutine id with __builtin_coro_id.
// CIR: %[[NullPtr:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
-// CIR: %[[Align:.*]] = cir.const #cir.int<16> : !u32i
-// CIR: %[[CoroId:.*]] = cir.coro.intrinsic.id(%[[Align]], %[[NullPtr]], %[[NullPtr]], %[[NullPtr]]) : (!u32i, !cir.ptr<!void>, !cir.ptr<!void>, !cir.ptr<!void>) -> token
+// CIR-NEXT: %[[Align:.*]] = cir.const #cir.int<16> : !u32i
+// CIR-NEXT: %[[CoroId:.*]] = cir.coro.intrinsic.id(%[[Align]], %[[NullPtr]], %[[NullPtr]], %[[NullPtr]]) : (!u32i, !cir.ptr<!void>, !cir.ptr<!void>, !cir.ptr<!void>) -> token
// OGCG: %[[CoroId:.*]] = call token @llvm.coro.id(i32 16, ptr %[[VoidPromisseAddr]], ptr null, ptr null)
// Perform allocation calling operator 'new' depending on __builtin_coro_alloc and
// call __builtin_coro_begin for the final coroutine frame address.
-// CIR: %[[ShouldAlloc:.*]] = cir.coro.intrinsic.alloc(%[[CoroId]]) : (token) -> !cir.bool
-// CIR: cir.store{{.*}} %[[NullPtr]], %[[SavedFrameAddr]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
-// CIR: cir.if %[[ShouldAlloc]] {
-// CIR: %[[CoroSize:.*]] = cir.coro.intrinsic.size() : () -> !u64i
-// CIR: %[[AllocAddr:.*]] = cir.call @_Znwm(%[[CoroSize]]) {allocsize = array<i32: 0>} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, llvm.noundef})
-// CIR: cir.store{{.*}} %[[AllocAddr]], %[[SavedFrameAddr]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
-// CIR: }
-// CIR: %[[Load0:.*]] = cir.load{{.*}} %[[SavedFrameAddr]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
-// CIR: %[[CoroFrameAddr:.*]] = cir.coro.intrinsic.begin(%[[CoroId]], %[[Load0]]) : (token, !cir.ptr<!void>) -> !cir.ptr<!void>
+// CIR-NEXT: %[[ShouldAlloc:.*]] = cir.coro.intrinsic.alloc(%[[CoroId]]) : (token) -> !cir.bool
+// CIR-NEXT: cir.store{{.*}} %[[NullPtr]], %[[SavedFrameAddr]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
+// CIR-NEXT: cir.if %[[ShouldAlloc]] {
+// CIR-NEXT: %[[CoroSize:.*]] = cir.coro.intrinsic.size() : () -> !u64i
+// CIR-NEXT: %[[AllocAddr:.*]] = cir.call @_Znwm(%[[CoroSize]]) {allocsize = array<i32: 0>} : (!u64i {llvm.noundef}) -> (!cir.ptr<!void> {llvm.nonnull, llvm.noundef})
+// CIR-NEXT: cir.store{{.*}} %[[AllocAddr]], %[[SavedFrameAddr]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
+// CIR-NEXT: }
+// CIR-NEXT: %[[Load0:.*]] = cir.load{{.*}} %[[SavedFrameAddr]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+// CIR-NEXT: %[[CoroFrameAddr:.*]] = cir.coro.intrinsic.begin(%[[CoroId]], %[[Load0]]) : (token, !cir.ptr<!void>) -> !cir.ptr<!void>
// OGCG: %[[ShouldAlloc:.*]] = call i1 @llvm.coro.alloc(token %[[CoroId]])
// OGCG: br i1 %[[ShouldAlloc]], label %coro.alloc, label %coro.init
@@ -92,7 +92,7 @@ VoidTask silly_task() {
// to later passes, same is done elsewhere.
// CIR: %[[Tmp0:.*]] = cir.call @_ZN5folly4coro4TaskIvE12promise_type15initial_suspendEv(%[[VoidPromisseAddr]])
-// CIR: cir.store{{.*}} %[[Tmp0:.*]], %[[SuspendAlwaysAddr]]
+// CIR: cir.store{{.*}} %[[Tmp0]], %[[SuspendAlwaysAddr]]
// OGCG: call void @_ZN5folly4coro4TaskIvE12promise_type15initial_suspendEv(ptr noundef nonnull align 1 dereferenceable(1) %[[VoidPromisseAddr]])
@@ -102,9 +102,9 @@ VoidTask silly_task() {
// First regions `ready` has a special cir.yield code to veto suspension.
-// CIR: cir.await(init, ready : {
-// CIR: %[[ReadyVeto:.*]] = cir.call @_ZNSt14suspend_always11await_readyEv(%[[SuspendAlwaysAddr]])
-// CIR: cir.condition(%[[ReadyVeto]])
+// CIR-NEXT: cir.await(init, ready : {
+// CIR-NEXT: %[[ReadyVeto:.*]] = cir.call @_ZNSt14suspend_always11await_readyEv(%[[SuspendAlwaysAddr]])
+// CIR-NEXT: cir.condition(%[[ReadyVeto]])
// OGCG: %[[Tmp0:.*]] = call noundef zeroext i1 @_ZNSt14suspend_always11await_readyEv(ptr noundef nonnull align 1 dereferenceable(1) %[[SuspendAlwaysAddr]])
// OGCG: br i1 %[[Tmp0]], label %init.ready, label %init.suspend
@@ -118,14 +118,14 @@ VoidTask silly_task() {
//
// FIXME: add veto support for non-void await_suspends.
-// CIR: }, suspend : {
-// CIR: %[[FromAddrRes:.*]] = cir.call @_ZNSt16coroutine_handleIN5folly4coro4TaskIvE12promise_typeEE12from_addressEPv(%[[CoroFrameAddr]])
-// CIR: cir.store{{.*}} %[[FromAddrRes]], %[[CoroHandlePromiseAddr]] : ![[CoroHandlePromiseVoid]]
-// CIR: %[[CoroHandlePromiseReload:.*]] = cir.load{{.*}} %[[CoroHandlePromiseAddr]]
-// CIR: cir.call @_ZNSt16coroutine_handleIvEC1IN5folly4coro4TaskIvE12promise_typeEEES_IT_E(%[[CoroHandleVoidAddr]], %[[CoroHandlePromiseReload]])
-// CIR: %[[CoroHandleVoidReload:.*]] = cir.load{{.*}} %[[CoroHandleVoidAddr]] : !cir.ptr<![[CoroHandleVoid]]>, ![[CoroHandleVoid]]
-// CIR: cir.call @_ZNSt14suspend_always13await_suspendESt16coroutine_handleIvE(%[[SuspendAlwaysAddr]], %[[CoroHandleVoidReload]])
-// CIR: cir.yield
+// CIR-NEXT: }, suspend : {
+// CIR-NEXT: %[[FromAddrRes:.*]] = cir.call @_ZNSt16coroutine_handleIN5folly4coro4TaskIvE12promise_typeEE12from_addressEPv(%[[CoroFrameAddr]])
+// CIR-NEXT: cir.store{{.*}} %[[FromAddrRes]], %[[CoroHandlePromiseAddr]] : ![[CoroHandlePromiseVoid]]
+// CIR-NEXT: %[[CoroHandlePromiseReload:.*]] = cir.load{{.*}} %[[CoroHandlePromiseAddr]]
+// CIR-NEXT: cir.call @_ZNSt16coroutine_handleIvEC1IN5folly4coro4TaskIvE12promise_typeEEES_IT_E(%[[CoroHandleVoidAddr]], %[[CoroHandlePromiseReload]])
+// CIR-NEXT: %[[CoroHandleVoidReload:.*]] = cir.load{{.*}} %[[CoroHandleVoidAddr]] : !cir.ptr<![[CoroHandleVoid]]>, ![[CoroHandleVoid]]
+// CIR-NEXT: cir.call @_ZNSt14suspend_always13await_suspendESt16coroutine_handleIvE(%[[SuspendAlwaysAddr]], %[[CoroHandleVoidReload]])
+// CIR-NEXT: cir.yield
// OGCG: init.suspend:
// OGCG: %[[Save:.*]] = call token @llvm.coro.save(ptr null)
@@ -138,10 +138,10 @@ VoidTask silly_task() {
// Third region `resume` handles coroutine resuming logic.
-// CIR: }, resume : {
-// CIR: cir.call @_ZNSt14suspend_always12await_resumeEv(%[[SuspendAlwaysAddr]])
-// CIR: cir.yield
-// CIR: },)
+// CIR-NEXT: }, resume : {
+// CIR-NEXT: cir.call @_ZNSt14suspend_always12await_resumeEv(%[[SuspendAlwaysAddr]])
+// CIR-NEXT: cir.yield
+// CIR-NEXT: },)
// OGCG: init.ready:
// OGCG: call void @_ZNSt14suspend_always12await_resumeEv(ptr noundef nonnull align 1 dereferenceable(1) %[[SuspendAlwaysAddr]]
@@ -177,7 +177,7 @@ VoidTask silly_task() {
// CIR: }, suspend : {
// CIR: }, resume : {
// CIR: },)
-// CIR: cir.yield
+// CIR-NEXT: cir.yield
// OGCG: coro.final:
// OGCG: final.suspend:
@@ -189,16 +189,16 @@ VoidTask silly_task() {
// If null, no dynamic allocation happened, so nothing to free.
// The `if` ensures we only call delete on non-null.
-// CIR: } cleanup normal {
-// CIR: %[[FreeMem:.*]] = cir.coro.intrinsic.free(%[[CoroId]], %[[CoroFrameAddr]]) : (token, !cir.ptr<!void>) -> !cir.ptr<!void>
-// CIR: %[[NullPtr2:.*]] = cir.const #cir.ptr<null>
-// CIR: %[[Cond:.*]] = cir.cmp ne %[[FreeMem]], %[[NullPtr2]]
-// CIR: cir.if %[[Cond]] {
-// CIR: %[[Size:.*]] = cir.coro.intrinsic.size()
-// CIR: cir.call @_ZdlPvm(%[[FreeMem]], %[[Size]])
-// CIR: }
-// CIR: cir.yield
-// CIR: }
+// CIR-NEXT: } cleanup normal {
+// CIR-NEXT: %[[FreeMem:.*]] = cir.coro.intrinsic.free(%[[CoroId]], %[[CoroFrameAddr]]) : (token, !cir.ptr<!void>) -> !cir.ptr<!void>
+// CIR-NEXT: %[[NullPtr2:.*]] = cir.const #cir.ptr<null>
+// CIR-NEXT: %[[Cond:.*]] = cir.cmp ne %[[FreeMem]], %[[NullPtr2]]
+// CIR-NEXT: cir.if %[[Cond]] {
+// CIR-NEXT: %[[Size:.*]] = cir.coro.intrinsic.size()
+// CIR-NEXT: cir.call @_ZdlPvm(%[[FreeMem]], %[[Size]]){{.*}}
+// CIR-NEXT: }
+// CIR-NEXT: cir.yield
+// CIR-NEXT: }
// OGCG: %[[FreeMem:.*]] = call ptr @llvm.coro.free(token %[[CoroId]], ptr %[[CoroFrameAddr]])
// OGCG: %[[Cond:.*]] = icmp ne ptr %[[FreeMem]], null
@@ -212,10 +212,10 @@ VoidTask silly_task() {
// Call builtin coro end and return
-// CIR: %[[TK_NONE:.*]] = cir.token.none
-// CIR: %[[CoroEndArg1:.*]] = cir.const #false
-// CIR: %[[CoroEndArg0:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
-// CIR: cir.coro.intrinsic.end(%[[CoroEndArg0]], %[[CoroEndArg1]], %[[TK_NONE]]) : (!cir.ptr<!void>, !cir.bool, token)
+// CIR-NEXT: %[[CoroEndArg0:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
+// CIR-NEXT: %[[CoroEndArg1:.*]] = cir.const #false
+// CIR-NEXT: %[[TK_NONE:.*]] = cir.token.none
+// CIR-NEXT: cir.coro.intrinsic.end(%[[CoroEndArg0]], %[[CoroEndArg1]], %[[TK_NONE]]) : (!cir.ptr<!void>, !cir.bool, token)
// CIR: %[[Tmp1:.*]] = cir.load{{.*}} %[[VoidTaskAddr]]
// CIR: cir.return %[[Tmp1]]
More information about the cfe-commits
mailing list