[llvm-branch-commits] [mlir] [mlir][arith] Add support for min/max to `ArithToAPFloat` (PR #169760)
Matthias Springer via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Nov 26 21:12:56 PST 2025
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 <me at m-sp.org>
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
More information about the llvm-branch-commits
mailing list