[Mlir-commits] [mlir] 709b274 - [mlir][vector] Bring back `maxf`/`minf` reductions

Diego Caballero llvmlistbot at llvm.org
Wed Sep 13 15:50:43 PDT 2023


Author: Daniil Dudkin
Date: 2023-09-13T22:49:07Z
New Revision: 709b27427b4661bdd08fe80b0164acf53c895793

URL: https://github.com/llvm/llvm-project/commit/709b27427b4661bdd08fe80b0164acf53c895793
DIFF: https://github.com/llvm/llvm-project/commit/709b27427b4661bdd08fe80b0164acf53c895793.diff

LOG: [mlir][vector] Bring back `maxf`/`minf` reductions

This patch is part of a larger initiative aimed at fixing floating-point `max` and `min` operations in MLIR: https://discourse.llvm.org/t/rfc-fix-floating-point-max-and-min-operations-in-mlir/72671.

In line with the mentioned RFC, this patch  tackles tasks 2.3 and 2.4.
It adds LLVM conversions for the `maxf`/`minf` reductions to the non-NaN-propagating LLVM intrinsics.

Depends on D158618

Reviewed By: dcaballe

Differential Revision: https://reviews.llvm.org/D158659

Added: 
    

Modified: 
    mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
    mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir
    mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32-reassoc.mlir
    mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32.mlir
    mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64-reassoc.mlir
    mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
index 5a42cccca297506..335e113d12b7e3c 100644
--- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
+++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
@@ -577,6 +577,14 @@ template <>
 struct VectorToScalarMapper<LLVM::vector_reduce_fminimum> {
   using Type = LLVM::MinimumOp;
 };
+template <>
+struct VectorToScalarMapper<LLVM::vector_reduce_fmax> {
+  using Type = LLVM::MaxNumOp;
+};
+template <>
+struct VectorToScalarMapper<LLVM::vector_reduce_fmin> {
+  using Type = LLVM::MinNumOp;
+};
 } // namespace
 
 template <class LLVMRedIntrinOp>
@@ -770,6 +778,12 @@ class VectorReductionOpConversion
       result =
           createFPReductionComparisonOpLowering<LLVM::vector_reduce_fmaximum>(
               rewriter, loc, llvmType, operand, acc);
+    } else if (kind == vector::CombiningKind::MINF) {
+      result = createFPReductionComparisonOpLowering<LLVM::vector_reduce_fmin>(
+          rewriter, loc, llvmType, operand, acc);
+    } else if (kind == vector::CombiningKind::MAXF) {
+      result = createFPReductionComparisonOpLowering<LLVM::vector_reduce_fmax>(
+          rewriter, loc, llvmType, operand, acc);
     } else
       return failure();
 
@@ -880,15 +894,11 @@ class MaskedReductionOpConversion
           rewriter, loc, llvmType, operand, acc, maskOp.getMask());
       break;
     case vector::CombiningKind::MINF:
-      // FIXME: MLIR's 'minf' and LLVM's 'vector_reduce_fmin' do not handle
-      // NaNs/-0.0/+0.0 in the same way.
       result = lowerReductionWithStartValue<LLVM::VPReduceFMinOp,
                                             ReductionNeutralFPMax>(
           rewriter, loc, llvmType, operand, acc, maskOp.getMask());
       break;
     case vector::CombiningKind::MAXF:
-      // FIXME: MLIR's 'minf' and LLVM's 'vector_reduce_fmin' do not handle
-      // NaNs/-0.0/+0.0 in the same way.
       result = lowerReductionWithStartValue<LLVM::VPReduceFMaxOp,
                                             ReductionNeutralFPMin>(
           rewriter, loc, llvmType, operand, acc, maskOp.getMask());

diff  --git a/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir
index 354c79c9e198a1a..4c06324087a0133 100644
--- a/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir
+++ b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir
@@ -1341,6 +1341,30 @@ func.func @reduce_fminimum_f32(%arg0: vector<16xf32>, %arg1: f32) -> f32 {
 
 // -----
 
+func.func @reduce_fmax_f32(%arg0: vector<16xf32>, %arg1: f32) -> f32 {
+  %0 = vector.reduction <maxf>, %arg0, %arg1 : vector<16xf32> into f32
+  return %0 : f32
+}
+// CHECK-LABEL: @reduce_fmax_f32(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>, %[[B:.*]]: f32)
+//      CHECK: %[[V:.*]] = llvm.intr.vector.reduce.fmax(%[[A]]) : (vector<16xf32>) -> f32
+//      CHECK: %[[R:.*]] = llvm.intr.maxnum(%[[V]], %[[B]]) : (f32, f32) -> f32
+//      CHECK: return %[[R]] : f32
+
+// -----
+
+func.func @reduce_fmin_f32(%arg0: vector<16xf32>, %arg1: f32) -> f32 {
+  %0 = vector.reduction <minf>, %arg0, %arg1 : vector<16xf32> into f32
+  return %0 : f32
+}
+// CHECK-LABEL: @reduce_fmin_f32(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>, %[[B:.*]]: f32)
+//      CHECK: %[[V:.*]] = llvm.intr.vector.reduce.fmin(%[[A]]) : (vector<16xf32>) -> f32
+//      CHECK: %[[R:.*]] = llvm.intr.minnum(%[[V]], %[[B]]) : (f32, f32) -> f32
+//      CHECK: return %[[R]] : f32
+
+// -----
+
 func.func @reduce_minui_i32(%arg0: vector<16xi32>) -> i32 {
   %0 = vector.reduction <minui>, %arg0 : vector<16xi32> into i32
   return %0 : i32

diff  --git a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32-reassoc.mlir b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32-reassoc.mlir
index 1ebf0394d4b9f8f..ce160880a009358 100644
--- a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32-reassoc.mlir
+++ b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32-reassoc.mlir
@@ -33,6 +33,12 @@ func.func @entry() {
   %3 = vector.reduction <maximumf>, %v2 : vector<64xf32> into f32
   vector.print %3 : f32
   // CHECK: 3
+  %4 = vector.reduction <minf>, %v2 : vector<64xf32> into f32
+  vector.print %4 : f32
+  // CHECK: 1
+  %5 = vector.reduction <maxf>, %v2 : vector<64xf32> into f32
+  vector.print %5 : f32
+  // CHECK: 3
 
   return
 }

diff  --git a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32.mlir b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32.mlir
index fdb83ba055ac975..56d987ba2e22516 100644
--- a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32.mlir
+++ b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f32.mlir
@@ -45,6 +45,12 @@ func.func @entry() {
   %3 = vector.reduction <maximumf>, %v9 : vector<10xf32> into f32
   vector.print %3 : f32
   // CHECK: 5
+  %4 = vector.reduction <minf>, %v9 : vector<10xf32> into f32
+  vector.print %4 : f32
+  // CHECK: -16
+  %5 = vector.reduction <maxf>, %v9 : vector<10xf32> into f32
+  vector.print %5 : f32
+  // CHECK: 5
 
   return
 }

diff  --git a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64-reassoc.mlir b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64-reassoc.mlir
index 8c250de5786fbec..711144b674851a9 100644
--- a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64-reassoc.mlir
+++ b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64-reassoc.mlir
@@ -33,6 +33,12 @@ func.func @entry() {
   %3 = vector.reduction <maximumf>, %v2 : vector<64xf64> into f64
   vector.print %3 : f64
   // CHECK: 3
+  %4 = vector.reduction <minf>, %v2 : vector<64xf64> into f64
+  vector.print %4 : f64
+  // CHECK: 1
+  %5 = vector.reduction <maxf>, %v2 : vector<64xf64> into f64
+  vector.print %5 : f64
+  // CHECK: 3
 
   return
 }

diff  --git a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64.mlir b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64.mlir
index 5d3c2a5f02db7d1..41d1bbcb731fee1 100644
--- a/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64.mlir
+++ b/mlir/test/Integration/Dialect/Vector/CPU/test-reductions-f64.mlir
@@ -45,6 +45,12 @@ func.func @entry() {
   %3 = vector.reduction <maximumf>, %v9 : vector<10xf64> into f64
   vector.print %3 : f64
   // CHECK: 5
+  %4 = vector.reduction <minf>, %v9 : vector<10xf64> into f64
+  vector.print %4 : f64
+  // CHECK: -16
+  %5 = vector.reduction <maxf>, %v9 : vector<10xf64> into f64
+  vector.print %5 : f64
+  // CHECK: 5
 
   return
 }


        


More information about the Mlir-commits mailing list