Skip to content

Commit 4ca0e2c

Browse files
denis0x0Dtensorflower-gardener
authored andcommitted
[spirv] Add binary arithmetic operations #2.
Add binary operations such as: OpUdiv, OpSDiv, OpUMod, OpSRem, OpSMod. Closes #56 COPYBARA_INTEGRATE_REVIEW=tensorflow/mlir#56 from denis0x0D:sandbox/bin_ops_int 4959325a693b4658b978a8b97f79b8237eb39764 PiperOrigin-RevId: 260961681
1 parent 96ed591 commit 4ca0e2c

File tree

4 files changed

+263
-1
lines changed

4 files changed

+263
-1
lines changed

include/mlir/Dialect/SPIRV/SPIRVBase.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,12 @@ def SPV_OC_OpISub : I32EnumAttrCase<"OpISub", 130>;
105105
def SPV_OC_OpFSub : I32EnumAttrCase<"OpFSub", 131>;
106106
def SPV_OC_OpIMul : I32EnumAttrCase<"OpIMul", 132>;
107107
def SPV_OC_OpFMul : I32EnumAttrCase<"OpFMul", 133>;
108+
def SPV_OC_OpUDiv : I32EnumAttrCase<"OpUDiv", 134>;
109+
def SPV_OC_OpSDiv : I32EnumAttrCase<"OpSDiv", 135>;
108110
def SPV_OC_OpFDiv : I32EnumAttrCase<"OpFDiv", 136>;
111+
def SPV_OC_OpUMod : I32EnumAttrCase<"OpUMod", 137>;
112+
def SPV_OC_OpSRem : I32EnumAttrCase<"OpSRem", 138>;
113+
def SPV_OC_OpSMod : I32EnumAttrCase<"OpSMod", 139>;
109114
def SPV_OC_OpFRem : I32EnumAttrCase<"OpFRem", 140>;
110115
def SPV_OC_OpFMod : I32EnumAttrCase<"OpFMod", 141>;
111116
def SPV_OC_OpReturn : I32EnumAttrCase<"OpReturn", 253>;
@@ -121,7 +126,8 @@ def SPV_OpcodeAttr :
121126
SPV_OC_OpFunctionEnd, SPV_OC_OpVariable, SPV_OC_OpLoad, SPV_OC_OpStore,
122127
SPV_OC_OpAccessChain, SPV_OC_OpDecorate, SPV_OC_OpCompositeExtract,
123128
SPV_OC_OpIAdd, SPV_OC_OpFAdd, SPV_OC_OpISub, SPV_OC_OpFSub, SPV_OC_OpIMul,
124-
SPV_OC_OpFMul, SPV_OC_OpFDiv, SPV_OC_OpFRem, SPV_OC_OpFMod, SPV_OC_OpReturn
129+
SPV_OC_OpFMul, SPV_OC_OpUDiv, SPV_OC_OpSDiv, SPV_OC_OpFDiv, SPV_OC_OpUMod,
130+
SPV_OC_OpSRem, SPV_OC_OpSMod, SPV_OC_OpFRem, SPV_OC_OpFMod, SPV_OC_OpReturn
125131
]> {
126132
let returnType = "::mlir::spirv::Opcode";
127133
let convertFromStorage = "static_cast<::mlir::spirv::Opcode>($_self.getInt())";

include/mlir/Dialect/SPIRV/SPIRVOps.td

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,113 @@ def SPV_ReturnOp : SPV_Op<"Return", [Terminator]> {
623623

624624
// -----
625625

626+
def SPV_SDivOp : SPV_ArithmeticOp<"SDiv", SPV_Integer> {
627+
let summary = "Signed-integer division of Operand 1 divided by Operand 2.";
628+
629+
let description = [{
630+
Result Type must be a scalar or vector of integer type.
631+
632+
The type of Operand 1 and Operand 2 must be a scalar or vector of
633+
integer type. They must have the same number of components as Result
634+
Type. They must have the same component width as Result Type.
635+
636+
Results are computed per component. The resulting value is undefined
637+
if Operand 2 is 0.
638+
639+
### Custom assembly form
640+
``` {.ebnf}
641+
integer-scalar-vector-type ::= integer-type |
642+
`vector<` integer-literal `x` integer-type `>`
643+
sdiv-op ::= ssa-id `=` `spv.SDiv` ssa-use, ssa-use
644+
`:` integer-scalar-vector-type
645+
```
646+
647+
For example:
648+
649+
```
650+
%4 = spv.SDiv %0, %1 : i32
651+
%5 = spv.SDiv %2, %3 : vector<4xi32>
652+
653+
```
654+
}];
655+
}
656+
657+
// -----
658+
659+
def SPV_SModOp : SPV_ArithmeticOp<"SMod", SPV_Integer> {
660+
let summary = [{
661+
Signed remainder operation for the remainder whose sign matches the sign
662+
of Operand 2.
663+
}];
664+
665+
let description = [{
666+
Result Type must be a scalar or vector of integer type.
667+
668+
The type of Operand 1 and Operand 2 must be a scalar or vector of
669+
integer type. They must have the same number of components as Result
670+
Type. They must have the same component width as Result Type.
671+
672+
Results are computed per component. The resulting value is undefined
673+
if Operand 2 is 0. Otherwise, the result is the remainder r of Operand
674+
1 divided by Operand 2 where if r ≠ 0, the sign of r is the same as the
675+
sign of Operand 2.
676+
677+
### Custom assembly form
678+
``` {.ebnf}
679+
integer-scalar-vector-type ::= integer-type |
680+
`vector<` integer-literal `x` integer-type `>`
681+
smod-op ::= ssa-id `=` `spv.SMod` ssa-use, ssa-use
682+
`:` integer-scalar-vector-type
683+
```
684+
For example:
685+
686+
```
687+
%4 = spv.SMod %0, %1 : i32
688+
%5 = spv.SMod %2, %3 : vector<4xi32>
689+
690+
```
691+
}];
692+
}
693+
694+
// -----
695+
696+
def SPV_SRemOp : SPV_ArithmeticOp<"SRem", SPV_Integer> {
697+
let summary = [{
698+
Signed remainder operation for the remainder whose sign matches the sign
699+
of Operand 1.
700+
}];
701+
702+
let description = [{
703+
Result Type must be a scalar or vector of integer type.
704+
705+
The type of Operand 1 and Operand 2 must be a scalar or vector of
706+
integer type. They must have the same number of components as Result
707+
Type. They must have the same component width as Result Type.
708+
709+
Results are computed per component. The resulting value is undefined
710+
if Operand 2 is 0. Otherwise, the result is the remainder r of Operand
711+
1 divided by Operand 2 where if r ≠ 0, the sign of r is the same as the
712+
sign of Operand 1.
713+
714+
### Custom assembly form
715+
``` {.ebnf}
716+
integer-scalar-vector-type ::= integer-type |
717+
`vector<` integer-literal `x` integer-type `>`
718+
srem-op ::= ssa-id `=` `spv.SRem` ssa-use, ssa-use
719+
`:` integer-scalar-vector-type
720+
```
721+
For example:
722+
723+
```
724+
%4 = spv.SRem %0, %1 : i32
725+
%5 = spv.SRem %2, %3 : vector<4xi32>
726+
727+
```
728+
}];
729+
}
730+
731+
// -----
732+
626733
def SPV_StoreOp : SPV_Op<"Store", []> {
627734
let summary = "Store through a pointer.";
628735

@@ -665,6 +772,70 @@ def SPV_StoreOp : SPV_Op<"Store", []> {
665772

666773
// -----
667774

775+
def SPV_UDivOp : SPV_ArithmeticOp<"UDiv", SPV_Integer> {
776+
let summary = "Unsigned-integer division of Operand 1 divided by Operand 2.";
777+
778+
let description = [{
779+
Result Type must be a scalar or vector of integer type, whose Signedness
780+
operand is 0.
781+
782+
The types of Operand 1 and Operand 2 both must be the same as Result
783+
Type.
784+
785+
Results are computed per component. The resulting value is undefined
786+
if Operand 2 is 0.
787+
788+
### Custom assembly form
789+
``` {.ebnf}
790+
integer-scalar-vector-type ::= integer-type |
791+
`vector<` integer-literal `x` integer-type `>`
792+
udiv-op ::= ssa-id `=` `spv.UDiv` ssa-use, ssa-use
793+
`:` integer-scalar-vector-type
794+
```
795+
For example:
796+
797+
```
798+
%4 = spv.UDiv %0, %1 : i32
799+
%5 = spv.UDiv %2, %3 : vector<4xi32>
800+
801+
```
802+
}];
803+
}
804+
805+
// -----
806+
807+
def SPV_UModOp : SPV_ArithmeticOp<"UMod", SPV_Integer> {
808+
let summary = "Unsigned modulo operation of Operand 1 modulo Operand 2.";
809+
810+
let description = [{
811+
Result Type must be a scalar or vector of integer type, whose Signedness
812+
operand is 0.
813+
814+
The types of Operand 1 and Operand 2 both must be the same as Result
815+
Type.
816+
817+
Results are computed per component. The resulting value is undefined
818+
if Operand 2 is 0.
819+
820+
### Custom assembly form
821+
``` {.ebnf}
822+
integer-scalar-vector-type ::= integer-type |
823+
`vector<` integer-literal `x` integer-type `>`
824+
umod-op ::= ssa-id `=` `spv.UMod` ssa-use, ssa-use
825+
`:` integer-scalar-vector-type
826+
```
827+
For example:
828+
829+
```
830+
%4 = spv.UMod %0, %1 : i32
831+
%5 = spv.UMod %2, %3 : vector<4xi32>
832+
833+
```
834+
}];
835+
}
836+
837+
// -----
838+
668839
def SPV_VariableOp : SPV_Op<"Variable", []> {
669840
let summary = [{
670841
Allocate an object in memory, resulting in a pointer to it, which can be

test/Dialect/SPIRV/Serialization/bin_ops.mlir

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,31 @@ func @spirv_bin_ops() -> () {
4747
%0 = spv.IMul %arg0, %arg1 : vector<4xi32>
4848
spv.Return
4949
}
50+
func @udiv(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
51+
// CHECK: {{%.*}} = spv.UDiv {{%.*}}, {{%.*}} : vector<4xi32>
52+
%0 = spv.UDiv %arg0, %arg1 : vector<4xi32>
53+
spv.Return
54+
}
55+
func @umod(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
56+
// CHECK: {{%.*}} = spv.UMod {{%.*}}, {{%.*}} : vector<4xi32>
57+
%0 = spv.UMod %arg0, %arg1 : vector<4xi32>
58+
spv.Return
59+
}
60+
func @sdiv(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
61+
// CHECK: {{%.*}} = spv.SDiv {{%.*}}, {{%.*}} : vector<4xi32>
62+
%0 = spv.SDiv %arg0, %arg1 : vector<4xi32>
63+
spv.Return
64+
}
65+
func @smod(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
66+
// CHECK: {{%.*}} = spv.SMod {{%.*}}, {{%.*}} : vector<4xi32>
67+
%0 = spv.SMod %arg0, %arg1 : vector<4xi32>
68+
spv.Return
69+
}
70+
func @srem(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
71+
// CHECK: {{%.*}} = spv.SRem {{%.*}}, {{%.*}} : vector<4xi32>
72+
%0 = spv.SRem %arg0, %arg1 : vector<4xi32>
73+
spv.Return
74+
}
5075
}
5176
return
5277
}

test/Dialect/SPIRV/ops.mlir

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,66 @@ spv.module "Logical" "VulkanKHR" {
659659

660660
// -----
661661

662+
//===----------------------------------------------------------------------===//
663+
// spv.SDiv
664+
//===----------------------------------------------------------------------===//
665+
666+
func @sdiv_scalar(%arg: i32) -> i32 {
667+
// CHECK: spv.SDiv
668+
%0 = spv.SDiv %arg, %arg : i32
669+
return %0 : i32
670+
}
671+
672+
// -----
673+
674+
//===----------------------------------------------------------------------===//
675+
// spv.SMod
676+
//===----------------------------------------------------------------------===//
677+
678+
func @smod_scalar(%arg: i32) -> i32 {
679+
// CHECK: spv.SMod
680+
%0 = spv.SMod %arg, %arg : i32
681+
return %0 : i32
682+
}
683+
684+
// -----
685+
686+
//===----------------------------------------------------------------------===//
687+
// spv.SRem
688+
//===----------------------------------------------------------------------===//
689+
690+
func @srem_scalar(%arg: i32) -> i32 {
691+
// CHECK: spv.SRem
692+
%0 = spv.SRem %arg, %arg : i32
693+
return %0 : i32
694+
}
695+
696+
// -----
697+
698+
//===----------------------------------------------------------------------===//
699+
// spv.UDiv
700+
//===----------------------------------------------------------------------===//
701+
702+
func @udiv_scalar(%arg: i32) -> i32 {
703+
// CHECK: spv.UDiv
704+
%0 = spv.UDiv %arg, %arg : i32
705+
return %0 : i32
706+
}
707+
708+
// -----
709+
710+
//===----------------------------------------------------------------------===//
711+
// spv.UMod
712+
//===----------------------------------------------------------------------===//
713+
714+
func @umod_scalar(%arg: i32) -> i32 {
715+
// CHECK: spv.UMod
716+
%0 = spv.UMod %arg, %arg : i32
717+
return %0 : i32
718+
}
719+
720+
// -----
721+
662722
//===----------------------------------------------------------------------===//
663723
// spv.StoreOp
664724
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)