https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/144262
None >From fa6756886c5e0d432445d2364d92ff38ad0127ae Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sun, 15 Jun 2025 14:45:12 +0200 Subject: [PATCH] [CIR] Upstream __imag__ for ComplexType --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 20 +++++++++++++++++++ clang/test/CIR/CodeGen/complex.cpp | 23 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 615a0e7bef556..a1896c5e7f7e5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -604,6 +604,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitUnaryLNot(const UnaryOperator *e); mlir::Value VisitUnaryReal(const UnaryOperator *e); + mlir::Value VisitUnaryImag(const UnaryOperator *e); mlir::Value VisitCXXThisExpr(CXXThisExpr *te) { return cgf.loadCXXThis(); } @@ -1912,6 +1913,25 @@ mlir::Value ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *e) { return Visit(op); } +mlir::Value ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *e) { + // TODO(cir): handle scalar promotion. + Expr *op = e->getSubExpr(); + if (op->getType()->isAnyComplexType()) { + // If it's an l-value, load through the appropriate subobject l-value. + // Note that we have to ask E because Op might be an l-value that + // this won't work for, e.g. an Obj-C property. + if (e->isGLValue()) + return cgf.emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc()) + .getScalarVal(); + + // Otherwise, calculate and project. + cgf.cgm.errorNYI(e->getSourceRange(), + "VisitUnaryImag calculate and project"); + } + + return Visit(op); +} + /// Return the size or alignment of the type of argument of the sizeof /// expression as an integer. mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 3d1e395d7613c..6c29dc3e1b7fe 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -226,3 +226,26 @@ void foo12() { // OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0 // OGCG: %[[REAL:.*]] = load double, ptr %[[REAL_PTR]], align 8 // OGCG: store double %[[REAL]], ptr %[[INIT]], align 8 + +void foo13() { + double _Complex c; + double imag = __imag__ c; +} + +// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["c"] +// CIR: %[[INIT:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["imag", init] +// CIR: %[[IMAG_PTR:.*]] = cir.complex.imag_ptr %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double> +// CIR: %[[IMAG:.*]] = cir.load{{.*}} %[[REAL_PTR]] : !cir.ptr<!cir.double>, !cir.double +// CIR: cir.store{{.*}} %[[IMAG]], %[[INIT]] : !cir.double, !cir.ptr<!cir.double> + +// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8 +// LLVM: %[[INIT:.*]] = alloca double, i64 1, align 8 +// LLVM: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1 +// LLVM: %[[IMAG:.*]] = load double, ptr %[[IMAG_PTR]], align 8 +// LLVM: store double %[[IMAG]], ptr %[[INIT]], align 8 + +// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8 +// OGCG: %[[INIT:.*]] = alloca double, align 8 +// OGCG: %[[IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1 +// OGCG: %[[IMAG:.*]] = load double, ptr %[[IMAG_PTR]], align 8 +// OGCG: store double %[[IMAG]], ptr %[[INIT]], align 8 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits