From 0605fc936fef32cd5e0f70cc36fc00c9d8643d90 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sat, 5 Jul 2025 14:27:21 +0200 Subject: [PATCH 1/3] [CIR] Implement CXXScalarValueInitExpr for ComplexType --- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 12 ++++++++++++ clang/test/CIR/CodeGen/complex.cpp | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 55c7db7b851b2..f13169a589538 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -47,6 +47,7 @@ class ComplexExprEmitter : public StmtVisitor { mlir::Value VisitCallExpr(const CallExpr *e); mlir::Value VisitCastExpr(CastExpr *e); mlir::Value VisitChooseExpr(ChooseExpr *e); + mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e); mlir::Value VisitDeclRefExpr(DeclRefExpr *e); mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *e); mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e); @@ -201,6 +202,17 @@ mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) { return Visit(e->getChosenSubExpr()); } +mlir::Value +ComplexExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) { + mlir::Location loc = cgf.getLoc(e->getExprLoc()); + QualType complexElemTy = + e->getType()->castAs()->getElementType(); + mlir::Type complexElemLLVMTy = cgf.convertType(complexElemTy); + mlir::TypedAttr defaultValue = builder.getZeroInitAttr(complexElemLLVMTy); + auto complexAttr = cir::ConstComplexAttr::get(defaultValue, defaultValue); + return builder.create(loc, complexAttr); +} + mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) { if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e)) return emitConstant(constant, e); diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 25d81785ef482..2140fcf7cf019 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -717,6 +717,24 @@ void foo27(bool cond, int _Complex a, int _Complex b) { // OGCG: store i32 %[[REAL]], ptr %[[RESULT_REAL_PTR]], align 4 // OGCG: store i32 %[[IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4 +void foo28() { + using IntComplex = int _Complex; + int _Complex a = IntComplex(); +} + +// CIR: %[[INIT:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["a", init] +// CIR: %[[COMPLEX:.*]] = cir.const #cir.const_complex<#cir.int<0> : !s32i, #cir.int<0> : !s32i> : !cir.complex +// CIR: cir.store align(4) %[[COMPLEX]], %[[INIT]] : !cir.complex, !cir.ptr> + +// LLVM: %[[INIT:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: store { i32, i32 } zeroinitializer, ptr %[[INIT]], align 4 + +// OGCG: %[[INIT:.*]] = alloca { i32, i32 }, align 4 +// OGCG: %[[INIT_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[INIT]], i32 0, i32 0 +// OGCG: %[[INIT_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[INIT]], i32 0, i32 1 +// OGCG: store i32 0, ptr %[[INIT_REAL_PTR]], align 4 +// OGCG: store i32 0, ptr %[[INIT_IMAG_PTR]], align 4 + void foo29() { using IntComplex = int _Complex; int _Complex a = IntComplex{}; From 6633ffea120902851b38be4854f568eb285812ee Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Mon, 7 Jul 2025 21:51:44 +0200 Subject: [PATCH 2/3] Replace creating cir::ConstComplexAttr with getNullValue --- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 8 ++------ clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 13 +++++++++++-- clang/test/CIR/CodeGen/complex.cpp | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index f13169a589538..858e80720d4c2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -205,12 +205,8 @@ mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) { mlir::Value ComplexExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) { mlir::Location loc = cgf.getLoc(e->getExprLoc()); - QualType complexElemTy = - e->getType()->castAs()->getElementType(); - mlir::Type complexElemLLVMTy = cgf.convertType(complexElemTy); - mlir::TypedAttr defaultValue = builder.getZeroInitAttr(complexElemLLVMTy); - auto complexAttr = cir::ConstComplexAttr::get(defaultValue, defaultValue); - return builder.create(loc, complexAttr); + mlir::Type complexLLVMTy = cgf.convertType(e->getType()); + return builder.getNullValue(complexLLVMTy, loc); } mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) { diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 5ac42b6a63b09..09dea282e5718 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1044,10 +1044,19 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite( getTypeConverter())); return mlir::success(); } else if (auto complexTy = mlir::dyn_cast(op.getType())) { - auto complexAttr = mlir::cast(op.getValue()); - mlir::Type complexElemTy = complexTy.getElementType(); + auto complexElemTy = complexTy.getElementType(); mlir::Type complexElemLLVMTy = typeConverter->convertType(complexElemTy); + if (auto zeroInitAttr = mlir::dyn_cast(op.getValue())) { + mlir::TypedAttr zeroAttr = rewriter.getZeroAttr(complexElemLLVMTy); + mlir::ArrayAttr array = rewriter.getArrayAttr({zeroAttr, zeroAttr}); + rewriter.replaceOpWithNewOp( + op, getTypeConverter()->convertType(op.getType()), array); + return mlir::success(); + } + + auto complexAttr = mlir::cast(op.getValue()); + mlir::Attribute components[2]; if (mlir::isa(complexElemTy)) { components[0] = rewriter.getIntegerAttr( diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 2140fcf7cf019..6e7e889df146f 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -723,7 +723,7 @@ void foo28() { } // CIR: %[[INIT:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["a", init] -// CIR: %[[COMPLEX:.*]] = cir.const #cir.const_complex<#cir.int<0> : !s32i, #cir.int<0> : !s32i> : !cir.complex +// CIR: %[[COMPLEX:.*]] = cir.const #cir.zero : !cir.complex // CIR: cir.store align(4) %[[COMPLEX]], %[[INIT]] : !cir.complex, !cir.ptr> // LLVM: %[[INIT:.*]] = alloca { i32, i32 }, i64 1, align 4 From 7732455d6b4ed382dc0ff43e49d0551d926a899f Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Mon, 7 Jul 2025 22:12:59 +0200 Subject: [PATCH 3/3] Address code review comments --- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 4 ++-- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 858e80720d4c2..84fad959ebf49 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -205,8 +205,8 @@ mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) { mlir::Value ComplexExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) { mlir::Location loc = cgf.getLoc(e->getExprLoc()); - mlir::Type complexLLVMTy = cgf.convertType(e->getType()); - return builder.getNullValue(complexLLVMTy, loc); + mlir::Type complexTy = cgf.convertType(e->getType()); + return builder.getNullValue(complexTy, loc); } mlir::Value ComplexExprEmitter::VisitDeclRefExpr(DeclRefExpr *e) { diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 09dea282e5718..af307f6ad673d 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1044,7 +1044,7 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite( getTypeConverter())); return mlir::success(); } else if (auto complexTy = mlir::dyn_cast(op.getType())) { - auto complexElemTy = complexTy.getElementType(); + mlir::Type complexElemTy = complexTy.getElementType(); mlir::Type complexElemLLVMTy = typeConverter->convertType(complexElemTy); if (auto zeroInitAttr = mlir::dyn_cast(op.getValue())) {