https://github.com/AmrDeveloper updated
https://github.com/llvm/llvm-project/pull/194027
>From 7ba981f976cf0ef4d7b982409ed526c2111ba276 Mon Sep 17 00:00:00 2001
From: Amr Hesham
Date: Fri, 24 Apr 2026 21:07:58 +0200
Subject: [PATCH 1/2] [CIR] Implement CoawaitExpr for ComplexType
---
clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp | 10 ++--
clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 3 +-
clang/lib/CIR/CodeGen/CIRGenValue.h | 2 +
clang/test/CIR/CodeGen/coro-task.cpp| 59 +
4 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 12408b7c59458..0bc198f07e8d8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -558,12 +558,12 @@ emitSuspendExpression(CIRGenFunction &cgf, CGCoroData
&coro,
if (!awaitRes.rv.isIgnored()) {
// Create the alloca in the block before the scope wrapping
// cir.await.
+mlir::Value value = awaitRes.rv.getAnyValue();
tmpResumeRValAddr = cgf.emitAlloca(
-"__coawait_resume_rval", awaitRes.rv.getValue().getType(), loc,
-CharUnits::One(),
+"__coawait_resume_rval", value.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(),
+builder.CIRBaseBuilderTy::createStore(loc, value,
tmpResumeRValAddr);
}
}
@@ -614,7 +614,9 @@ static RValue emitSuspendExpr(CIRGenFunction &cgf,
// once we have a testcase and prove all pieces work.
cgf.cgm.errorNYI("emitSuspendExpr Aggregate");
} else { // complex
-cgf.cgm.errorNYI("emitSuspendExpr Complex");
+rval = RValue::getComplex(cir::LoadOp::create(
+cgf.getBuilder(), scopeLoc, rval.getComplexValue().getType(),
+tmpResumeRValAddr));
}
return rval;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index b359c2bd719e4..6a26b2c987f3e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -86,8 +86,7 @@ class ComplexExprEmitter : public
StmtVisitor {
return Visit(pe->getReplacement());
}
mlir::Value VisitCoawaitExpr(CoawaitExpr *s) {
-cgf.cgm.errorNYI(s->getExprLoc(), "ComplexExprEmitter VisitCoawaitExpr");
-return {};
+return cgf.emitCoawaitExpr(*s).getComplexValue();
}
mlir::Value VisitCoyieldExpr(CoyieldExpr *s) {
cgf.cgm.errorNYI(s->getExprLoc(), "ComplexExprEmitter VisitCoyieldExpr");
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h
b/clang/lib/CIR/CodeGen/CIRGenValue.h
index e70dac5851189..89e25927ef792 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -59,6 +59,8 @@ class RValue {
return value;
}
+ mlir::Value getAnyValue() const { return value; }
+
/// Return the value of this complex value.
mlir::Value getComplexValue() const {
assert(isComplex() && "Not a complex!");
diff --git a/clang/test/CIR/CodeGen/coro-task.cpp
b/clang/test/CIR/CodeGen/coro-task.cpp
index 2874009157f88..46d7cde18b047 100644
--- a/clang/test/CIR/CodeGen/coro-task.cpp
+++ b/clang/test/CIR/CodeGen/coro-task.cpp
@@ -839,3 +839,62 @@ folly::coro::Task co_return_with_dtor(int flag) {
// OGCG: cleanup4:
// OGCG: call void @_ZN7HasDtorD1Ev({{.*}} %[[LOCAL]])
// OGCG: br label %coro.final
+
+folly::coro::Task fetchData() noexcept {
+ int __complex__ a;
+ co_return a;
+}
+
+folly::coro::Task complex_co_await() noexcept {
+ co_await fetchData();
+}
+
+// CIR: cir.func coroutine {{.*}} @_Z16complex_co_awaitv
+
+// CIR: %[[COMPLEX_ADDR:.*]] = cir.alloca
!rec_folly3A3Acoro3A3ATask3C_Complex_int3E,
!cir.ptr, ["ref.tmp1"]
+// CIR: %[[RESUME_VAL_ADDR:.*]] = cir.alloca !cir.complex,
!cir.ptr>, ["__coawait_resume_rval"]
+
+// CIR: cir.cleanup.scope {
+// CIR: cir.await(init, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: },)
+
+// CIR: cir.coro.body {
+// CIR: %[[CALL:.*]] = cir.call @_Z9fetchDatav() nothrow : () ->
!rec_folly3A3Acoro3A3ATask3C_Complex_int3E
+// CIR: cir.store {{.*}} %[[CALL]], %[[COMPLEX_ADDR]] :
!rec_folly3A3Acoro3A3ATask3C_Complex_int3E,
!cir.ptr
+
+// CIR: cir.await(user, ready : {
+// CIR: }, suspend : {
+// CIR: }, resume : {
+// CIR: %[[RESUME_VAL:.*]] = cir.call
@_ZN5folly4coro4TaskICiE12await_resumeEv(%[[COMPLEX_ADDR]]) :
(!cir.ptr {llvm.align = 1 : i64,
llvm.dereferenceable = 1 : i64, llvm.nonnull, llvm.noundef}) ->
(!cir.complex {llvm.noundef})
+// CIR: cir.store %[[RESUME_VAL]], %[[RESUME_VAL_ADDR]] :
!cir.complex, !cir.ptr>
+// CIR: