https://github.com/matthias-springer created 
https://github.com/llvm/llvm-project/pull/169760

Add support for `arith.minnumf`, `arith.maxnumf`, `arith.minimumf`, 
`arith.maximumf`.


>From 9fe4582461d8a6757db6d485eb798fbb9fe6ef33 Mon Sep 17 00:00:00 2001
From: Matthias Springer <[email protected]>
Date: Thu, 27 Nov 2025 05:11:18 +0000
Subject: [PATCH] [mlir][arith] Add support for min/max to `ArithToAPFloat`

---
 .../ArithToAPFloat/ArithToAPFloat.cpp         |  8 ++++
 mlir/lib/ExecutionEngine/APFloatWrappers.cpp  | 20 ++++++++++
 .../ArithToApfloat/arith-to-apfloat.mlir      | 40 +++++++++++++++++++
 .../Arith/CPU/test-apfloat-emulation.mlir     |  4 ++
 4 files changed, 72 insertions(+)

diff --git a/mlir/lib/Conversion/ArithToAPFloat/ArithToAPFloat.cpp 
b/mlir/lib/Conversion/ArithToAPFloat/ArithToAPFloat.cpp
index 230abb51e8158..25cb5af889c4d 100644
--- a/mlir/lib/Conversion/ArithToAPFloat/ArithToAPFloat.cpp
+++ b/mlir/lib/Conversion/ArithToAPFloat/ArithToAPFloat.cpp
@@ -513,6 +513,14 @@ void ArithToAPFloatConversionPass::runOnOperation() {
       context, "divide", getOperation());
   patterns.add<BinaryArithOpToAPFloatConversion<arith::RemFOp>>(
       context, "remainder", getOperation());
+  patterns.add<BinaryArithOpToAPFloatConversion<arith::MinNumFOp>>(
+      context, "minnum", getOperation());
+  patterns.add<BinaryArithOpToAPFloatConversion<arith::MaxNumFOp>>(
+      context, "maxnum", getOperation());
+  patterns.add<BinaryArithOpToAPFloatConversion<arith::MinimumFOp>>(
+      context, "minimum", getOperation());
+  patterns.add<BinaryArithOpToAPFloatConversion<arith::MaximumFOp>>(
+      context, "maximum", getOperation());
   patterns
       .add<FpToFpConversion<arith::ExtFOp>, FpToFpConversion<arith::TruncFOp>>(
           context, getOperation());
diff --git a/mlir/lib/ExecutionEngine/APFloatWrappers.cpp 
b/mlir/lib/ExecutionEngine/APFloatWrappers.cpp
index f2d5254be6b57..f3e38eb8ffa2d 100644
--- a/mlir/lib/ExecutionEngine/APFloatWrappers.cpp
+++ b/mlir/lib/ExecutionEngine/APFloatWrappers.cpp
@@ -151,4 +151,24 @@ MLIR_APFLOAT_WRAPPERS_EXPORT uint64_t 
_mlir_apfloat_neg(int32_t semantics, uint6
   x.changeSign();
   return x.bitcastToAPInt().getZExtValue();
 }
+
+/// Min/max operations.
+#define APFLOAT_MIN_MAX_OP(OP)                                                 
\
+  MLIR_APFLOAT_WRAPPERS_EXPORT uint64_t _mlir_apfloat_##OP(                    
\
+      int32_t semantics, uint64_t a, uint64_t b) {                             
\
+    const llvm::fltSemantics &sem = llvm::APFloatBase::EnumToSemantics(        
\
+        static_cast<llvm::APFloatBase::Semantics>(semantics));                 
\
+    unsigned bitWidth = llvm::APFloatBase::semanticsSizeInBits(sem);           
\
+    llvm::APFloat lhs(sem, llvm::APInt(bitWidth, a));                          
\
+    llvm::APFloat rhs(sem, llvm::APInt(bitWidth, b));                          
\
+    llvm::APFloat result = llvm::OP(lhs, rhs);                                 
\
+    return result.bitcastToAPInt().getZExtValue();                             
\
+  }
+
+APFLOAT_MIN_MAX_OP(minimum)
+APFLOAT_MIN_MAX_OP(maximum)
+APFLOAT_MIN_MAX_OP(minnum)
+APFLOAT_MIN_MAX_OP(maxnum)
+
+#undef APFLOAT_MIN_MAX_OP
 }
diff --git a/mlir/test/Conversion/ArithToApfloat/arith-to-apfloat.mlir 
b/mlir/test/Conversion/ArithToApfloat/arith-to-apfloat.mlir
index 775cb5ea60f22..950d2cecefa95 100644
--- a/mlir/test/Conversion/ArithToApfloat/arith-to-apfloat.mlir
+++ b/mlir/test/Conversion/ArithToApfloat/arith-to-apfloat.mlir
@@ -223,3 +223,43 @@ func.func @negf(%arg0: f32) {
   %0 = arith.negf %arg0 : f32
   return
 }
+
+// -----
+
+// CHECK: func.func private @_mlir_apfloat_minimum(i32, i64, i64) -> i64
+// CHECK: %[[sem:.*]] = arith.constant 2 : i32
+// CHECK: %[[res:.*]] = call @_mlir_apfloat_minimum(%[[sem]], %{{.*}}, 
%{{.*}}) : (i32, i64, i64) -> i64
+func.func @minimumf(%arg0: f32, %arg1: f32) {
+  %0 = arith.minimumf %arg0, %arg1 : f32
+  return
+}
+
+// -----
+
+// CHECK: func.func private @_mlir_apfloat_maximum(i32, i64, i64) -> i64
+// CHECK: %[[sem:.*]] = arith.constant 2 : i32
+// CHECK: %[[res:.*]] = call @_mlir_apfloat_maximum(%[[sem]], %{{.*}}, 
%{{.*}}) : (i32, i64, i64) -> i64
+func.func @maximumf(%arg0: f32, %arg1: f32) {
+  %0 = arith.maximumf %arg0, %arg1 : f32
+  return
+}
+
+// -----
+
+// CHECK: func.func private @_mlir_apfloat_minnum(i32, i64, i64) -> i64
+// CHECK: %[[sem:.*]] = arith.constant 2 : i32
+// CHECK: %[[res:.*]] = call @_mlir_apfloat_minnum(%[[sem]], %{{.*}}, %{{.*}}) 
: (i32, i64, i64) -> i64
+func.func @minnumf(%arg0: f32, %arg1: f32) {
+  %0 = arith.minnumf %arg0, %arg1 : f32
+  return
+}
+
+// -----
+
+// CHECK: func.func private @_mlir_apfloat_maxnum(i32, i64, i64) -> i64
+// CHECK: %[[sem:.*]] = arith.constant 2 : i32
+// CHECK: %[[res:.*]] = call @_mlir_apfloat_maxnum(%[[sem]], %{{.*}}, %{{.*}}) 
: (i32, i64, i64) -> i64
+func.func @maxnumf(%arg0: f32, %arg1: f32) {
+  %0 = arith.maxnumf %arg0, %arg1 : f32
+  return
+}
diff --git 
a/mlir/test/Integration/Dialect/Arith/CPU/test-apfloat-emulation.mlir 
b/mlir/test/Integration/Dialect/Arith/CPU/test-apfloat-emulation.mlir
index 555cc9a531966..7f72dd5931488 100644
--- a/mlir/test/Integration/Dialect/Arith/CPU/test-apfloat-emulation.mlir
+++ b/mlir/test/Integration/Dialect/Arith/CPU/test-apfloat-emulation.mlir
@@ -47,6 +47,10 @@ func.func @entry() {
   %negated = arith.negf %cvt : f8E4M3FN
   vector.print %negated : f8E4M3FN
 
+  // CHECK-NEXT: -2.25
+  %min = arith.minimumf %cvt, %negated : f8E4M3FN
+  vector.print %min : f8E4M3FN
+
   // CHECK-NEXT: 1
   %cmp1 = arith.cmpf "olt", %cvt, %c1 : f8E4M3FN
   vector.print %cmp1 : i1

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to