Author: Amr Hesham
Date: 2025-12-09T11:02:19+01:00
New Revision: a94f01a6f868bf8ead1de190d1461dd5ced81a2f

URL: 
https://github.com/llvm/llvm-project/commit/a94f01a6f868bf8ead1de190d1461dd5ced81a2f
DIFF: 
https://github.com/llvm/llvm-project/commit/a94f01a6f868bf8ead1de190d1461dd5ced81a2f.diff

LOG: [CIR] Implement StmtExpr for ComplexType (#171196)

Implement StmtExpr for ComplexType

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
    clang/test/CIR/CodeGen/stmt-expr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index fe06f8cc2c430..d1124252e13cd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -400,8 +400,13 @@ mlir::Value ComplexExprEmitter::VisitCallExpr(const 
CallExpr *e) {
 }
 
 mlir::Value ComplexExprEmitter::VisitStmtExpr(const StmtExpr *e) {
-  cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitExpr");
-  return {};
+  CIRGenFunction::StmtExprEvaluation eval(cgf);
+  Address retAlloca =
+      cgf.createMemTemp(e->getType(), cgf.getLoc(e->getSourceRange()));
+  (void)cgf.emitCompoundStmt(*e->getSubStmt(), &retAlloca);
+  assert(retAlloca.isValid() && "Expected complex return value");
+  return emitLoadOfLValue(cgf.makeAddrLValue(retAlloca, e->getType()),
+                          e->getExprLoc());
 }
 
 mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,

diff  --git a/clang/test/CIR/CodeGen/stmt-expr.cpp 
b/clang/test/CIR/CodeGen/stmt-expr.cpp
index f65bf9b7e010f..b645b15087ec5 100644
--- a/clang/test/CIR/CodeGen/stmt-expr.cpp
+++ b/clang/test/CIR/CodeGen/stmt-expr.cpp
@@ -88,3 +88,46 @@ void cleanup() {
 // OGCG:   %[[WD:.+]] = alloca %struct.with_dtor
 // OGCG:   call void @_ZN9with_dtorD1Ev(ptr {{.*}} %[[WD]])
 // OGCG:   ret void
+
+void gnu_statement_extension() {
+  float b = __real__ ({float _Complex a; a;});
+}
+
+// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.float, !cir.ptr<!cir.float>, ["b", 
init]
+// CIR: %[[TMP_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, 
!cir.ptr<!cir.complex<!cir.float>>, ["tmp"]
+// CIR: cir.scope {
+// CIR:   %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, 
!cir.ptr<!cir.complex<!cir.float>>, ["a"]
+// CIR:   %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR:   cir.store {{.*}} %[[TMP_A]], %[[TMP_ADDR]] : 
!cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
+// CIR: }
+// CIR: %[[TMP:.*]] = cir.load {{.*}} %[[TMP_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.float> -> 
!cir.float
+// CIR: cir.store {{.*}} %[[REAL]], %[[B_ADDR]] : !cir.float, 
!cir.ptr<!cir.float>
+
+// LLVM:   %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 4
+// LLVM:   %[[B_ADDR:.*]] = alloca float, i64 1, align 4
+// LLVM:   %[[TMP_ADDR:.*]] = alloca { float, float }, i64 1, align 4
+// LLVM:   br label %[[LABEL_1:.*]]
+// LLVM: [[LABEL_1]]:
+// LLVM:   %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4
+// LLVM:   store { float, float } %[[TMP_A]], ptr %[[TMP_ADDR]], align 4
+// LLVM:   br label %[[LABEL_2:.*]]
+// LLVM: [[LABEL_2]]:
+// LLVM:   %[[TMP:.*]] = load { float, float }, ptr %[[TMP_ADDR]], align 4
+// LLVM:   %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0
+// LLVM:   store float %[[REAL]], ptr %[[B_ADDR]], align 4
+
+// OGCG: %[[B_ADDR:.*]] = alloca float, align 4
+// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[TMP_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[A_ADDR]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
+// OGCG: %[[TMP_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, 
ptr %[[TMP_ADDR]], i32 0, i32 0
+// OGCG: %[[TMP_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, 
ptr %[[TMP_ADDR]], i32 0, i32 1
+// OGCG: store float %[[A_REAL]], ptr %[[TMP_REAL_PTR]], align 4
+// OGCG: store float %[[A_IMAG]], ptr %[[TMP_IMAG_PTR]], align 4
+// OGCG: %[[TMP_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, 
ptr %[[TMP_ADDR]], i32 0, i32 0
+// OGCG: %[[TMP_REAL:.*]] = load float, ptr %[[TMP_REAL_PTR]], align 4
+// OGCG: store float %[[TMP_REAL]], ptr %[[B_ADDR]], align 4


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

Reply via email to