[Mlir-commits] [mlir] 7a89444 - [mlir][spirv] Add ops and patterns for lowering standard max/min ops

Lei Zhang llvmlistbot at llvm.org
Tue Oct 5 11:27:50 PDT 2021


Author: Lei Zhang
Date: 2021-10-05T14:27:32-04:00
New Revision: 7a89444cd99ceea8ee8d11f6cf4834680bbf26a0

URL: https://github.com/llvm/llvm-project/commit/7a89444cd99ceea8ee8d11f6cf4834680bbf26a0
DIFF: https://github.com/llvm/llvm-project/commit/7a89444cd99ceea8ee8d11f6cf4834680bbf26a0.diff

LOG: [mlir][spirv] Add ops and patterns for lowering standard max/min ops

Reviewed By: ThomasRaoux

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

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
    mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp
    mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
    mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
    mlir/test/Target/SPIRV/glsl-ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
index 4653267c74bff..55b3a67bc336c 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
@@ -261,10 +261,10 @@ def SPV_GLSLTanOp : SPV_GLSLUnaryArithmeticOp<"Tan", 15, SPV_Float16or32> {
   let description = [{
     The standard trigonometric tangent of x radians.
 
-    The operand x must be a scalar or vector whose component type is 16-bit or 
+    The operand x must be a scalar or vector whose component type is 16-bit or
     32-bit floating-point.
 
-    Result Type and the type of x must be the same type. Results are computed 
+    Result Type and the type of x must be the same type. Results are computed
     per component.
 
     <!-- End of AutoGen section -->
@@ -576,6 +576,36 @@ def SPV_GLSLFMaxOp : SPV_GLSLBinaryArithmeticOp<"FMax", 40, SPV_Float> {
 
 // -----
 
+def SPV_GLSLUMaxOp : SPV_GLSLBinaryArithmeticOp<"UMax", 41, SPV_Integer> {
+  let summary = "Return maximum of two unsigned integer operands";
+
+  let description = [{
+    Result is y if x < y; otherwise result is x, where x and y are interpreted
+    as unsigned integers.
+
+    Result Type and the type of x and y must both be integer scalar or integer
+    vector types. Result Type and operand types must have the same number of
+    components with the same component width. Results are computed per
+    component.
+
+    <!-- End of AutoGen section -->
+    ```
+    integer-scalar-vector-type ::= integer-type |
+                                   `vector<` integer-literal `x` integer-type `>`
+    smax-op ::= ssa-id `=` `spv.GLSL.UMax` ssa-use `:`
+                integer-scalar-vector-type
+    ```
+    #### Example:
+
+    ```mlir
+    %2 = spv.GLSL.UMax %0, %1 : i32
+    %3 = spv.GLSL.UMax %0, %1 : vector<3xi16>
+    ```
+  }];
+}
+
+// -----
+
 def SPV_GLSLSMaxOp : SPV_GLSLBinaryArithmeticOp<"SMax", 42, SPV_Integer> {
   let summary = "Return maximum of two signed integer operands";
 
@@ -637,6 +667,36 @@ def SPV_GLSLFMinOp : SPV_GLSLBinaryArithmeticOp<"FMin", 37, SPV_Float> {
 
 // -----
 
+def SPV_GLSLUMinOp : SPV_GLSLBinaryArithmeticOp<"UMin", 38, SPV_Integer> {
+  let summary = "Return minimum of two unsigned integer operands";
+
+  let description = [{
+    Result is y if y < x; otherwise result is x, where x and y are interpreted
+    as unsigned integers.
+
+    Result Type and the type of x and y must both be integer scalar or integer
+    vector types. Result Type and operand types must have the same number of
+    components with the same component width. Results are computed per
+    component.
+
+    <!-- End of AutoGen section -->
+    ```
+    integer-scalar-vector-type ::= integer-type |
+                                   `vector<` integer-literal `x` integer-type `>`
+    smin-op ::= ssa-id `=` `spv.GLSL.UMin` ssa-use `:`
+                integer-scalar-vector-type
+    ```
+    #### Example:
+
+    ```mlir
+    %2 = spv.GLSL.UMin %0, %1 : i32
+    %3 = spv.GLSL.UMin %0, %1 : vector<3xi16>
+    ```
+  }];
+}
+
+// -----
+
 def SPV_GLSLSMinOp : SPV_GLSLBinaryArithmeticOp<"SMin", 39, SPV_Integer> {
   let summary = "Return minimum of two signed integer operands";
 

diff  --git a/mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp b/mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp
index fe8b9256c1c67..951a0512a4b90 100644
--- a/mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp
+++ b/mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp
@@ -889,6 +889,12 @@ void populateStandardToSPIRVPatterns(SPIRVTypeConverter &typeConverter,
       UnaryAndBinaryOpPattern<CeilFOp, spirv::GLSLCeilOp>,
       UnaryAndBinaryOpPattern<DivFOp, spirv::FDivOp>,
       UnaryAndBinaryOpPattern<FloorFOp, spirv::GLSLFloorOp>,
+      UnaryAndBinaryOpPattern<MaxFOp, spirv::GLSLFMaxOp>,
+      UnaryAndBinaryOpPattern<MaxSIOp, spirv::GLSLSMaxOp>,
+      UnaryAndBinaryOpPattern<MaxUIOp, spirv::GLSLUMaxOp>,
+      UnaryAndBinaryOpPattern<MinFOp, spirv::GLSLFMinOp>,
+      UnaryAndBinaryOpPattern<MinSIOp, spirv::GLSLSMinOp>,
+      UnaryAndBinaryOpPattern<MinUIOp, spirv::GLSLUMinOp>,
       UnaryAndBinaryOpPattern<MulFOp, spirv::FMulOp>,
       UnaryAndBinaryOpPattern<MulIOp, spirv::IMulOp>,
       UnaryAndBinaryOpPattern<NegFOp, spirv::FNegateOp>,

diff  --git a/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir b/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
index f580edcce840c..d55aaca358a9b 100644
--- a/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
+++ b/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
@@ -24,6 +24,14 @@ func @int32_scalar(%lhs: i32, %rhs: i32) {
   %4 = divi_unsigned %lhs, %rhs: i32
   // CHECK: spv.UMod %{{.*}}, %{{.*}}: i32
   %5 = remi_unsigned %lhs, %rhs: i32
+  // CHECK: spv.GLSL.SMax %{{.*}}, %{{.*}}: i32
+  %6 = maxsi %lhs, %rhs : i32
+  // CHECK: spv.GLSL.UMax %{{.*}}, %{{.*}}: i32
+  %7 = maxui %lhs, %rhs : i32
+  // CHECK: spv.GLSL.SMin %{{.*}}, %{{.*}}: i32
+  %8 = minsi %lhs, %rhs : i32
+  // CHECK: spv.GLSL.UMin %{{.*}}, %{{.*}}: i32
+  %9 = minui %lhs, %rhs : i32
   return
 }
 
@@ -67,6 +75,10 @@ func @float32_binary_scalar(%lhs: f32, %rhs: f32) {
   %3 = divf %lhs, %rhs: f32
   // CHECK: spv.FRem %{{.*}}, %{{.*}}: f32
   %4 = remf %lhs, %rhs: f32
+  // CHECK: spv.GLSL.FMax %{{.*}}, %{{.*}}: f32
+  %5 = maxf %lhs, %rhs: f32
+  // CHECK: spv.GLSL.FMin %{{.*}}, %{{.*}}: f32
+  %6 = minf %lhs, %rhs: f32
   return
 }
 

diff  --git a/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir b/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
index cb941ad5fe26b..78997114a0e40 100644
--- a/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
@@ -51,24 +51,42 @@ func @exp(%arg0 : i32) -> () {
 // -----
 
 //===----------------------------------------------------------------------===//
-// spv.GLSL.FMax
+// spv.GLSL.{F|S|U}{Max|Min}
 //===----------------------------------------------------------------------===//
 
-func @fmax(%arg0 : f32, %arg1 : f32) -> () {
+func @fmaxmin(%arg0 : f32, %arg1 : f32) {
   // CHECK: spv.GLSL.FMax {{%.*}}, {{%.*}} : f32
-  %2 = spv.GLSL.FMax %arg0, %arg1 : f32
+  %1 = spv.GLSL.FMax %arg0, %arg1 : f32
+  // CHECK: spv.GLSL.FMin {{%.*}}, {{%.*}} : f32
+  %2 = spv.GLSL.FMin %arg0, %arg1 : f32
   return
 }
 
-func @fmaxvec(%arg0 : vector<3xf16>, %arg1 : vector<3xf16>) -> () {
+func @fmaxminvec(%arg0 : vector<3xf16>, %arg1 : vector<3xf16>) {
   // CHECK: spv.GLSL.FMax {{%.*}}, {{%.*}} : vector<3xf16>
-  %2 = spv.GLSL.FMax %arg0, %arg1 : vector<3xf16>
+  %1 = spv.GLSL.FMax %arg0, %arg1 : vector<3xf16>
+  // CHECK: spv.GLSL.FMin {{%.*}}, {{%.*}} : vector<3xf16>
+  %2 = spv.GLSL.FMin %arg0, %arg1 : vector<3xf16>
   return
 }
 
-func @fmaxf64(%arg0 : f64, %arg1 : f64) -> () {
+func @fmaxminf64(%arg0 : f64, %arg1 : f64) {
   // CHECK: spv.GLSL.FMax {{%.*}}, {{%.*}} : f64
-  %2 = spv.GLSL.FMax %arg0, %arg1 : f64
+  %1 = spv.GLSL.FMax %arg0, %arg1 : f64
+  // CHECK: spv.GLSL.FMin {{%.*}}, {{%.*}} : f64
+  %2 = spv.GLSL.FMin %arg0, %arg1 : f64
+  return
+}
+
+func @iminmax(%arg0: i32, %arg1: i32) {
+  // CHECK: spv.GLSL.SMax {{%.*}}, {{%.*}} : i32
+  %1 = spv.GLSL.SMax %arg0, %arg1 : i32
+  // CHECK: spv.GLSL.UMax {{%.*}}, {{%.*}} : i32
+  %2 = spv.GLSL.UMax %arg0, %arg1 : i32
+  // CHECK: spv.GLSL.SMin {{%.*}}, {{%.*}} : i32
+  %3 = spv.GLSL.SMin %arg0, %arg1 : i32
+  // CHECK: spv.GLSL.UMin {{%.*}}, {{%.*}} : i32
+  %4 = spv.GLSL.UMin %arg0, %arg1 : i32
   return
 }
 

diff  --git a/mlir/test/Target/SPIRV/glsl-ops.mlir b/mlir/test/Target/SPIRV/glsl-ops.mlir
index 1423eed6f329e..914aa1ffc40e8 100644
--- a/mlir/test/Target/SPIRV/glsl-ops.mlir
+++ b/mlir/test/Target/SPIRV/glsl-ops.mlir
@@ -1,11 +1,9 @@
 // RUN: mlir-translate -test-spirv-roundtrip %s | FileCheck %s
 
 spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
-  spv.func @fmul(%arg0 : f32, %arg1 : f32, %arg2 : i32) "None" {
+  spv.func @math(%arg0 : f32, %arg1 : f32, %arg2 : i32) "None" {
     // CHECK: {{%.*}} = spv.GLSL.Exp {{%.*}} : f32
     %0 = spv.GLSL.Exp %arg0 : f32
-    // CHECK: {{%.*}} = spv.GLSL.FMax {{%.*}}, {{%.*}} : f32
-    %1 = spv.GLSL.FMax %arg0, %arg1 : f32
     // CHECK: {{%.*}} = spv.GLSL.Sqrt {{%.*}} : f32
     %2 = spv.GLSL.Sqrt %arg0 : f32
     // CHECK: {{%.*}} = spv.GLSL.Cos {{%.*}} : f32
@@ -37,6 +35,23 @@ spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
     spv.Return
   }
 
+  spv.func @maxmin(%arg0 : f32, %arg1 : f32, %arg2 : i32, %arg3 : i32) "None" {
+    // CHECK: {{%.*}} = spv.GLSL.FMax {{%.*}}, {{%.*}} : f32
+    %1 = spv.GLSL.FMax %arg0, %arg1 : f32
+    // CHECK: {{%.*}} = spv.GLSL.SMax {{%.*}}, {{%.*}} : i32
+    %2 = spv.GLSL.SMax %arg2, %arg3 : i32
+    // CHECK: {{%.*}} = spv.GLSL.UMax {{%.*}}, {{%.*}} : i32
+    %3 = spv.GLSL.UMax %arg2, %arg3 : i32
+
+    // CHECK: {{%.*}} = spv.GLSL.FMin {{%.*}}, {{%.*}} : f32
+    %4 = spv.GLSL.FMin %arg0, %arg1 : f32
+    // CHECK: {{%.*}} = spv.GLSL.SMin {{%.*}}, {{%.*}} : i32
+    %5 = spv.GLSL.SMin %arg2, %arg3 : i32
+    // CHECK: {{%.*}} = spv.GLSL.UMin {{%.*}}, {{%.*}} : i32
+    %6 = spv.GLSL.UMin %arg2, %arg3 : i32
+    spv.Return
+  }
+
   spv.func @fclamp(%arg0 : f32, %arg1 : f32, %arg2 : f32) "None" {
     // CHECK: spv.GLSL.FClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : f32
     %13 = spv.GLSL.FClamp %arg0, %arg1, %arg2 : f32


        


More information about the Mlir-commits mailing list