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

Reply via email to