diff options
author | Amr Hesham <amr96@programmer.net> | 2025-06-16 20:10:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-16 20:10:40 +0200 |
commit | fccab5d757778204666d70e2f1592952fc8b336d (patch) | |
tree | f244bc6c636b53ba8d665adeb43e3948e6c702cf | |
parent | 492d25bbe12af7702a392fa7ad41eb9e09a48cf2 (diff) | |
download | llvm-fccab5d757778204666d70e2f1592952fc8b336d.zip llvm-fccab5d757778204666d70e2f1592952fc8b336d.tar.gz llvm-fccab5d757778204666d70e2f1592952fc8b336d.tar.bz2 |
[CIR] Upstream ComplexType ImaginaryLiteral (#144223)
This change adds support for ComplexType ImaginaryLiteral
https://github.com/llvm/llvm-project/issues/141365
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 30 | ||||
-rw-r--r-- | clang/test/CIR/CodeGen/complex.cpp | 29 |
2 files changed, 59 insertions, 0 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 2ffe75a..26070a6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -21,6 +21,8 @@ public: bool isInit); mlir::Value VisitInitListExpr(InitListExpr *e); + + mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il); }; } // namespace @@ -66,6 +68,34 @@ mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) { return builder.create<cir::ConstantOp>(loc, complexAttr); } +mlir::Value +ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) { + auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType())); + mlir::Type elementTy = ty.getElementType(); + mlir::Location loc = cgf.getLoc(il->getExprLoc()); + + mlir::TypedAttr realValueAttr; + mlir::TypedAttr imagValueAttr; + + if (mlir::isa<cir::IntType>(elementTy)) { + llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue(); + realValueAttr = cir::IntAttr::get(elementTy, 0); + imagValueAttr = cir::IntAttr::get(elementTy, imagValue); + } else { + assert(mlir::isa<cir::CIRFPTypeInterface>(elementTy) && + "Expected complex element type to be floating-point"); + + llvm::APFloat imagValue = + cast<FloatingLiteral>(il->getSubExpr())->getValue(); + realValueAttr = cir::FPAttr::get( + elementTy, llvm::APFloat::getZero(imagValue.getSemantics())); + imagValueAttr = cir::FPAttr::get(elementTy, imagValue); + } + + auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr); + return builder.create<cir::ConstantOp>(loc, complexAttr); +} + mlir::Value CIRGenFunction::emitComplexExpr(const Expr *e) { assert(e && getComplexType(e->getType()) && "Invalid complex expression to emit"); diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index d193b9f3..db0b911 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -176,3 +176,32 @@ void foo7() { // OGCG: store float %[[TMP_A]], ptr %[[C_REAL_PTR]], align 4 // OGCG: store float 2.000000e+00, ptr %[[C_IMAG_PTR]], align 4 +void foo8() { + double _Complex c = 2.00i; +} + +// CIR: %[[COMPLEX:.*]] = cir.const #cir.const_complex<#cir.fp<0.000000e+00> : !cir.double, #cir.fp<2.000000e+00> : !cir.double> : !cir.complex<!cir.double> + +// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8 +// LLVM: store { double, double } { double 0.000000e+00, double 2.000000e+00 }, ptr %[[COMPLEX]], align 8 + +// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8 +// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0 +// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1 +// OGCG: store double 0.000000e+00, ptr %[[C_REAL_PTR]], align 8 +// OGCG: store double 2.000000e+00, ptr %[[C_IMAG_PTR]], align 8 + +void foo14() { + int _Complex c = 2i; +} + +// CIR: %[[COMPLEX:.*]] = cir.const #cir.const_complex<#cir.int<0> : !s32i, #cir.int<2> : !s32i> : !cir.complex<!s32i> + +// LLVM: %[[COMPLEX:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: store { i32, i32 } { i32 0, i32 2 }, ptr %[[COMPLEX]], align 4 + +// OGCG: %[[COMPLEX:.*]] = alloca { i32, i32 }, align 4 +// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX]], i32 0, i32 0 +// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX]], i32 0, i32 1 +// OGCG: store i32 0, ptr %[[C_REAL_PTR]], align 4 +// OGCG: store i32 2, ptr %[[C_IMAG_PTR]], align 4 |