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/2] [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 e2fe3adefd4af..b0e3f0ae00ebe 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 0000000000000..271aaecf5e0a8 --- /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 c15375621f08a..372eb97c323f3 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/2] [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 b0e3f0ae00ebe..ae4ce14ea47e0 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 0000000000000..6f3320ed83d53 --- /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 271aaecf5e0a8..095e841ee26a2 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 372eb97c323f3..a89006deb4c8d 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
