llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) <details> <summary>Changes</summary> This change adds support for builtin_complex https://github.com/llvm/llvm-project/issues/141365 --- Full diff: https://github.com/llvm/llvm-project/pull/144225.diff 4 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+9-1) - (modified) clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp (+33) - (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+1) - (modified) clang/test/CIR/CodeGen/complex.cpp (+24) ``````````diff diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index c59ac78210f81..b1b2e9080af45 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -50,6 +50,14 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, } mlir::Location loc = getLoc(e->getExprLoc()); - cgm.errorNYI(loc, "non constant foldable builtin calls"); + switch (builtinID) { + case Builtin::BI__builtin_complex: { + mlir::Value real = emitScalarExpr(e->getArg(0)); + mlir::Value imag = emitScalarExpr(e->getArg(1)); + return RValue::getComplex(real, imag); + } + default: + cgm.errorNYI(loc, "non constant foldable builtin calls"); + } return getUndefRValue(e->getType()); } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 2ffe75a388e98..0c7c5c382267c 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); }; @@ -32,6 +46,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() || @@ -44,6 +68,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 c1e08ba1e9b67..ca932382c5150 100644 --- a/clang/lib/CIR/CodeGen/CIRGenValue.h +++ b/clang/lib/CIR/CodeGen/CIRGenValue.h @@ -96,6 +96,7 @@ class RValue { er.isVolatile = false; return er; } + static RValue getComplex(const std::pair<mlir::Value, mlir::Value> &c) { return getComplex(c.first, c.second); } diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index d193b9f32efbc..8319a7ddecb1d 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -176,3 +176,27 @@ 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 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 `````````` </details> https://github.com/llvm/llvm-project/pull/144225 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits