[clang] [CIR] Implement CoawaitExpr for ComplexType (PR #194027)

2026-05-09 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor approved this pull request.

lgtm

https://github.com/llvm/llvm-project/pull/194027
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement CoawaitExpr for ComplexType (PR #194027)

2026-05-07 Thread Amr Hesham via cfe-commits


@@ -59,6 +59,8 @@ class RValue {
 return value;
   }
 
+  mlir::Value getAnyValue() const { return value; }

AmrDeveloper wrote:

I will create NFC once this PR is merged to rename it

https://github.com/llvm/llvm-project/pull/194027
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement CoawaitExpr for ComplexType (PR #194027)

2026-05-07 Thread Amr Hesham via cfe-commits


@@ -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();

AmrDeveloper wrote:

That makes sense. I removed anyValue and added NYI for the aggregate value

https://github.com/llvm/llvm-project/pull/194027
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement CoawaitExpr for ComplexType (PR #194027)

2026-05-07 Thread Amr Hesham via cfe-commits

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:   

[clang] [CIR] Implement CoawaitExpr for ComplexType (PR #194027)

2026-05-06 Thread Andy Kaylor via cfe-commits


@@ -59,6 +59,8 @@ class RValue {
 return value;
   }
 
+  mlir::Value getAnyValue() const { return value; }

andykaylor wrote:

Classic codegen has `getScalarVal`, and it would make sense to align with that. 
Right now, it should be a simple matter to replace all uses of `getValue` with 
`getScalarVal`. I have concerns about `getAnyVal` though. I think the assert in 
`getScalarValue` in classic codegen is necessary because aggregate and complex 
r-values don't have a single value to be returned. It looks to me like maybe we 
have that same issue in CIR with aggregate r-values.

https://github.com/llvm/llvm-project/pull/194027
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Implement CoawaitExpr for ComplexType (PR #194027)

2026-05-06 Thread Andy Kaylor via cfe-commits


@@ -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();

andykaylor wrote:

If `awaitRes` is an aggregate, this will be UB.

https://github.com/llvm/llvm-project/pull/194027
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits