mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 23:49:22 +08:00
[mlir][spirv] Add ops and patterns for lowering standard max/min ops
Reviewed By: ThomasRaoux Differential Revision: https://reviews.llvm.org/D111143
This commit is contained in:
@@ -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";
|
||||
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user