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 <[email protected]>
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<ComplexExprEmitter, mlir::Value> {
     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<int> co_return_with_dtor(int flag) {
 // OGCG: cleanup4:
 // OGCG:   call void @_ZN7HasDtorD1Ev({{.*}} %[[LOCAL]])
 // OGCG:   br label %coro.final
+
+folly::coro::Task<int __complex__> fetchData() noexcept {
+  int __complex__ a;
+  co_return a;
+}
+
+folly::coro::Task<int __complex__> 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<!rec_folly3A3Acoro3A3ATask3C_Complex_int3E>, ["ref.tmp1"]
+// CIR: %[[RESUME_VAL_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, 
!cir.ptr<!cir.complex<!s32i>>, ["__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<!rec_folly3A3Acoro3A3ATask3C_Complex_int3E>
+
+// CIR:       cir.await(user, ready : {
+// CIR:       }, suspend : {
+// CIR:       }, resume : {
+// CIR:         %[[RESUME_VAL:.*]] = cir.call 
@_ZN5folly4coro4TaskICiE12await_resumeEv(%[[COMPLEX_ADDR]]) : 
(!cir.ptr<!rec_folly3A3Acoro3A3ATask3C_Complex_int3E> {llvm.align = 1 : i64, 
llvm.dereferenceable = 1 : i64, llvm.nonnull, llvm.noundef}) -> 
(!cir.complex<!s32i> {llvm.noundef})
+// CIR:         cir.store %[[RESUME_VAL]], %[[RESUME_VAL_ADDR]] : 
!cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
+// CIR:       },)
+// CIR:       %[[V:.*]] = cir.load %[[RESUME_VAL_ADDR]] : 
!cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
+// CIR:       cir.yield
+// CIR:   }
+
+// CIR: } cleanup  normal {
+// CIR: }
+
+// OGCG: define dso_local void @_Z16complex_co_awaitv()
+
+// OGCG: %[[RESUME_VAL_ADDR:.*]] = alloca { i32, i32 }, align 4
+// OGCG: %[[RESUME_REAL_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[RESUME_IMAG_ADDR:.*]] = alloca i32, align 4
+
+// OGCG: coro.init:
+// OGCG: await.ready:
+// OGCG:   %[[RESUME_VAL:.*]] = call noundef i64 
@_ZN5folly4coro4TaskICiE12await_resumeEv(ptr noundef nonnull align 1 
dereferenceable(1) %{{.*}})
+// OGCG:   store i64 %[[RESUME_VAL]], ptr %[[RESUME_VAL_ADDR]], align 4
+// OGCG:   %[[RESUME_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr %[[RESUME_VAL_ADDR]], i32 0, i32 0
+// OGCG:   %[[RESUME_REAL:.*]] = load i32, ptr %[[RESUME_REAL_PTR]], align 4
+// OGCG:   store i32 %[[RESUME_REAL]], ptr %[[RESUME_REAL_ADDR]], align 4
+// OGCG:   %[[RESUME_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, 
ptr %[[RESUME_VAL_ADDR]], i32 0, i32 1
+// OGCG:   %[[RESUME_IMAG:.*]] = load i32, ptr %[[RESUME_IMAG_PTR]], align 4
+// OGCG:   store i32 %[[RESUME_IMAG]], ptr %[[RESUME_IMAG_ADDR]], align 4
+// OGCG:   br label %[[CLEANUP_FROM_AWAIT_READY:.*]]
+
+// OGCG: [[CLEANUP_CONT:.*]]:
+// OGCG:   %[[RESUME_REAL:.*]] = load i32, ptr %[[RESUME_REAL_ADDR]], align 4
+// OGCG:   %[[RESUME_IMAG:.*]] = load i32, ptr %[[RESUME_IMAG_ADDR]], align 4

>From c9e465939b099c5d574b78fe0057641f35a39a6c Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Thu, 7 May 2026 19:48:03 +0200
Subject: [PATCH 2/2] Remove anyValue and switch on the kind

---
 clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp | 12 +++++++++++-
 clang/lib/CIR/CodeGen/CIRGenValue.h       |  2 --
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
index 0bc198f07e8d8..870015c844a6d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp
@@ -558,7 +558,17 @@ 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();
+            mlir::Value value;
+            RValue rv = awaitRes.rv;
+            if (rv.isScalar()) {
+              value = rv.getValue();
+            } else if (rv.isComplex()) {
+              value = rv.getComplexValue();
+            } else {
+              cgf.cgm.errorNYI("emitSuspendExpression: Aggregate value");
+              return;
+            }
+
             tmpResumeRValAddr = cgf.emitAlloca(
                 "__coawait_resume_rval", value.getType(), loc, 
CharUnits::One(),
                 builder.getBestAllocaInsertPoint(scopeParentBlock));
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h 
b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 89e25927ef792..e70dac5851189 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -59,8 +59,6 @@ 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!");

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

Reply via email to