https://github.com/xakep8 updated https://github.com/llvm/llvm-project/pull/224204
>From 422867a172ef2fbf49ef601ae0c2435720eb303f Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Thu, 17 Sep 2026 12:17:03 +0530 Subject: [PATCH 1/4] [CIR] Lowering for __builtin_reduce_add/mul Added lowering for __builtin_reduce_add and __builtin_reduce_mul by mimicking the same shape as __builtin_reduce_xor which mirrors classic Codegen shape Added test for the same --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 10 +++- .../builtin-reduce-arithmetic.c | 49 +++++++++++++++++++ .../CodeGenBuiltins/builtin-undef-rvalue.cpp | 8 +-- 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index e2fe3adefd4afb..b0e3f0ae00ebe4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2141,9 +2141,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, case Builtin::BI__builtin_elementwise_minimumnum: case Builtin::BI__builtin_reduce_max: case Builtin::BI__builtin_reduce_min: + return errorBuiltinNYI(*this, e, builtinID); case Builtin::BI__builtin_reduce_add: + return emitBuiltinWithOneOverloadedType<1>( + e, "vector.reduce.add", + cast<cir::VectorType>(convertType(e->getArg(0)->getType())) + .getElementType()); case Builtin::BI__builtin_reduce_mul: - return errorBuiltinNYI(*this, e, builtinID); + return emitBuiltinWithOneOverloadedType<1>( + e, "vector.reduce.mul", + cast<cir::VectorType>(convertType(e->getArg(0)->getType())) + .getElementType()); case Builtin::BI__builtin_reduce_xor: return emitBuiltinWithOneOverloadedType<1>( e, "vector.reduce.xor", diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c new file mode 100644 index 00000000000000..271aaecf5e0a8f --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s + +typedef int v4si __attribute__((vector_size(16))); +typedef unsigned int v4su __attribute__((vector_size(16))); + +int test_reduce_add(v4si x) { + // CIR-LABEL: @test_reduce_add + // CIR: cir.call_llvm_intrinsic "vector.reduce.add" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_add + // LLVM: call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_add(x); +} + +unsigned test_reduce_add_unsigned(v4su x) { + // CIR-LABEL: @test_reduce_add_unsigned + // CIR: cir.call_llvm_intrinsic "vector.reduce.add" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_add_unsigned + // LLVM: call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_add(x); +} + +int test_reduce_mul(v4si x) { + // CIR-LABEL: @test_reduce_mul + // CIR: cir.call_llvm_intrinsic "vector.reduce.mul" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_mul + // LLVM: call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_mul(x); +} + +unsigned test_reduce_mul_unsigned(v4su x) { + // CIR-LABEL: @test_reduce_mul_unsigned + // CIR: cir.call_llvm_intrinsic "vector.reduce.mul" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_mul_unsigned + // LLVM: call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_mul(x); +} diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp b/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp index c15375621f08a2..372eb97c323f37 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp +++ b/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp @@ -3,11 +3,11 @@ typedef int v4si __attribute__((vector_size(16))); -int test_builtin_reduce_add_undef_rvalue(v4si x) { - // expected-error@+1 {{unimplemented builtin call: __builtin_reduce_add}} - return __builtin_reduce_add(x); +int test_builtin_reduce_max_undef_rvalue(v4si x) { + // expected-error@+1 {{unimplemented builtin call: __builtin_reduce_max}} + return __builtin_reduce_max(x); } -// CIR-LABEL: @_Z36test_builtin_reduce_add_undef_rvalueDv4_i +// CIR-LABEL: @_Z36test_builtin_reduce_max_undef_rvalueDv4_i // CIR: cir.const #cir.undef : !s32i // CIR: cir.return >From b0dd4a8e6361f2e4084704b3b886a71a50aa60c2 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Thu, 17 Sep 2026 15:13:03 +0530 Subject: [PATCH 2/4] [CIR] Lowering for __builtin_reduce_max/min Added lowering for __builtin_reduce_max and __builtin_reduce_min matching classic CodeGen by selecting signed, unsigned and floating-point min/max reduction intrinsics from the vector element type, including sizeless vector types. Added test for same. --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 31 +++++++- .../builtin-reduce-arithmetic-sve.c | 73 +++++++++++++++++++ .../builtin-reduce-arithmetic.c | 61 ++++++++++++++++ .../CodeGenBuiltins/builtin-undef-rvalue.cpp | 12 +-- 4 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index b0e3f0ae00ebe4..ae4ce14ea47e02 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2139,9 +2139,36 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, case Builtin::BI__builtin_elementwise_maximumnum: case Builtin::BI__builtin_elementwise_minimumnum: - case Builtin::BI__builtin_reduce_max: - case Builtin::BI__builtin_reduce_min: return errorBuiltinNYI(*this, e, builtinID); + case Builtin::BI__builtin_reduce_max: + case Builtin::BI__builtin_reduce_min: { + auto getIntrinsicName = [this, builtinIDIfNoAsmLabel](QualType type) { + if (const auto *vecTy = type->getAs<VectorType>()) + type = vecTy->getElementType(); + else if (type->isSizelessVectorType()) + type = type->getSizelessVectorEltType(getContext()); + + if (builtinIDIfNoAsmLabel == Builtin::BI__builtin_reduce_max) { + if (type->isSignedIntegerType()) + return "vector.reduce.smax"; + if (type->isUnsignedIntegerType()) + return "vector.reduce.umax"; + assert(type->isFloatingType() && "must have a float here"); + return "vector.reduce.fmax"; + } + + if (type->isSignedIntegerType()) + return "vector.reduce.smin"; + if (type->isUnsignedIntegerType()) + return "vector.reduce.umin"; + assert(type->isFloatingType() && "must have a float here"); + return "vector.reduce.fmin"; + }; + return emitBuiltinWithOneOverloadedType<1>( + e, getIntrinsicName(e->getArg(0)->getType()), + cast<cir::VectorType>(convertType(e->getArg(0)->getType())) + .getElementType()); + } case Builtin::BI__builtin_reduce_add: return emitBuiltinWithOneOverloadedType<1>( e, "vector.reduce.add", diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c new file mode 100644 index 00000000000000..6f3320ed83d531 --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -target-feature +sve \ +// RUN: -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -target-feature +sve \ +// RUN: -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -target-feature +sve \ +// RUN: -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s +// +// REQUIRES: aarch64-registered-target + +#include <arm_sve.h> + +int test_sve_reduce_max(svint32_t x) { + // CIR-LABEL: @test_sve_reduce_max + // CIR: cir.call_llvm_intrinsic "vector.reduce.smax" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_max + // LLVM: call i32 @llvm.vector.reduce.smax.nxv4i32(<vscale x 4 x i32> + // LLVM: ret i32 + return __builtin_reduce_max(x); +} + +unsigned test_sve_reduce_max_unsigned(svuint32_t x) { + // CIR-LABEL: @test_sve_reduce_max_unsigned + // CIR: cir.call_llvm_intrinsic "vector.reduce.umax" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_max_unsigned + // LLVM: call i32 @llvm.vector.reduce.umax.nxv4i32(<vscale x 4 x i32> + // LLVM: ret i32 + return __builtin_reduce_max(x); +} + +float test_sve_reduce_max_float(svfloat32_t x) { + // CIR-LABEL: @test_sve_reduce_max_float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_max_float + // LLVM: call float @llvm.vector.reduce.fmax.nxv4f32(<vscale x 4 x float> + // LLVM: ret float + return __builtin_reduce_max(x); +} + +int test_sve_reduce_min(svint32_t x) { + // CIR-LABEL: @test_sve_reduce_min + // CIR: cir.call_llvm_intrinsic "vector.reduce.smin" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_min + // LLVM: call i32 @llvm.vector.reduce.smin.nxv4i32(<vscale x 4 x i32> + // LLVM: ret i32 + return __builtin_reduce_min(x); +} + +unsigned test_sve_reduce_min_unsigned(svuint32_t x) { + // CIR-LABEL: @test_sve_reduce_min_unsigned + // CIR: cir.call_llvm_intrinsic "vector.reduce.umin" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_min_unsigned + // LLVM: call i32 @llvm.vector.reduce.umin.nxv4i32(<vscale x 4 x i32> + // LLVM: ret i32 + return __builtin_reduce_min(x); +} + +float test_sve_reduce_min_float(svfloat32_t x) { + // CIR-LABEL: @test_sve_reduce_min_float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_min_float + // LLVM: call float @llvm.vector.reduce.fmin.nxv4f32(<vscale x 4 x float> + // LLVM: ret float + return __builtin_reduce_min(x); +} diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c index 271aaecf5e0a8f..095e841ee26a2b 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c @@ -7,6 +7,7 @@ typedef int v4si __attribute__((vector_size(16))); typedef unsigned int v4su __attribute__((vector_size(16))); +typedef float v4sf __attribute__((vector_size(16))); int test_reduce_add(v4si x) { // CIR-LABEL: @test_reduce_add @@ -47,3 +48,63 @@ unsigned test_reduce_mul_unsigned(v4su x) { // LLVM: ret i32 return __builtin_reduce_mul(x); } + +int test_reduce_max(v4si x) { + // CIR-LABEL: @test_reduce_max + // CIR: cir.call_llvm_intrinsic "vector.reduce.smax" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_max + // LLVM: call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_max(x); +} + +unsigned test_reduce_max_unsigned(v4su x) { + // CIR-LABEL: @test_reduce_max_unsigned + // CIR: cir.call_llvm_intrinsic "vector.reduce.umax" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_max_unsigned + // LLVM: call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_max(x); +} + +float test_reduce_max_float(v4sf x) { + // CIR-LABEL: @test_reduce_max_float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fmax" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_max_float + // LLVM: call float @llvm.vector.reduce.fmax.v4f32(<4 x float> + // LLVM: ret float + return __builtin_reduce_max(x); +} + +int test_reduce_min(v4si x) { + // CIR-LABEL: @test_reduce_min + // CIR: cir.call_llvm_intrinsic "vector.reduce.smin" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_min + // LLVM: call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_min(x); +} + +unsigned test_reduce_min_unsigned(v4su x) { + // CIR-LABEL: @test_reduce_min_unsigned + // CIR: cir.call_llvm_intrinsic "vector.reduce.umin" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_min_unsigned + // LLVM: call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> + // LLVM: ret i32 + return __builtin_reduce_min(x); +} + +float test_reduce_min_float(v4sf x) { + // CIR-LABEL: @test_reduce_min_float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fmin" + // CIR: cir.return + // LLVM-LABEL: @test_reduce_min_float + // LLVM: call float @llvm.vector.reduce.fmin.v4f32(<4 x float> + // LLVM: ret float + return __builtin_reduce_min(x); +} diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp b/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp index 372eb97c323f37..a89006deb4c8dd 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp +++ b/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -verify %s -o - > %t.cir // RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s -typedef int v4si __attribute__((vector_size(16))); +typedef float v4sf __attribute__((vector_size(16))); -int test_builtin_reduce_max_undef_rvalue(v4si x) { - // expected-error@+1 {{unimplemented builtin call: __builtin_reduce_max}} - return __builtin_reduce_max(x); +float test_builtin_reduce_maximum_undef_rvalue(v4sf x) { + // expected-error@+1 {{unimplemented builtin call: __builtin_reduce_maximum}} + return __builtin_reduce_maximum(x); } -// CIR-LABEL: @_Z36test_builtin_reduce_max_undef_rvalueDv4_i -// CIR: cir.const #cir.undef : !s32i +// CIR-LABEL: test_builtin_reduce_maximum_undef_rvalue +// CIR: cir.const #cir.undef : !cir.float // CIR: cir.return >From c30314b23a8a70fbefdd3592fb405d7820ed6d02 Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Thu, 17 Sep 2026 22:26:22 +0530 Subject: [PATCH 3/4] [CIR] Lowering __builtin_reduce_in_order_fadd Added lowering for __builtin_reduce_in_order_fadd matching classic codegen behaviour to llvm.vector.reduce.fadd. Added tests for the same. --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 29 +++++++++++- .../builtin-reduce-arithmetic-sve.c | 32 +++++++++++++ .../builtin-reduce-arithmetic.c | 45 +++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index ae4ce14ea47e02..ae3da50665dd87 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -16,6 +16,7 @@ #include "CIRGenModule.h" #include "CIRGenValue.h" #include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Value.h" #include "mlir/Support/LLVM.h" #include "clang/AST/DeclBase.h" @@ -24,6 +25,7 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/DiagnosticFrontend.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/CIR/Dialect/IR/CIROpsEnums.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/MissingFeatures.h" #include "clang/CodeGenUtils/CodeGenUtils.h" @@ -2195,7 +2197,32 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, cast<cir::VectorType>(convertType(e->getArg(0)->getType())) .getElementType()); case Builtin::BI__builtin_reduce_assoc_fadd: - case Builtin::BI__builtin_reduce_in_order_fadd: + return errorBuiltinNYI(*this, e, builtinID); + case Builtin::BI__builtin_reduce_in_order_fadd: { + mlir::Value vector = emitScalarExpr(e->getArg(0)); + auto vectorTy = cast<cir::VectorType>(vector.getType()); + mlir::Type scalarTy = vectorTy.getElementType(); + mlir::Value startValue; + mlir::Location loc = getLoc(e->getExprLoc()); + 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); + return RValue::get(result); + } case Builtin::BI__builtin_reduce_maximum: case Builtin::BI__builtin_reduce_minimum: case Builtin::BI__builtin_matrix_transpose: diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c index 6f3320ed83d531..11cbf40909a74c 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c @@ -71,3 +71,35 @@ float test_sve_reduce_min_float(svfloat32_t x) { // LLVM: ret float return __builtin_reduce_min(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: cir.return + // LLVM-LABEL: @test_sve_reduce_in_order_fadd + // LLVM: call float @llvm.vector.reduce.fadd.nxv4f32(float %{{.*}}, <vscale x 4 x float> + // LLVM: ret float + return __builtin_reduce_in_order_fadd(x, start); +} + +float test_sve_reduce_in_order_fadd_cast_start(svfloat32_t x, double start) { + // CIR-LABEL: @test_sve_reduce_in_order_fadd_cast_start + // CIR: cir.cast floating {{.*}} : !cir.double -> !cir.float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<[4] x !cir.float>) -> !cir.float + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_in_order_fadd_cast_start + // LLVM: fptrunc double %{{.*}} to float + // LLVM: call float @llvm.vector.reduce.fadd.nxv4f32(float %{{.*}}, <vscale x 4 x float> + // LLVM: ret float + return __builtin_reduce_in_order_fadd(x, start); +} + +double test_sve_reduce_in_order_fadd_double(svfloat64_t x, double start) { + // CIR-LABEL: @test_sve_reduce_in_order_fadd_double + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.double, !cir.vector<[2] x !cir.double>) -> !cir.double + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_in_order_fadd_double + // LLVM: call double @llvm.vector.reduce.fadd.nxv2f64(double %{{.*}}, <vscale x 2 x double> + // LLVM: ret double + return __builtin_reduce_in_order_fadd(x, start); +} diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c index 095e841ee26a2b..a2a4624de18549 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic.c @@ -8,6 +8,7 @@ typedef int v4si __attribute__((vector_size(16))); typedef unsigned int v4su __attribute__((vector_size(16))); typedef float v4sf __attribute__((vector_size(16))); +typedef double v2df __attribute__((vector_size(16))); int test_reduce_add(v4si x) { // CIR-LABEL: @test_reduce_add @@ -108,3 +109,47 @@ float test_reduce_min_float(v4sf x) { // LLVM: ret float return __builtin_reduce_min(x); } + +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: cir.return + // LLVM-LABEL: @test_reduce_in_order_fadd + // LLVM: call float @llvm.vector.reduce.fadd.v4f32(float %{{.*}}, <4 x float> + // LLVM: ret float + return __builtin_reduce_in_order_fadd(x, start); +} + +float test_reduce_in_order_fadd_cast_start(v4sf x, double start) { + // CIR-LABEL: @test_reduce_in_order_fadd_cast_start + // CIR: cir.cast floating {{.*}} : !cir.double -> !cir.float + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.float, !cir.vector<4 x !cir.float>) -> !cir.float + // CIR: cir.return + // LLVM-LABEL: @test_reduce_in_order_fadd_cast_start + // LLVM: fptrunc double %{{.*}} to float + // LLVM: call float @llvm.vector.reduce.fadd.v4f32(float %{{.*}}, <4 x float> + // LLVM: ret float + return __builtin_reduce_in_order_fadd(x, start); +} + +double test_reduce_in_order_fadd_double(v2df x, double start) { + // CIR-LABEL: @test_reduce_in_order_fadd_double + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.double, !cir.vector<2 x !cir.double>) -> !cir.double + // CIR: cir.return + // LLVM-LABEL: @test_reduce_in_order_fadd_double + // LLVM: call double @llvm.vector.reduce.fadd.v2f64(double %{{.*}}, <2 x double> + // LLVM: ret double + return __builtin_reduce_in_order_fadd(x, start); +} + +double test_reduce_in_order_fadd_ext_start(v2df x, float start) { + // CIR-LABEL: @test_reduce_in_order_fadd_ext_start + // CIR: cir.cast floating {{.*}} : !cir.float -> !cir.double + // CIR: cir.call_llvm_intrinsic "vector.reduce.fadd" {{.*}} : (!cir.double, !cir.vector<2 x !cir.double>) -> !cir.double + // CIR: cir.return + // LLVM-LABEL: @test_reduce_in_order_fadd_ext_start + // LLVM: fpext float %{{.*}} to double + // LLVM: call double @llvm.vector.reduce.fadd.v2f64(double %{{.*}}, <2 x double> + // LLVM: ret double + return __builtin_reduce_in_order_fadd(x, start); +} >From cd31a04b155120ad8e7d0e4358d44baf821240bc Mon Sep 17 00:00:00 2001 From: Kunal Dubey <[email protected]> Date: Fri, 18 Sep 2026 10:33:58 +0530 Subject: [PATCH 4/4] [CIR] Tests for scalable arithmetic vector reductions Added SVE coverage for arithmetic vector reduction builtins lowered through CIR. Also removed the default-start path from the in_order_fadd lowering since Sema requires exactly two arguments for that builtin. --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 22 ++++++------------- .../builtin-reduce-arithmetic-sve.c | 20 +++++++++++++++++ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index ae3da50665dd87..65e76a2f99846e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2199,25 +2199,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, 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"); mlir::Value vector = emitScalarExpr(e->getArg(0)); auto vectorTy = cast<cir::VectorType>(vector.getType()); mlir::Type scalarTy = vectorTy.getElementType(); - mlir::Value startValue; mlir::Location loc = getLoc(e->getExprLoc()); - 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))); - } + mlir::Value startValue = emitScalarExpr(e->getArg(1)); + if (startValue.getType() != scalarTy) + startValue = + builder.createCast(getLoc(e->getArg(1)->getExprLoc()), + cir::CastKind::floating, startValue, scalarTy); SmallVector<mlir::Value, 2> args = {startValue, vector}; mlir::Value result = builder.emitIntrinsicCallOp(loc, "vector.reduce.fadd", scalarTy, args); diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c index 11cbf40909a74c..fbd9752b255c32 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c +++ b/clang/test/CIR/CodeGenBuiltins/builtin-reduce-arithmetic-sve.c @@ -12,6 +12,26 @@ #include <arm_sve.h> +int test_sve_reduce_add(svint32_t x) { + // CIR-LABEL: @test_sve_reduce_add + // CIR: cir.call_llvm_intrinsic "vector.reduce.add" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_add + // LLVM: call i32 @llvm.vector.reduce.add.nxv4i32(<vscale x 4 x i32> + // LLVM: ret i32 + return __builtin_reduce_add(x); +} + +int test_sve_reduce_mul(svint32_t x) { + // CIR-LABEL: @test_sve_reduce_mul + // CIR: cir.call_llvm_intrinsic "vector.reduce.mul" + // CIR: cir.return + // LLVM-LABEL: @test_sve_reduce_mul + // LLVM: call i32 @llvm.vector.reduce.mul.nxv4i32(<vscale x 4 x i32> + // LLVM: ret i32 + return __builtin_reduce_mul(x); +} + int test_sve_reduce_max(svint32_t x) { // CIR-LABEL: @test_sve_reduce_max // CIR: cir.call_llvm_intrinsic "vector.reduce.smax" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
