https://github.com/xakep8 updated https://github.com/llvm/llvm-project/pull/226095
>From e8d9129c83c10f75e5df43e6aaa24149fb258c17 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Thu, 24 Sep 2026 15:08:58 +0530 Subject: [PATCH] [CIR] Lowering for __builtin_reduce_assoc_fadd Added lowering for __builtin_reduce_assoc_fadd with the use of the new implementation of CIR FastMathFlags, following same lowering path as Classic Codegen. Added tests for the same. --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 39 ++++++++++++++----- .../builtin-reduce-arithmetic-sve.c | 22 +++++++++++ .../builtin-reduce-arithmetic.c | 34 ++++++++++++++++ 3 files changed, 85 insertions(+), 10 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 245708691b7d9..3a37966854380 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2240,22 +2240,41 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, cast<cir::VectorType>(convertType(e->getArg(0)->getType())) .getElementType()); case Builtin::BI__builtin_reduce_assoc_fadd: - return errorBuiltinNYI(*this, e, builtinID); case Builtin::BI__builtin_reduce_in_order_fadd: { - assert(e->getNumArgs() == 2 && - "__builtin_reduce_in_order_fadd requires a start value"); + bool isAssociative = + builtinIDIfNoAsmLabel == Builtin::BI__builtin_reduce_assoc_fadd; + + assert((isAssociative ? e->getNumArgs() == 1 || e->getNumArgs() == 2 + : e->getNumArgs() == 2) && + "invalid argument count for floating-point reduction"); mlir::Value vector = emitScalarExpr(e->getArg(0)); auto vectorTy = cast<cir::VectorType>(vector.getType()); mlir::Type scalarTy = vectorTy.getElementType(); mlir::Location loc = getLoc(e->getExprLoc()); - mlir::Value startValue = emitScalarExpr(e->getArg(1)); - if (startValue.getType() != scalarTy) - startValue = - builder.createCast(getLoc(e->getArg(1)->getExprLoc()), - cir::CastKind::floating, startValue, scalarTy); + mlir::Value startValue; + if (e->getNumArgs() == 2) { + startValue = emitScalarExpr(e->getArg(1)); + if (startValue.getType() != scalarTy) + startValue = + builder.createCast(getLoc(e->getArg(1)->getExprLoc()), + cir::CastKind::floating, startValue, scalarTy); + } else { + auto fpTy = cast<cir::FPTypeInterface>(scalarTy); + startValue = cir::ConstantOp::create( + builder, loc, + cir::FPAttr::get(scalarTy, + llvm::APFloat::getZero(fpTy.getFloatSemantics(), + /*Negative=*/true))); + } + SmallVector<mlir::Value, 2> args = {startValue, vector}; - mlir::Value result = - builder.emitIntrinsicCallOp(loc, "vector.reduce.fadd", scalarTy, args); + cir::FastMathFlagsAttr fastMath; + if (isAssociative) + fastMath = cir::FastMathFlagsAttr::get(&getMLIRContext(), + cir::FastMathFlags::reassoc); + + mlir::Value result = builder.emitIntrinsicCallOp(loc, "vector.reduce.fadd", + scalarTy, fastMath, args); return RValue::get(result); } case Builtin::BI__builtin_reduce_maximum: diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c index fbd9752b255c3..2ce6bdad76727 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c @@ -92,9 +92,31 @@ float test_sve_reduce_min_float(svfloat32_t x) { return __builtin_reduce_min(x); } +float test_sve_reduce_assoc_fadd(svfloat32_t x, float start) { + // CIR-LABEL: @test_sve_reduce_assoc_fadd + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_assoc_fadd + // LLVM: call reassoc float @llvm.vector.reduce.fadd.nxv4f32(float %{{.*}}, <vscale x 4 x float> + // LLVM: ret float + return __builtin_reduce_assoc_fadd(x, start); +} + +float test_sve_reduce_assoc_fadd_default_start(svfloat32_t x) { + // CIR-LABEL: @test_sve_reduce_assoc_fadd_default_start + // CIR: %[[START:.*]] = cir.const #cir.fp<-0.000000e+00> : !cir.float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[START]], {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_assoc_fadd_default_start + // LLVM: call reassoc float @llvm.vector.reduce.fadd.nxv4f32(float -0.000000e+00, <vscale x 4 x float> + // LLVM: ret float + return __builtin_reduce_assoc_fadd(x); +} + float test_sve_reduce_in_order_fadd(svfloat32_t x, float start) { // CIR-LABEL: @test_sve_reduce_in_order_fadd // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float + // CIR-NOT: fastmath_flags // CIR: cir.return // LLVM-LABEL: @test_sve_reduce_in_order_fadd // LLVM: call float @llvm.vector.reduce.fadd.nxv4f32(float %{{.*}}, <vscale x 4 x float> diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c index a2a4624de1854..57408af5d80d4 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c @@ -110,9 +110,43 @@ float test_reduce_min_float(v4sf x) { return __builtin_reduce_min(x); } +float test_reduce_assoc_fadd(v4sf x, float start) { + // CIR-LABEL: @test_reduce_assoc_fadd + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.return + // LLVM-LABEL: @test_reduce_assoc_fadd + // LLVM: call reassoc float @llvm.vector.reduce.fadd.v4f32(float %{{.*}}, <4 x float> + // LLVM: ret float + return __builtin_reduce_assoc_fadd(x, start); +} + +float test_reduce_assoc_fadd_default_start(v4sf x) { + // CIR-LABEL: @test_reduce_assoc_fadd_default_start + // CIR: %[[START:.*]] = cir.const #cir.fp<-0.000000e+00> : !cir.float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[START]], {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.return + // LLVM-LABEL: @test_reduce_assoc_fadd_default_start + // LLVM: call reassoc float @llvm.vector.reduce.fadd.v4f32(float -0.000000e+00, <4 x float> + // LLVM: ret float + return __builtin_reduce_assoc_fadd(x); +} + +float test_reduce_assoc_fadd_cast_start(v4sf x, double start) { + // CIR-LABEL: @test_reduce_assoc_fadd_cast_start + // CIR: %[[START:.*]] = cir.cast floating {{.*}} : !cir.double -> !cir.float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" %[[START]], {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float fastmath<reassoc> + // CIR: cir.return + // LLVM-LABEL: @test_reduce_assoc_fadd_cast_start + // LLVM: %[[START:.*]] = fptrunc double %{{.*}} to float + // LLVM: call reassoc float @llvm.vector.reduce.fadd.v4f32(float %[[START]], <4 x float> + // LLVM: ret float + return __builtin_reduce_assoc_fadd(x, start); +} + float test_reduce_in_order_fadd(v4sf x, float start) { // CIR-LABEL: @test_reduce_in_order_fadd // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float + // CIR-NOT: fastmath_flags // CIR: cir.return // LLVM-LABEL: @test_reduce_in_order_fadd // LLVM: call float @llvm.vector.reduce.fadd.v4f32(float %{{.*}}, <4 x float> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
