Skip to content

Commit 076f87a

Browse files
ergawyantiagainst
authored andcommitted
[MLIR][SPIRV] Add support for GLSL F/U/SClamp.
Adds support for 3 ternary ops from SPIR-V extended instructions for GLSL. Namely, adds support for FClamp, UClamp, and SClamp. Reviewed By: antiagainst Differential Revision: https://reviews.llvm.org/D92859
1 parent 0ee73bb commit 076f87a

File tree

4 files changed

+205
-0
lines changed

4 files changed

+205
-0
lines changed

mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3075,6 +3075,7 @@ def SPV_Type : AnyTypeOf<[
30753075
SPV_AnyCooperativeMatrix, SPV_AnyMatrix
30763076
]>;
30773077

3078+
def SPV_SignedInt : SignedIntOfWidths<[8, 16, 32, 64]>;
30783079
def SPV_SignlessOrUnsignedInt : SignlessOrUnsignedIntOfWidths<[8, 16, 32, 64]>;
30793080

30803081
class SPV_CoopMatrixOfType<list<Type> allowedTypes> :

mlir/include/mlir/Dialect/SPIRV/SPIRVGLSLOps.td

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,28 @@ class SPV_GLSLBinaryArithmeticOp<string mnemonic, int opcode, Type type,
7777
list<OpTrait> traits = []> :
7878
SPV_GLSLBinaryOp<mnemonic, opcode, type, type, traits>;
7979

80+
// Base class for GLSL ternary ops.
81+
class SPV_GLSLTernaryArithmeticOp<string mnemonic, int opcode, Type type,
82+
list<OpTrait> traits = []> :
83+
SPV_GLSLOp<mnemonic, opcode, !listconcat([NoSideEffect], traits)> {
84+
85+
let arguments = (ins
86+
SPV_ScalarOrVectorOf<type>:$x,
87+
SPV_ScalarOrVectorOf<type>:$y,
88+
SPV_ScalarOrVectorOf<type>:$z
89+
);
90+
91+
let results = (outs
92+
SPV_ScalarOrVectorOf<type>:$result
93+
);
94+
95+
let parser = [{ return impl::parseOneResultSameOperandTypeOp(parser, result); }];
96+
97+
let printer = [{ return impl::printOneResultOp(getOperation(), p); }];
98+
99+
let verifier = [{ return success(); }];
100+
}
101+
80102
// -----
81103

82104
def SPV_GLSLFAbsOp : SPV_GLSLUnaryArithmeticOp<"FAbs", 4, SPV_Float> {
@@ -862,4 +884,92 @@ def SPV_GLSLTanhOp : SPV_GLSLUnaryArithmeticOp<"Tanh", 21, SPV_Float16or32> {
862884
}];
863885
}
864886

887+
// -----
888+
889+
def SPV_GLSLFClampOp : SPV_GLSLTernaryArithmeticOp<"FClamp", 43, SPV_Float> {
890+
let summary = "Clamp x between min and max values.";
891+
892+
let description = [{
893+
Result is min(max(x, minVal), maxVal). The resulting value is undefined if
894+
minVal > maxVal. The semantics used by min() and max() are those of FMin and
895+
FMax.
896+
897+
The operands must all be a scalar or vector whose component type is
898+
floating-point.
899+
900+
Result Type and the type of all operands must be the same type. Results are
901+
computed per component.
902+
903+
<!-- End of AutoGen section -->
904+
```
905+
fclamp-op ::= ssa-id `=` `spv.GLSL.FClamp` ssa-use, ssa-use, ssa-use `:`
906+
float-scalar-vector-type
907+
```
908+
#### Example:
909+
910+
```mlir
911+
%2 = spv.GLSL.FClamp %x, %min, %max : f32
912+
%3 = spv.GLSL.FClamp %x, %min, %max : vector<3xf16>
913+
```
914+
}];
915+
}
916+
917+
// -----
918+
919+
def SPV_GLSLUClampOp : SPV_GLSLTernaryArithmeticOp<"UClamp", 44, SPV_SignlessOrUnsignedInt> {
920+
let summary = "Clamp x between min and max values.";
921+
922+
let description = [{
923+
Result is min(max(x, minVal), maxVal), where x, minVal and maxVal are
924+
interpreted as unsigned integers. The resulting value is undefined if
925+
minVal > maxVal.
926+
927+
Result Type and the type of the operands must both be integer scalar or
928+
integer vector types. Result Type and operand types must have the same number
929+
of components with the same component width. Results are computed per
930+
component.
931+
932+
<!-- End of AutoGen section -->
933+
```
934+
uclamp-op ::= ssa-id `=` `spv.GLSL.UClamp` ssa-use, ssa-use, ssa-use `:`
935+
unsgined-signless-scalar-vector-type
936+
```
937+
#### Example:
938+
939+
```mlir
940+
%2 = spv.GLSL.UClamp %x, %min, %max : i32
941+
%3 = spv.GLSL.UClamp %x, %min, %max : vector<3xui16>
942+
```
943+
}];
944+
}
945+
946+
// -----
947+
948+
def SPV_GLSLSClampOp : SPV_GLSLTernaryArithmeticOp<"SClamp", 45, SPV_SignedInt> {
949+
let summary = "Clamp x between min and max values.";
950+
951+
let description = [{
952+
Result is min(max(x, minVal), maxVal), where x, minVal and maxVal are
953+
interpreted as signed integers. The resulting value is undefined if
954+
minVal > maxVal.
955+
956+
Result Type and the type of the operands must both be integer scalar or
957+
integer vector types. Result Type and operand types must have the same number
958+
of components with the same component width. Results are computed per
959+
component.
960+
961+
<!-- End of AutoGen section -->
962+
```
963+
uclamp-op ::= ssa-id `=` `spv.GLSL.UClamp` ssa-use, ssa-use, ssa-use `:`
964+
sgined-scalar-vector-type
965+
```
966+
#### Example:
967+
968+
```mlir
969+
%2 = spv.GLSL.SClamp %x, %min, %max : si32
970+
%3 = spv.GLSL.SClamp %x, %min, %max : vector<3xsi16>
971+
```
972+
}];
973+
}
974+
865975
#endif // SPIRV_GLSL_OPS

mlir/test/Dialect/SPIRV/Serialization/glsl-ops.mlir

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,22 @@ spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
3030
%12 = spv.GLSL.Round %arg0 : f32
3131
spv.Return
3232
}
33+
34+
spv.func @fclamp(%arg0 : f32, %arg1 : f32, %arg2 : f32) "None" {
35+
// CHECK: spv.GLSL.FClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : f32
36+
%13 = spv.GLSL.FClamp %arg0, %arg1, %arg2 : f32
37+
spv.Return
38+
}
39+
40+
spv.func @uclamp(%arg0 : ui32, %arg1 : ui32, %arg2 : ui32) "None" {
41+
// CHECK: spv.GLSL.UClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : i32
42+
%13 = spv.GLSL.UClamp %arg0, %arg1, %arg2 : ui32
43+
spv.Return
44+
}
45+
46+
spv.func @sclamp(%arg0 : si32, %arg1 : si32, %arg2 : si32) "None" {
47+
// CHECK: spv.GLSL.SClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : si32
48+
%13 = spv.GLSL.SClamp %arg0, %arg1, %arg2 : si32
49+
spv.Return
50+
}
3351
}

mlir/test/Dialect/SPIRV/glslops.mlir

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,79 @@ func @roundvec(%arg0 : vector<3xf16>) -> () {
269269
%2 = spv.GLSL.Round %arg0 : vector<3xf16>
270270
return
271271
}
272+
273+
// -----
274+
275+
//===----------------------------------------------------------------------===//
276+
// spv.GLSL.FClamp
277+
//===----------------------------------------------------------------------===//
278+
279+
func @fclamp(%arg0 : f32, %min : f32, %max : f32) -> () {
280+
// CHECK: spv.GLSL.FClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : f32
281+
%2 = spv.GLSL.FClamp %arg0, %min, %max : f32
282+
return
283+
}
284+
285+
// -----
286+
287+
func @fclamp(%arg0 : vector<3xf32>, %min : vector<3xf32>, %max : vector<3xf32>) -> () {
288+
// CHECK: spv.GLSL.FClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : vector<3xf32>
289+
%2 = spv.GLSL.FClamp %arg0, %min, %max : vector<3xf32>
290+
return
291+
}
292+
293+
// -----
294+
295+
//===----------------------------------------------------------------------===//
296+
// spv.GLSL.UClamp
297+
//===----------------------------------------------------------------------===//
298+
299+
func @fclamp(%arg0 : ui32, %min : ui32, %max : ui32) -> () {
300+
// CHECK: spv.GLSL.UClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : ui32
301+
%2 = spv.GLSL.UClamp %arg0, %min, %max : ui32
302+
return
303+
}
304+
305+
// -----
306+
307+
func @fclamp(%arg0 : vector<4xi32>, %min : vector<4xi32>, %max : vector<4xi32>) -> () {
308+
// CHECK: spv.GLSL.UClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : vector<4xi32>
309+
%2 = spv.GLSL.UClamp %arg0, %min, %max : vector<4xi32>
310+
return
311+
}
312+
313+
// -----
314+
315+
func @fclamp(%arg0 : si32, %min : si32, %max : si32) -> () {
316+
// expected-error @+1 {{must be 8/16/32/64-bit signless/unsigned integer or vector}}
317+
%2 = spv.GLSL.UClamp %arg0, %min, %max : si32
318+
return
319+
}
320+
321+
// -----
322+
323+
//===----------------------------------------------------------------------===//
324+
// spv.GLSL.SClamp
325+
//===----------------------------------------------------------------------===//
326+
327+
func @fclamp(%arg0 : si32, %min : si32, %max : si32) -> () {
328+
// CHECK: spv.GLSL.SClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : si32
329+
%2 = spv.GLSL.SClamp %arg0, %min, %max : si32
330+
return
331+
}
332+
333+
// -----
334+
335+
func @fclamp(%arg0 : vector<4xsi32>, %min : vector<4xsi32>, %max : vector<4xsi32>) -> () {
336+
// CHECK: spv.GLSL.SClamp {{%[^,]*}}, {{%[^,]*}}, {{%[^,]*}} : vector<4xsi32>
337+
%2 = spv.GLSL.SClamp %arg0, %min, %max : vector<4xsi32>
338+
return
339+
}
340+
341+
// -----
342+
343+
func @fclamp(%arg0 : i32, %min : i32, %max : i32) -> () {
344+
// expected-error @+1 {{must be 8/16/32/64-bit signed integer or vector}}
345+
%2 = spv.GLSL.SClamp %arg0, %min, %max : i32
346+
return
347+
}

0 commit comments

Comments
 (0)