Skip to content

Commit 7716768

Browse files
authored
[mlir][spirv] Add missing group non-uniform bitwise and logical ops (#73475)
This covers the following ops: `spirv.GroupNonUniform` x {`Bitwise`, `Logical`} x {`And`, `Or`, `Xor`} We need these to efficiently lower from the `gpu.subgroup_reduce` op.
1 parent 2e6c01b commit 7716768

File tree

4 files changed

+537
-0
lines changed

4 files changed

+537
-0
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,6 +4462,12 @@ def SPIRV_OC_OpGroupNonUniformFMin : I32EnumAttrCase<"OpGroupNonUniformFM
44624462
def SPIRV_OC_OpGroupNonUniformSMax : I32EnumAttrCase<"OpGroupNonUniformSMax", 356>;
44634463
def SPIRV_OC_OpGroupNonUniformUMax : I32EnumAttrCase<"OpGroupNonUniformUMax", 357>;
44644464
def SPIRV_OC_OpGroupNonUniformFMax : I32EnumAttrCase<"OpGroupNonUniformFMax", 358>;
4465+
def SPIRV_OC_OpGroupNonUniformBitwiseAnd : I32EnumAttrCase<"OpGroupNonUniformBitwiseAnd", 359>;
4466+
def SPIRV_OC_OpGroupNonUniformBitwiseOr : I32EnumAttrCase<"OpGroupNonUniformBitwiseOr", 360>;
4467+
def SPIRV_OC_OpGroupNonUniformBitwiseXor : I32EnumAttrCase<"OpGroupNonUniformBitwiseXor", 361>;
4468+
def SPIRV_OC_OpGroupNonUniformLogicalAnd : I32EnumAttrCase<"OpGroupNonUniformLogicalAnd", 362>;
4469+
def SPIRV_OC_OpGroupNonUniformLogicalOr : I32EnumAttrCase<"OpGroupNonUniformLogicalOr", 363>;
4470+
def SPIRV_OC_OpGroupNonUniformLogicalXor : I32EnumAttrCase<"OpGroupNonUniformLogicalXor", 364>;
44654471
def SPIRV_OC_OpSubgroupBallotKHR : I32EnumAttrCase<"OpSubgroupBallotKHR", 4421>;
44664472
def SPIRV_OC_OpSDot : I32EnumAttrCase<"OpSDot", 4450>;
44674473
def SPIRV_OC_OpUDot : I32EnumAttrCase<"OpUDot", 4451>;
@@ -4570,6 +4576,9 @@ def SPIRV_OpcodeAttr :
45704576
SPIRV_OC_OpGroupNonUniformSMin, SPIRV_OC_OpGroupNonUniformUMin,
45714577
SPIRV_OC_OpGroupNonUniformFMin, SPIRV_OC_OpGroupNonUniformSMax,
45724578
SPIRV_OC_OpGroupNonUniformUMax, SPIRV_OC_OpGroupNonUniformFMax,
4579+
SPIRV_OC_OpGroupNonUniformBitwiseAnd, SPIRV_OC_OpGroupNonUniformBitwiseOr,
4580+
SPIRV_OC_OpGroupNonUniformBitwiseXor, SPIRV_OC_OpGroupNonUniformLogicalAnd,
4581+
SPIRV_OC_OpGroupNonUniformLogicalOr, SPIRV_OC_OpGroupNonUniformLogicalXor,
45734582
SPIRV_OC_OpSubgroupBallotKHR, SPIRV_OC_OpSDot, SPIRV_OC_OpUDot,
45744583
SPIRV_OC_OpSUDot, SPIRV_OC_OpSDotAccSat, SPIRV_OC_OpUDotAccSat,
45754584
SPIRV_OC_OpSUDotAccSat,

mlir/include/mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,4 +997,304 @@ def SPIRV_GroupNonUniformUMinOp : SPIRV_GroupNonUniformArithmeticOp<"GroupNonUni
997997

998998
// -----
999999

1000+
def SPIRV_GroupNonUniformBitwiseAndOp :
1001+
SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformBitwiseAnd",
1002+
SPIRV_Integer, []> {
1003+
let summary = [{
1004+
A bitwise `and` group operation of all Value operands contributed by active
1005+
invocations in the group.
1006+
}];
1007+
1008+
let description = [{
1009+
Result Type must be a scalar or vector of integer type.
1010+
1011+
Execution is a Scope. It must be either Workgroup or Subgroup.
1012+
1013+
The identity I for Operation is ~0. If Operation is ClusteredReduce,
1014+
ClusterSize must be present.
1015+
1016+
The type of Value must be the same as Result Type.
1017+
1018+
ClusterSize is the size of cluster to use. ClusterSize must be a scalar
1019+
of integer type, whose Signedness operand is 0. ClusterSize must come
1020+
from a constant instruction. ClusterSize must be at least 1, and must be
1021+
a power of 2. If ClusterSize is greater than the declared SubGroupSize,
1022+
executing this instruction results in undefined behavior.
1023+
1024+
<!-- End of AutoGen section -->
1025+
1026+
#### Example:
1027+
1028+
```mlir
1029+
%four = spirv.Constant 4 : i32
1030+
%scalar = ... : i32
1031+
%vector = ... : vector<4xi32>
1032+
%0 = spirv.GroupNonUniformBitwiseAnd "Workgroup" "Reduce" %scalar : i32
1033+
%1 = spirv.GroupNonUniformBitwiseAnd "Subgroup" "ClusteredReduce"
1034+
%vector cluster_size(%four) : vector<4xi32>
1035+
```
1036+
}];
1037+
1038+
let availability = [
1039+
MinVersion<SPIRV_V_1_3>,
1040+
MaxVersion<SPIRV_V_1_6>,
1041+
Extension<[]>,
1042+
Capability<[SPIRV_C_GroupNonUniformArithmetic,
1043+
SPIRV_C_GroupNonUniformClustered,
1044+
SPIRV_C_GroupNonUniformPartitionedNV]>
1045+
];
1046+
}
1047+
1048+
// -----
1049+
1050+
def SPIRV_GroupNonUniformBitwiseOrOp :
1051+
SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformBitwiseOr",
1052+
SPIRV_Integer, []> {
1053+
let summary = [{
1054+
A bitwise `or` group operation of all Value operands contributed by active
1055+
invocations in the group.
1056+
}];
1057+
1058+
let description = [{
1059+
Result Type must be a scalar or vector of integer type.
1060+
1061+
Execution is a Scope. It must be either Workgroup or Subgroup.
1062+
1063+
The identity I for Operation is 0. If Operation is ClusteredReduce,
1064+
ClusterSize must be present.
1065+
1066+
The type of Value must be the same as Result Type.
1067+
1068+
ClusterSize is the size of cluster to use. ClusterSize must be a scalar
1069+
of integer type, whose Signedness operand is 0. ClusterSize must come
1070+
from a constant instruction. ClusterSize must be at least 1, and must be
1071+
a power of 2. If ClusterSize is greater than the declared SubGroupSize,
1072+
executing this instruction results in undefined behavior.
1073+
1074+
<!-- End of AutoGen section -->
1075+
1076+
#### Example:
1077+
1078+
```mlir
1079+
%four = spirv.Constant 4 : i32
1080+
%scalar = ... : i32
1081+
%vector = ... : vector<4xi32>
1082+
%0 = spirv.GroupNonUniformBitwiseOr "Workgroup" "Reduce" %scalar : i32
1083+
%1 = spirv.GroupNonUniformBitwiseOr "Subgroup" "ClusteredReduce"
1084+
%vector cluster_size(%four) : vector<4xi32>
1085+
```
1086+
}];
1087+
1088+
let availability = [
1089+
MinVersion<SPIRV_V_1_3>,
1090+
MaxVersion<SPIRV_V_1_6>,
1091+
Extension<[]>,
1092+
Capability<[SPIRV_C_GroupNonUniformArithmetic,
1093+
SPIRV_C_GroupNonUniformClustered,
1094+
SPIRV_C_GroupNonUniformPartitionedNV]>
1095+
];
1096+
}
1097+
1098+
// -----
1099+
1100+
def SPIRV_GroupNonUniformBitwiseXorOp :
1101+
SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformBitwiseXor",
1102+
SPIRV_Integer, []> {
1103+
let summary = [{
1104+
A bitwise `xor` group operation of all Value operands contributed by active
1105+
invocations in the group.
1106+
}];
1107+
1108+
let description = [{
1109+
Result Type must be a scalar or vector of integer type.
1110+
1111+
Execution is a Scope. It must be either Workgroup or Subgroup.
1112+
1113+
The identity I for Operation is 0. If Operation is ClusteredReduce,
1114+
ClusterSize must be present.
1115+
1116+
The type of Value must be the same as Result Type.
1117+
1118+
ClusterSize is the size of cluster to use. ClusterSize must be a scalar
1119+
of integer type, whose Signedness operand is 0. ClusterSize must come
1120+
from a constant instruction. ClusterSize must be at least 1, and must be
1121+
a power of 2. If ClusterSize is greater than the declared SubGroupSize,
1122+
executing this instruction results in undefined behavior.
1123+
1124+
<!-- End of AutoGen section -->
1125+
1126+
#### Example:
1127+
1128+
```mlir
1129+
%four = spirv.Constant 4 : i32
1130+
%scalar = ... : i32
1131+
%vector = ... : vector<4xi32>
1132+
%0 = spirv.GroupNonUniformBitwiseXor "Workgroup" "Reduce" %scalar : i32
1133+
%1 = spirv.GroupNonUniformBitwiseXor "Subgroup" "ClusteredReduce"
1134+
%vector cluster_size(%four) : vector<4xi32>
1135+
```
1136+
}];
1137+
1138+
let availability = [
1139+
MinVersion<SPIRV_V_1_3>,
1140+
MaxVersion<SPIRV_V_1_6>,
1141+
Extension<[]>,
1142+
Capability<[SPIRV_C_GroupNonUniformArithmetic,
1143+
SPIRV_C_GroupNonUniformClustered,
1144+
SPIRV_C_GroupNonUniformPartitionedNV]>
1145+
];
1146+
}
1147+
1148+
// -----
1149+
1150+
def SPIRV_GroupNonUniformLogicalAndOp :
1151+
SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformLogicalAnd",
1152+
SPIRV_Bool, []> {
1153+
let summary = [{
1154+
A logical `and` group operation of all Value operands contributed by active
1155+
invocations in the group.
1156+
}];
1157+
1158+
let description = [{
1159+
Result Type must be a scalar or vector of Boolean type.
1160+
1161+
Execution is a Scope. It must be either Workgroup or Subgroup.
1162+
1163+
The identity I for Operation is ~0. If Operation is ClusteredReduce,
1164+
ClusterSize must be present.
1165+
1166+
The type of Value must be the same as Result Type.
1167+
1168+
ClusterSize is the size of cluster to use. ClusterSize must be a scalar
1169+
of integer type, whose Signedness operand is 0. ClusterSize must come
1170+
from a constant instruction. ClusterSize must be at least 1, and must be
1171+
a power of 2. If ClusterSize is greater than the declared SubGroupSize,
1172+
executing this instruction results in undefined behavior.
1173+
1174+
<!-- End of AutoGen section -->
1175+
1176+
#### Example:
1177+
1178+
```mlir
1179+
%four = spirv.Constant 4 : i32
1180+
%scalar = ... : i1
1181+
%vector = ... : vector<4xi1>
1182+
%0 = spirv.GroupNonUniformLogicalAnd "Workgroup" "Reduce" %scalar : i1
1183+
%1 = spirv.GroupNonUniformLogicalAnd "Subgroup" "ClusteredReduce"
1184+
%vector cluster_size(%four) : vector<4xi1>
1185+
```
1186+
}];
1187+
1188+
let availability = [
1189+
MinVersion<SPIRV_V_1_3>,
1190+
MaxVersion<SPIRV_V_1_6>,
1191+
Extension<[]>,
1192+
Capability<[SPIRV_C_GroupNonUniformArithmetic,
1193+
SPIRV_C_GroupNonUniformClustered,
1194+
SPIRV_C_GroupNonUniformPartitionedNV]>
1195+
];
1196+
}
1197+
1198+
// -----
1199+
1200+
def SPIRV_GroupNonUniformLogicalOrOp :
1201+
SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformLogicalOr",
1202+
SPIRV_Bool, []> {
1203+
let summary = [{
1204+
A logical `or` group operation of all Value operands contributed by active
1205+
invocations in the group.
1206+
}];
1207+
1208+
let description = [{
1209+
Result Type must be a scalar or vector of Boolean type.
1210+
1211+
Execution is a Scope. It must be either Workgroup or Subgroup.
1212+
1213+
The identity I for Operation is 0. If Operation is ClusteredReduce,
1214+
ClusterSize must be present.
1215+
1216+
The type of Value must be the same as Result Type.
1217+
1218+
ClusterSize is the size of cluster to use. ClusterSize must be a scalar
1219+
of integer type, whose Signedness operand is 0. ClusterSize must come
1220+
from a constant instruction. ClusterSize must be at least 1, and must be
1221+
a power of 2. If ClusterSize is greater than the declared SubGroupSize,
1222+
executing this instruction results in undefined behavior.
1223+
1224+
<!-- End of AutoGen section -->
1225+
1226+
#### Example:
1227+
1228+
```mlir
1229+
%four = spirv.Constant 4 : i32
1230+
%scalar = ... : i1
1231+
%vector = ... : vector<4xi1>
1232+
%0 = spirv.GroupNonUniformLogicalOr "Workgroup" "Reduce" %scalar : i1
1233+
%1 = spirv.GroupNonUniformLogicalOr "Subgroup" "ClusteredReduce"
1234+
%vector cluster_size(%four) : vector<4xi1>
1235+
```
1236+
}];
1237+
1238+
let availability = [
1239+
MinVersion<SPIRV_V_1_3>,
1240+
MaxVersion<SPIRV_V_1_6>,
1241+
Extension<[]>,
1242+
Capability<[SPIRV_C_GroupNonUniformArithmetic,
1243+
SPIRV_C_GroupNonUniformClustered,
1244+
SPIRV_C_GroupNonUniformPartitionedNV]>
1245+
];
1246+
}
1247+
1248+
// -----
1249+
1250+
def SPIRV_GroupNonUniformLogicalXorOp :
1251+
SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformLogicalXor",
1252+
SPIRV_Bool, []> {
1253+
let summary = [{
1254+
A logical `xor` group operation of all Value operands contributed by active
1255+
invocations in the group.
1256+
}];
1257+
1258+
let description = [{
1259+
Result Type must be a scalar or vector of Boolean type.
1260+
1261+
Execution is a Scope. It must be either Workgroup or Subgroup.
1262+
1263+
The identity I for Operation is 0. If Operation is ClusteredReduce,
1264+
ClusterSize must be present.
1265+
1266+
The type of Value must be the same as Result Type.
1267+
1268+
ClusterSize is the size of cluster to use. ClusterSize must be a scalar
1269+
of integer type, whose Signedness operand is 0. ClusterSize must come
1270+
from a constant instruction. ClusterSize must be at least 1, and must be
1271+
a power of 2. If ClusterSize is greater than the declared SubGroupSize,
1272+
executing this instruction results in undefined behavior.
1273+
1274+
<!-- End of AutoGen section -->
1275+
1276+
#### Example:
1277+
1278+
```mlir
1279+
%four = spirv.Constant 4 : i32
1280+
%scalar = ... : i1
1281+
%vector = ... : vector<4xi1>
1282+
%0 = spirv.GroupNonUniformLogicalXor "Workgroup" "Reduce" %scalar : i1
1283+
%1 = spirv.GroupNonUniformLogicalXor "Subgroup" "ClusteredReduce"
1284+
%vector cluster_size(%four) : vector<4xi>
1285+
```
1286+
}];
1287+
1288+
let availability = [
1289+
MinVersion<SPIRV_V_1_3>,
1290+
MaxVersion<SPIRV_V_1_6>,
1291+
Extension<[]>,
1292+
Capability<[SPIRV_C_GroupNonUniformArithmetic,
1293+
SPIRV_C_GroupNonUniformClustered,
1294+
SPIRV_C_GroupNonUniformPartitionedNV]>
1295+
];
1296+
}
1297+
1298+
// -----
1299+
10001300
#endif // MLIR_DIALECT_SPIRV_IR_NON_UNIFORM_OPS

0 commit comments

Comments
 (0)