[Mlir-commits] [mlir] 0064239 - [mlir][SPIR-V] Lower arith.maxnumf/minnumf to spirv.GL.NMax/NMin (#205975)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Jul 8 02:10:39 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-07-08T11:10:26+02:00
New Revision: 006423944b8efdb115d8fd001cffca888605cd7f

URL: https://github.com/llvm/llvm-project/commit/006423944b8efdb115d8fd001cffca888605cd7f
DIFF: https://github.com/llvm/llvm-project/commit/006423944b8efdb115d8fd001cffca888605cd7f.diff

LOG: [mlir][SPIR-V] Lower arith.maxnumf/minnumf to spirv.GL.NMax/NMin (#205975)

The previous lowering targeted spirv.GL.FMax/FMin + NaN guards

spirv.GL.NMax/NMin natively treat NaN as missing, matching
arith.maxnumf/minnumf exactly (no guards required)

Added: 
    

Modified: 
    mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
    mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
    mlir/test/Conversion/ArithToSPIRV/fast-math.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp b/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
index 9a6d330db72fe..614ac2b43b5f2 100644
--- a/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
+++ b/mlir/lib/Conversion/ArithToSPIRV/ArithToSPIRV.cpp
@@ -1403,7 +1403,7 @@ class MinimumMaximumFOpPattern final : public OpConversionPattern<Op> {
 // MinNumFOp, MaxNumFOp
 //===----------------------------------------------------------------------===//
 
-/// Converts arith.maxnumf/minnumf to spirv.GL.FMax/FMin or
+/// Converts arith.maxnumf/minnumf to spirv.GL.NMax/NMin or
 /// spirv.CL.fmax/fmin.
 template <typename Op, typename SPIRVOp>
 class MinNumMaxNumFOpPattern final : public OpConversionPattern<Op> {
@@ -1425,11 +1425,11 @@ class MinNumMaxNumFOpPattern final : public OpConversionPattern<Op> {
     // arith.maxnumf/minnumf:
     //   "If one of the arguments is NaN, then the result is the other
     //   argument."
-    // spirv.GL.FMax/FMin
-    //   "which operand is the result is undefined if one of the operands
-    //   is a NaN."
+    // spirv.GL.NMax/NMin: NaN is treated as missing, matches arith semantics.
     // spirv.CL.fmax/fmin:
     //   "If one argument is a NaN, Fmin returns the other argument."
+    // spirv.GL.FMax/FMin: undefined when either operand is NaN, requires
+    //   select guards to implement arith.maxnumf semantics.
 
     Location loc = op.getLoc();
     Value spirvOp =
@@ -1519,8 +1519,8 @@ void mlir::arith::populateArithToSPIRVPatterns(
 
     MinimumMaximumFOpPattern<arith::MaximumFOp, spirv::GLFMaxOp>,
     MinimumMaximumFOpPattern<arith::MinimumFOp, spirv::GLFMinOp>,
-    MinNumMaxNumFOpPattern<arith::MaxNumFOp, spirv::GLFMaxOp>,
-    MinNumMaxNumFOpPattern<arith::MinNumFOp, spirv::GLFMinOp>,
+    MinNumMaxNumFOpPattern<arith::MaxNumFOp, spirv::GLNMaxOp>,
+    MinNumMaxNumFOpPattern<arith::MinNumFOp, spirv::GLNMinOp>,
     BoolIOpPattern<arith::MaxSIOp, spirv::LogicalAndOp>, // signed i1: 1=-1, so max=0 unless both are 1
     BoolIOpPattern<arith::MaxUIOp, spirv::LogicalOrOp>,  // unsigned max on i1: 1 when either is 1
     BoolIOpPattern<arith::MinSIOp, spirv::LogicalOrOp>,  // signed i1: -1<0, so min=1 when either is 1

diff  --git a/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir b/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
index b6a488f0dad73..5c9966055b540 100644
--- a/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
+++ b/mlir/test/Conversion/ArithToSPIRV/arith-to-spirv.mlir
@@ -1494,15 +1494,9 @@ func.func @float32_minimumf_scalar(%arg0 : f32, %arg1 : f32) -> f32 {
 }
 
 // CHECK-LABEL: @float32_minnumf_scalar
-// CHECK-SAME: %[[LHS:.+]]: f32, %[[RHS:.+]]: f32
 func.func @float32_minnumf_scalar(%arg0 : f32, %arg1 : f32) -> f32 {
-  // CHECK: %[[MIN:.+]] = spirv.GL.FMin %arg0, %arg1 : f32
-  // CHECK: %[[LHS_NAN:.+]] = spirv.IsNan %[[LHS]] : f32
-  // CHECK: %[[RHS_NAN:.+]] = spirv.IsNan %[[RHS]] : f32
-  // CHECK: %[[SELECT1:.+]] = spirv.Select %[[LHS_NAN]], %[[RHS]], %[[MIN]]
-  // CHECK: %[[SELECT2:.+]] = spirv.Select %[[RHS_NAN]], %[[LHS]], %[[SELECT1]]
+  // CHECK: spirv.GL.NMin %arg0, %arg1 : f32
   %0 = arith.minnumf %arg0, %arg1 : f32
-  // CHECK: return %[[SELECT2]]
   return %0: f32
 }
 
@@ -1520,15 +1514,9 @@ func.func @float32_maximumf_scalar(%arg0 : vector<2xf32>, %arg1 : vector<2xf32>)
 }
 
 // CHECK-LABEL: @float32_maxnumf_scalar
-// CHECK-SAME: %[[LHS:.+]]: vector<2xf32>, %[[RHS:.+]]: vector<2xf32>
 func.func @float32_maxnumf_scalar(%arg0 : vector<2xf32>, %arg1 : vector<2xf32>) -> vector<2xf32> {
-  // CHECK: %[[MAX:.+]] = spirv.GL.FMax %arg0, %arg1 : vector<2xf32>
-  // CHECK: %[[LHS_NAN:.+]] = spirv.IsNan %[[LHS]] : vector<2xf32>
-  // CHECK: %[[RHS_NAN:.+]] = spirv.IsNan %[[RHS]] : vector<2xf32>
-  // CHECK: %[[SELECT1:.+]] = spirv.Select %[[LHS_NAN]], %[[RHS]], %[[MAX]]
-  // CHECK: %[[SELECT2:.+]] = spirv.Select %[[RHS_NAN]], %[[LHS]], %[[SELECT1]]
+  // CHECK: spirv.GL.NMax %arg0, %arg1 : vector<2xf32>
   %0 = arith.maxnumf %arg0, %arg1 : vector<2xf32>
-  // CHECK: return %[[SELECT2]]
   return %0: vector<2xf32>
 }
 

diff  --git a/mlir/test/Conversion/ArithToSPIRV/fast-math.mlir b/mlir/test/Conversion/ArithToSPIRV/fast-math.mlir
index 9bbe28fb127a7..e13bef977ddb7 100644
--- a/mlir/test/Conversion/ArithToSPIRV/fast-math.mlir
+++ b/mlir/test/Conversion/ArithToSPIRV/fast-math.mlir
@@ -49,20 +49,16 @@ func.func @maximumf(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>) -> vector<4xf3
 }
 
 // CHECK-LABEL: @minnumf
-// CHECK-SAME: %[[LHS:.+]]: f32, %[[RHS:.+]]: f32
 func.func @minnumf(%arg0 : f32, %arg1 : f32) -> f32 {
-  // CHECK: %[[F:.+]] = spirv.GL.FMin %[[LHS]], %[[RHS]]
+  // CHECK: spirv.GL.NMin %{{.*}}, %{{.*}} : f32
   %0 = arith.minnumf %arg0, %arg1 fastmath<fast> : f32
-  // CHECK: return %[[F]]
   return %0: f32
 }
 
 // CHECK-LABEL: @maxnumf
-// CHECK-SAME: %[[LHS:.+]]: vector<4xf32>, %[[RHS:.+]]: vector<4xf32>
 func.func @maxnumf(%arg0 : vector<4xf32>, %arg1 : vector<4xf32>) -> vector<4xf32> {
-  // CHECK: %[[F:.+]] = spirv.GL.FMax %[[LHS]], %[[RHS]]
+  // CHECK: spirv.GL.NMax %{{.*}}, %{{.*}} : vector<4xf32>
   %0 = arith.maxnumf %arg0, %arg1 fastmath<fast> : vector<4xf32>
-  // CHECK: return %[[F]]
   return %0: vector<4xf32>
 }
 


        


More information about the Mlir-commits mailing list