-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[CIR] Upstream support co_return of values from co_await #173174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-clangir Author: None (Andres-Salamanca) ChangesThis PR adds support for returning the result of a Full diff: https://github.com/llvm/llvm-project/pull/173174.diff 5 Files Affected:
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index acfc937a11993..78199adec1a05 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -152,7 +152,6 @@ struct MissingFeatures {
static bool coroEndBuiltinCall() { return false; }
static bool emitBodyAndFallthrough() { return false; }
static bool coroOutsideFrameMD() { return false; }
- static bool coroCoReturn() { return false; }
static bool coroCoYield() { return false; }
static bool coroutineExceptions() { return false; };
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 9251106a641b1..b636022251f0c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -422,10 +422,17 @@ emitSuspendExpression(CIRGenFunction &cgf, CGCoroData &coro,
} else {
awaitRes.rv =
cgf.emitAnyExpr(s.getResumeExpr(), aggSlot, ignoreResult);
- if (!awaitRes.rv.isIgnored())
+ if (!awaitRes.rv.isIgnored()) {
// Create the alloca in the block before the scope wrapping
// cir.await.
- assert(!cir::MissingFeatures::coroCoReturn());
+ tmpResumeRValAddr = cgf.emitAlloca(
+ "__coawait_resume_rval", awaitRes.rv.getValue().getType(), loc,
+ CharUnits::One(),
+ builder.getBestAllocaInsertPoint(scopeParentBlock));
+ // Store the rvalue so we can reload it before the promise call.
+ builder.CIRBaseBuilderTy::createStore(loc, awaitRes.rv.getValue(),
+ tmpResumeRValAddr);
+ }
}
if (tryStmt)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 367c56f07f734..77cff8d3c3f59 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -722,7 +722,21 @@ void AggExprEmitter::VisitLambdaExpr(LambdaExpr *e) {
void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *e) {
CIRGenFunction::RunCleanupsScope cleanups(cgf);
- Visit(e->getSubExpr());
+ auto &builder = cgf.getBuilder();
+ auto scopeLoc = cgf.getLoc(e->getSourceRange());
+ mlir::OpBuilder::InsertPoint scopeBegin;
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ scopeBegin = b.saveInsertionPoint();
+ });
+
+ {
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ builder.restoreInsertionPoint(scopeBegin);
+ CIRGenFunction::LexicalScope lexScope{cgf, scopeLoc,
+ builder.getInsertionBlock()};
+ Visit(e->getSubExpr());
+ }
}
void AggExprEmitter::VisitCallExpr(const CallExpr *e) {
diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGen/coro-task.cpp
index 6cd494317f2d8..2c4686e27a460 100644
--- a/clang/test/CIR/CodeGen/coro-task.cpp
+++ b/clang/test/CIR/CodeGen/coro-task.cpp
@@ -322,3 +322,88 @@ folly::coro::Task<void> silly_coro() {
// CIR: cir.call @_ZN5folly4coro4TaskIvE12promise_type11return_voidEv
// CIR-NOT: cir.call @_ZN5folly4coro4TaskIvE12promise_type11return_voidEv
// CIR: cir.await(final, ready : {
+
+folly::coro::Task<int> go(int const& val);
+folly::coro::Task<int> go1() {
+ auto task = go(1);
+ co_return co_await task;
+}
+
+// CIR: cir.func coroutine {{.*}} @_Z3go1v() {{.*}} ![[IntTask]]
+// CIR: %[[IntTaskAddr:.*]] = cir.alloca ![[IntTask]], !cir.ptr<![[IntTask]]>, ["task", init]
+
+// CIR: cir.await(init, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: },)
+// CIR: }
+
+// The call to go(1) has its own scope due to full-expression rules.
+// CIR: cir.scope {
+// CIR: %[[OneAddr:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp1", init] {alignment = 4 : i64}
+// CIR: %[[One:.*]] = cir.const #cir.int<1> : !s32i
+// CIR: cir.store{{.*}} %[[One]], %[[OneAddr]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[IntTaskTmp:.*]] = cir.call @_Z2goRKi(%[[OneAddr]]) : (!cir.ptr<!s32i>) -> ![[IntTask]]
+// CIR: cir.store{{.*}} %[[IntTaskTmp]], %[[IntTaskAddr]] : ![[IntTask]], !cir.ptr<![[IntTask]]>
+// CIR: }
+
+// CIR: %[[CoReturnValAddr:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__coawait_resume_rval"] {alignment = 1 : i64}
+// CIR: cir.await(user, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: %[[ResumeVal:.*]] = cir.call @_ZN5folly4coro4TaskIiE12await_resumeEv(%3)
+// CIR: cir.store{{.*}} %[[ResumeVal]], %[[CoReturnValAddr]] : !s32i, !cir.ptr<!s32i>
+// CIR: },)
+// CIR: %[[V:.*]] = cir.load{{.*}} %[[CoReturnValAddr]] : !cir.ptr<!s32i>, !s32i
+// CIR: cir.call @_ZN5folly4coro4TaskIiE12promise_type12return_valueEi({{.*}}, %[[V]])
+
+
+folly::coro::Task<int> go1_lambda() {
+ auto task = []() -> folly::coro::Task<int> {
+ co_return 1;
+ }();
+ co_return co_await task;
+}
+
+// CIR: cir.func coroutine {{.*}} @_ZZ10go1_lambdavENK3$_0clEv{{.*}} ![[IntTask]]
+// CIR: cir.func coroutine {{.*}} @_Z10go1_lambdav() {{.*}} ![[IntTask]]
+
+folly::coro::Task<int> go4() {
+ auto* fn = +[](int const& i) -> folly::coro::Task<int> { co_return i; };
+ auto task = fn(3);
+ co_return co_await std::move(task);
+}
+
+// CIR: cir.func coroutine {{.*}} @_Z3go4v() {{.*}} ![[IntTask]]
+
+// CIR: cir.await(init, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: },)
+// CIR: }
+
+// CIR: %[[RES:.*]] = cir.scope {
+// CIR: %[[LAMBDA:.*]] = cir.alloca !rec_anon2E2, !cir.ptr<!rec_anon2E2>, ["ref.tmp1"] {alignment = 1 : i64}
+
+// Get the lambda invoker ptr via `lambda operator folly::coro::Task<int> (*)(int const&)()`
+// CIR: %[[INVOKER:.*]] = cir.call @_ZZ3go4vENK3$_0cvPFN5folly4coro4TaskIiEERKiEEv(%[[LAMBDA]]) nothrow : (!cir.ptr<!rec_anon2E2>) -> !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: %[[PLUS:.*]] = cir.unary(plus, %[[INVOKER]]) : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: cir.yield %[[PLUS]] : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: }
+// CIR: cir.store{{.*}} %[[RES]], %[[PTR_TASK:.*]] : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>>
+// CIR: cir.scope {
+// CIR: %[[ARG:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp2", init] {alignment = 4 : i64}
+// CIR: %[[LAMBDA2:.*]] = cir.load{{.*}} %[[PTR_TASK]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: %[[THREE:.*]] = cir.const #cir.int<3> : !s32i
+// CIR: cir.store{{.*}} %[[THREE]], %[[ARG]] : !s32i, !cir.ptr<!s32i>
+
+// Call invoker, which calls operator() indirectly.
+// CIR: %[[RES:.*]] = cir.call %[[LAMBDA2]](%[[ARG]]) : (!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!s32i>) -> ![[IntTask]]
+// CIR: cir.store{{.*}} %[[RES]], %4 : ![[IntTask]], !cir.ptr<![[IntTask]]>
+// CIR: }
+
+// CIR: cir.await(user, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: },)
+// CIR: }
diff --git a/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp b/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp
index 7429549100362..76c0dd208cb64 100644
--- a/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp
+++ b/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp
@@ -27,11 +27,13 @@ StructWithCtorArg withArg = 0.0;
// OGCG: @withArg = global %struct.StructWithCtorArg zeroinitializer
// CIR: cir.func {{.*}} @__cxx_global_var_init()
-// CIR: %[[TMP0:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["ref.tmp0"]
// CIR: %[[WITH_ARG:.*]] = cir.get_global @withArg : !cir.ptr<!rec_StructWithCtorArg>
-// CIR: %[[ZERO:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.double
-// CIR: cir.store{{.*}} %[[ZERO]], %[[TMP0]] : !cir.double, !cir.ptr<!cir.double>
-// CIR: cir.call @_ZN17StructWithCtorArgC1ERKd(%[[WITH_ARG]], %[[TMP0]]) : (!cir.ptr<!rec_StructWithCtorArg>, !cir.ptr<!cir.double>) -> ()
+// CIR: cir.scope {
+// CIR: %[[TMP0:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["ref.tmp0"]
+// CIR: %[[ZERO:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.double
+// CIR: cir.store{{.*}} %[[ZERO]], %[[TMP0]] : !cir.double, !cir.ptr<!cir.double>
+// CIR: cir.call @_ZN17StructWithCtorArgC1ERKd(%[[WITH_ARG]], %[[TMP0]]) : (!cir.ptr<!rec_StructWithCtorArg>, !cir.ptr<!cir.double>) -> ()
+// CIR: }
// LLVM: define {{.*}} void @__cxx_global_var_init()
// LLVM: %[[TMP0:.*]] = alloca double
|
|
@llvm/pr-subscribers-clang Author: None (Andres-Salamanca) ChangesThis PR adds support for returning the result of a Full diff: https://github.com/llvm/llvm-project/pull/173174.diff 5 Files Affected:
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index acfc937a11993..78199adec1a05 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -152,7 +152,6 @@ struct MissingFeatures {
static bool coroEndBuiltinCall() { return false; }
static bool emitBodyAndFallthrough() { return false; }
static bool coroOutsideFrameMD() { return false; }
- static bool coroCoReturn() { return false; }
static bool coroCoYield() { return false; }
static bool coroutineExceptions() { return false; };
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 9251106a641b1..b636022251f0c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -422,10 +422,17 @@ emitSuspendExpression(CIRGenFunction &cgf, CGCoroData &coro,
} else {
awaitRes.rv =
cgf.emitAnyExpr(s.getResumeExpr(), aggSlot, ignoreResult);
- if (!awaitRes.rv.isIgnored())
+ if (!awaitRes.rv.isIgnored()) {
// Create the alloca in the block before the scope wrapping
// cir.await.
- assert(!cir::MissingFeatures::coroCoReturn());
+ tmpResumeRValAddr = cgf.emitAlloca(
+ "__coawait_resume_rval", awaitRes.rv.getValue().getType(), loc,
+ CharUnits::One(),
+ builder.getBestAllocaInsertPoint(scopeParentBlock));
+ // Store the rvalue so we can reload it before the promise call.
+ builder.CIRBaseBuilderTy::createStore(loc, awaitRes.rv.getValue(),
+ tmpResumeRValAddr);
+ }
}
if (tryStmt)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 367c56f07f734..77cff8d3c3f59 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -722,7 +722,21 @@ void AggExprEmitter::VisitLambdaExpr(LambdaExpr *e) {
void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *e) {
CIRGenFunction::RunCleanupsScope cleanups(cgf);
- Visit(e->getSubExpr());
+ auto &builder = cgf.getBuilder();
+ auto scopeLoc = cgf.getLoc(e->getSourceRange());
+ mlir::OpBuilder::InsertPoint scopeBegin;
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ scopeBegin = b.saveInsertionPoint();
+ });
+
+ {
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ builder.restoreInsertionPoint(scopeBegin);
+ CIRGenFunction::LexicalScope lexScope{cgf, scopeLoc,
+ builder.getInsertionBlock()};
+ Visit(e->getSubExpr());
+ }
}
void AggExprEmitter::VisitCallExpr(const CallExpr *e) {
diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGen/coro-task.cpp
index 6cd494317f2d8..2c4686e27a460 100644
--- a/clang/test/CIR/CodeGen/coro-task.cpp
+++ b/clang/test/CIR/CodeGen/coro-task.cpp
@@ -322,3 +322,88 @@ folly::coro::Task<void> silly_coro() {
// CIR: cir.call @_ZN5folly4coro4TaskIvE12promise_type11return_voidEv
// CIR-NOT: cir.call @_ZN5folly4coro4TaskIvE12promise_type11return_voidEv
// CIR: cir.await(final, ready : {
+
+folly::coro::Task<int> go(int const& val);
+folly::coro::Task<int> go1() {
+ auto task = go(1);
+ co_return co_await task;
+}
+
+// CIR: cir.func coroutine {{.*}} @_Z3go1v() {{.*}} ![[IntTask]]
+// CIR: %[[IntTaskAddr:.*]] = cir.alloca ![[IntTask]], !cir.ptr<![[IntTask]]>, ["task", init]
+
+// CIR: cir.await(init, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: },)
+// CIR: }
+
+// The call to go(1) has its own scope due to full-expression rules.
+// CIR: cir.scope {
+// CIR: %[[OneAddr:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp1", init] {alignment = 4 : i64}
+// CIR: %[[One:.*]] = cir.const #cir.int<1> : !s32i
+// CIR: cir.store{{.*}} %[[One]], %[[OneAddr]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[IntTaskTmp:.*]] = cir.call @_Z2goRKi(%[[OneAddr]]) : (!cir.ptr<!s32i>) -> ![[IntTask]]
+// CIR: cir.store{{.*}} %[[IntTaskTmp]], %[[IntTaskAddr]] : ![[IntTask]], !cir.ptr<![[IntTask]]>
+// CIR: }
+
+// CIR: %[[CoReturnValAddr:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__coawait_resume_rval"] {alignment = 1 : i64}
+// CIR: cir.await(user, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: %[[ResumeVal:.*]] = cir.call @_ZN5folly4coro4TaskIiE12await_resumeEv(%3)
+// CIR: cir.store{{.*}} %[[ResumeVal]], %[[CoReturnValAddr]] : !s32i, !cir.ptr<!s32i>
+// CIR: },)
+// CIR: %[[V:.*]] = cir.load{{.*}} %[[CoReturnValAddr]] : !cir.ptr<!s32i>, !s32i
+// CIR: cir.call @_ZN5folly4coro4TaskIiE12promise_type12return_valueEi({{.*}}, %[[V]])
+
+
+folly::coro::Task<int> go1_lambda() {
+ auto task = []() -> folly::coro::Task<int> {
+ co_return 1;
+ }();
+ co_return co_await task;
+}
+
+// CIR: cir.func coroutine {{.*}} @_ZZ10go1_lambdavENK3$_0clEv{{.*}} ![[IntTask]]
+// CIR: cir.func coroutine {{.*}} @_Z10go1_lambdav() {{.*}} ![[IntTask]]
+
+folly::coro::Task<int> go4() {
+ auto* fn = +[](int const& i) -> folly::coro::Task<int> { co_return i; };
+ auto task = fn(3);
+ co_return co_await std::move(task);
+}
+
+// CIR: cir.func coroutine {{.*}} @_Z3go4v() {{.*}} ![[IntTask]]
+
+// CIR: cir.await(init, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: },)
+// CIR: }
+
+// CIR: %[[RES:.*]] = cir.scope {
+// CIR: %[[LAMBDA:.*]] = cir.alloca !rec_anon2E2, !cir.ptr<!rec_anon2E2>, ["ref.tmp1"] {alignment = 1 : i64}
+
+// Get the lambda invoker ptr via `lambda operator folly::coro::Task<int> (*)(int const&)()`
+// CIR: %[[INVOKER:.*]] = cir.call @_ZZ3go4vENK3$_0cvPFN5folly4coro4TaskIiEERKiEEv(%[[LAMBDA]]) nothrow : (!cir.ptr<!rec_anon2E2>) -> !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: %[[PLUS:.*]] = cir.unary(plus, %[[INVOKER]]) : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: cir.yield %[[PLUS]] : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: }
+// CIR: cir.store{{.*}} %[[RES]], %[[PTR_TASK:.*]] : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>>
+// CIR: cir.scope {
+// CIR: %[[ARG:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp2", init] {alignment = 4 : i64}
+// CIR: %[[LAMBDA2:.*]] = cir.load{{.*}} %[[PTR_TASK]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
+// CIR: %[[THREE:.*]] = cir.const #cir.int<3> : !s32i
+// CIR: cir.store{{.*}} %[[THREE]], %[[ARG]] : !s32i, !cir.ptr<!s32i>
+
+// Call invoker, which calls operator() indirectly.
+// CIR: %[[RES:.*]] = cir.call %[[LAMBDA2]](%[[ARG]]) : (!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!s32i>) -> ![[IntTask]]
+// CIR: cir.store{{.*}} %[[RES]], %4 : ![[IntTask]], !cir.ptr<![[IntTask]]>
+// CIR: }
+
+// CIR: cir.await(user, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: },)
+// CIR: }
diff --git a/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp b/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp
index 7429549100362..76c0dd208cb64 100644
--- a/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp
+++ b/clang/test/CIR/CodeGen/trivial-ctor-const-init.cpp
@@ -27,11 +27,13 @@ StructWithCtorArg withArg = 0.0;
// OGCG: @withArg = global %struct.StructWithCtorArg zeroinitializer
// CIR: cir.func {{.*}} @__cxx_global_var_init()
-// CIR: %[[TMP0:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["ref.tmp0"]
// CIR: %[[WITH_ARG:.*]] = cir.get_global @withArg : !cir.ptr<!rec_StructWithCtorArg>
-// CIR: %[[ZERO:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.double
-// CIR: cir.store{{.*}} %[[ZERO]], %[[TMP0]] : !cir.double, !cir.ptr<!cir.double>
-// CIR: cir.call @_ZN17StructWithCtorArgC1ERKd(%[[WITH_ARG]], %[[TMP0]]) : (!cir.ptr<!rec_StructWithCtorArg>, !cir.ptr<!cir.double>) -> ()
+// CIR: cir.scope {
+// CIR: %[[TMP0:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["ref.tmp0"]
+// CIR: %[[ZERO:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.double
+// CIR: cir.store{{.*}} %[[ZERO]], %[[TMP0]] : !cir.double, !cir.ptr<!cir.double>
+// CIR: cir.call @_ZN17StructWithCtorArgC1ERKd(%[[WITH_ARG]], %[[TMP0]]) : (!cir.ptr<!rec_StructWithCtorArg>, !cir.ptr<!cir.double>) -> ()
+// CIR: }
// LLVM: define {{.*}} void @__cxx_global_var_init()
// LLVM: %[[TMP0:.*]] = alloca double
|
This PR adds support for returning the result of a
co_awaitviaco_return. A new variable,__coawait_resume_rval, is introduced to store the returned value.