https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/144225
>From d5c7a04815acee8b792e95fcd376fc492bcadb58 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sat, 14 Jun 2025 16:21:20 +0200 Subject: [PATCH 1/4] [CIR] Upstream ComplexType builtin_complex --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 6 ++++ clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 33 +++++++++++++++++++++ clang/lib/CIR/CodeGen/CIRGenValue.h | 1 - clang/test/CIR/CodeGen/complex.cpp | 25 ++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 83825f0835a1e..3ae7a5e660572 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -91,6 +91,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, builder.create<cir::AssumeOp>(getLoc(e->getExprLoc()), argValue); return RValue::get(nullptr); } + case Builtin::BI__builtin_complex: { + mlir::Value real = emitScalarExpr(e->getArg(0)); + mlir::Value imag = emitScalarExpr(e->getArg(1)); + mlir::Value complex = builder.createComplexCreate(loc, real, imag); + return RValue::get(complex); + } } cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call"); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 26070a6ca307a..fea069fc07356 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -15,11 +15,25 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> { explicit ComplexExprEmitter(CIRGenFunction &cgf) : cgf(cgf), builder(cgf.getBuilder()) {} + //===--------------------------------------------------------------------===// + // Utilities + //===--------------------------------------------------------------------===// + + /// Given an expression with complex type that represents a value l-value, + /// this method emits the address of the l-value, then loads and returns the + /// result. + mlir::Value emitLoadOfLValue(const Expr *e) { + return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc()); + } + + mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc); + /// Store the specified real/imag parts into the /// specified value pointer. void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv, bool isInit); + mlir::Value VisitCallExpr(const CallExpr *e); mlir::Value VisitInitListExpr(InitListExpr *e); mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il); @@ -34,6 +48,16 @@ static const ComplexType *getComplexType(QualType type) { return cast<ComplexType>(cast<AtomicType>(type)->getValueType()); } +mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv, + SourceLocation loc) { + assert(lv.isSimple() && "non-simple complex l-value?"); + if (lv.getType()->isAtomicType()) + cgf.cgm.errorNYI("emitLoadOfLValue with Atomic LV"); + + const Address srcAddr = lv.getAddress(); + return builder.createLoad(cgf.getLoc(loc), srcAddr); +} + void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv, bool isInit) { if (lv.getType()->isAtomicType() || @@ -46,6 +70,15 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val, builder.createStore(loc, val, destAddr); } +mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) { + if (e->getCallReturnType(cgf.getContext())->isReferenceType()) + return emitLoadOfLValue(e); + + mlir::Location loc = cgf.getLoc(e->getExprLoc()); + auto complex = cgf.emitCallExpr(e).getComplexVal(); + return builder.createComplexCreate(loc, complex.first, complex.second); +} + mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) { mlir::Location loc = cgf.getLoc(e->getExprLoc()); if (e->getNumInits() == 2) { diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h index 84972fc7f9118..7180d92f8c314 100644 --- a/clang/lib/CIR/CodeGen/CIRGenValue.h +++ b/clang/lib/CIR/CodeGen/CIRGenValue.h @@ -88,7 +88,6 @@ class RValue { return er; } - // FIXME: Aggregate rvalues need to retain information about whether they are // volatile or not. Remove default to find all places that probably get this // wrong. diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index db0b9111ab4fb..8b3c43709484d 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -191,6 +191,31 @@ void foo8() { // 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 foo9(double r, double i) { + double _Complex c = __builtin_complex(r, i); +} + +// CIR: %[[INIT:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["c", init] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.double>, !cir.double +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.double>, !cir.double +// CIR: %[[COMPLEX:.*]] = cir.complex.create %[[TMP_A]], %[[TMP_B]] : !cir.double -> !cir.complex<!cir.double> +// CIR: cir.store{{.*}} %[[COMPLEX]], %[[INIT]] : !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>> + +// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8 +// LLVM: %[[TMP_A:.*]] = load double, ptr {{.*}}, align 8 +// LLVM: %[[TMP_B:.*]] = load double, ptr {{.*}}, align 8 +// LLVM: %[[TMP:.*]] = insertvalue { double, double } undef, double %[[TMP_A]], 0 +// LLVM: %[[TMP_2:.*]] = insertvalue { double, double } %[[TMP]], double %[[TMP_B]], 1 +// LLVM: store { double, double } %[[TMP_2]], ptr %[[COMPLEX]], align 8 + +// OGCG: %[[COMPLEX]] = alloca { double, double }, align 8 +// OGCG: %[[TMP_A:.*]] = load double, ptr {{.*}}, align 8 +// OGCG: %[[TMP_B:.*]] = load double, ptr {{.*}}, 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 %[[TMP_A]], ptr %[[C_REAL_PTR]], align 8 +// OGCG: store double %[[TMP_B]], ptr %[[C_IMAG_PTR]], align 8 + void foo14() { int _Complex c = 2i; } >From 35c060297ecc3811d604193e8bd055dcb6d4be6e Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Mon, 16 Jun 2025 21:15:12 +0200 Subject: [PATCH 2/4] Address code review comments --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 1 + clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 4 ++-- clang/test/CIR/CodeGen/complex.cpp | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 3ae7a5e660572..b723c884ea68d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -91,6 +91,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, builder.create<cir::AssumeOp>(getLoc(e->getExprLoc()), argValue); return RValue::get(nullptr); } + case Builtin::BI__builtin_complex: { mlir::Value real = emitScalarExpr(e->getArg(0)); mlir::Value imag = emitScalarExpr(e->getArg(1)); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index fea069fc07356..44fd6d29941ad 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -52,7 +52,7 @@ mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv, SourceLocation loc) { assert(lv.isSimple() && "non-simple complex l-value?"); if (lv.getType()->isAtomicType()) - cgf.cgm.errorNYI("emitLoadOfLValue with Atomic LV"); + cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV"); const Address srcAddr = lv.getAddress(); return builder.createLoad(cgf.getLoc(loc), srcAddr); @@ -62,7 +62,7 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv, bool isInit) { if (lv.getType()->isAtomicType() || (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) { - cgf.cgm.errorNYI("StoreOfComplex with Atomic LV"); + cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV"); return; } diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 8b3c43709484d..721db235b37de 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -191,8 +191,8 @@ void foo8() { // 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 foo9(double r, double i) { - double _Complex c = __builtin_complex(r, i); +void foo9(double a, double b) { + double _Complex c = __builtin_complex(a, b); } // CIR: %[[INIT:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["c", init] >From 801e871692141e8f59d74f29ba2dd67c83d7fed7 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Tue, 17 Jun 2025 20:46:30 +0200 Subject: [PATCH 3/4] Address code review comments --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 2 ++ clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index b723c884ea68d..b86a41d8b4e87 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -98,6 +98,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, mlir::Value complex = builder.createComplexCreate(loc, real, imag); return RValue::get(complex); } + default: + break; } cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call"); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 44fd6d29941ad..12e8e27948cf7 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -74,9 +74,7 @@ mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) { if (e->getCallReturnType(cgf.getContext())->isReferenceType()) return emitLoadOfLValue(e); - mlir::Location loc = cgf.getLoc(e->getExprLoc()); - auto complex = cgf.emitCallExpr(e).getComplexVal(); - return builder.createComplexCreate(loc, complex.first, complex.second); + return cgf.emitCallExpr(e).getValue(); } mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) { >From 17f205410a0cb4754697b5af5f628f356a68d83b Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Tue, 17 Jun 2025 20:51:51 +0200 Subject: [PATCH 4/4] Fix code review comments --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index b86a41d8b4e87..cff139a7802df 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -78,6 +78,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, assert(!cir::MissingFeatures::builtinCallMathErrno()); assert(!cir::MissingFeatures::builtinCall()); + mlir::Location loc = getLoc(e->getExprLoc()); + switch (builtinIDIfNoAsmLabel) { default: break; @@ -88,7 +90,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, return RValue::get(nullptr); mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0)); - builder.create<cir::AssumeOp>(getLoc(e->getExprLoc()), argValue); + builder.create<cir::AssumeOp>(loc, argValue); return RValue::get(nullptr); } @@ -98,8 +100,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, mlir::Value complex = builder.createComplexCreate(loc, real, imag); return RValue::get(complex); } - default: - break; } cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call"); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits