Added GroupNonUniformBroadcastOp to spirv dialect.
Differential Revision: https://reviews.llvm.org/D87688
def SPV_OC_OpNoLine : I32EnumAttrCase<"OpNoLine", 317>;
def SPV_OC_OpModuleProcessed : I32EnumAttrCase<"OpModuleProcessed", 330>;
def SPV_OC_OpGroupNonUniformElect : I32EnumAttrCase<"OpGroupNonUniformElect", 333>;
+def SPV_OC_OpGroupNonUniformBroadcast : I32EnumAttrCase<"OpGroupNonUniformBroadcast", 337>;
def SPV_OC_OpGroupNonUniformBallot : I32EnumAttrCase<"OpGroupNonUniformBallot", 339>;
def SPV_OC_OpGroupNonUniformIAdd : I32EnumAttrCase<"OpGroupNonUniformIAdd", 349>;
def SPV_OC_OpGroupNonUniformFAdd : I32EnumAttrCase<"OpGroupNonUniformFAdd", 350>;
SPV_OC_OpBranch, SPV_OC_OpBranchConditional, SPV_OC_OpReturn,
SPV_OC_OpReturnValue, SPV_OC_OpUnreachable, SPV_OC_OpGroupBroadcast,
SPV_OC_OpNoLine, SPV_OC_OpModuleProcessed, SPV_OC_OpGroupNonUniformElect,
- SPV_OC_OpGroupNonUniformBallot, SPV_OC_OpGroupNonUniformIAdd,
- SPV_OC_OpGroupNonUniformFAdd, SPV_OC_OpGroupNonUniformIMul,
- SPV_OC_OpGroupNonUniformFMul, SPV_OC_OpGroupNonUniformSMin,
- SPV_OC_OpGroupNonUniformUMin, SPV_OC_OpGroupNonUniformFMin,
- SPV_OC_OpGroupNonUniformSMax, SPV_OC_OpGroupNonUniformUMax,
- SPV_OC_OpGroupNonUniformFMax, SPV_OC_OpSubgroupBallotKHR,
- SPV_OC_OpTypeCooperativeMatrixNV, SPV_OC_OpCooperativeMatrixLoadNV,
- SPV_OC_OpCooperativeMatrixStoreNV, SPV_OC_OpCooperativeMatrixMulAddNV,
- SPV_OC_OpCooperativeMatrixLengthNV, SPV_OC_OpSubgroupBlockReadINTEL,
- SPV_OC_OpSubgroupBlockWriteINTEL
+ SPV_OC_OpGroupNonUniformBroadcast, SPV_OC_OpGroupNonUniformBallot,
+ SPV_OC_OpGroupNonUniformIAdd, SPV_OC_OpGroupNonUniformFAdd,
+ SPV_OC_OpGroupNonUniformIMul, SPV_OC_OpGroupNonUniformFMul,
+ SPV_OC_OpGroupNonUniformSMin, SPV_OC_OpGroupNonUniformUMin,
+ SPV_OC_OpGroupNonUniformFMin, SPV_OC_OpGroupNonUniformSMax,
+ SPV_OC_OpGroupNonUniformUMax, SPV_OC_OpGroupNonUniformFMax,
+ SPV_OC_OpSubgroupBallotKHR, SPV_OC_OpTypeCooperativeMatrixNV,
+ SPV_OC_OpCooperativeMatrixLoadNV, SPV_OC_OpCooperativeMatrixStoreNV,
+ SPV_OC_OpCooperativeMatrixMulAddNV, SPV_OC_OpCooperativeMatrixLengthNV,
+ SPV_OC_OpSubgroupBlockReadINTEL, SPV_OC_OpSubgroupBlockWriteINTEL
]>;
// End opcode section. Generated from SPIR-V spec; DO NOT MODIFY!
// -----
+def SPV_GroupNonUniformBroadcastOp : SPV_Op<"GroupNonUniformBroadcast",
+ [NoSideEffect, AllTypesMatch<["value", "result"]>]> {
+ let summary = [{
+ Return the Value of the invocation identified by the id Id to all active
+ invocations in the group.
+ }];
+
+ let description = [{
+ Result Type must be a scalar or vector of floating-point type, integer
+ type, or Boolean type.
+
+ Execution must be Workgroup or Subgroup Scope.
+
+ The type of Value must be the same as Result Type.
+
+ Id must be a scalar of integer type, whose Signedness operand is 0.
+
+ Before version 1.5, Id must come from a constant instruction. Starting
+ with version 1.5, Id must be dynamically uniform.
+
+ The resulting value is undefined if Id is an inactive invocation, or is
+ greater than or equal to the size of the group.
+
+ <!-- End of AutoGen section -->
+
+ ```
+ scope ::= `"Workgroup"` | `"Subgroup"`
+ integer-float-scalar-vector-type ::= integer-type | float-type |
+ `vector<` integer-literal `x` integer-type `>` |
+ `vector<` integer-literal `x` float-type `>`
+ group-non-uniform-broadcast-op ::= ssa-id `=`
+ `spv.GroupNonUniformBroadcast` scope ssa_use,
+ ssa_use `:` integer-float-scalar-vector-type `,` integer-type
+ ```mlir
+
+ #### Example:
+
+ ```
+ %scalar_value = ... : f32
+ %vector_value = ... : vector<4xf32>
+ %id = ... : i32
+ %0 = spv.GroupNonUniformBroadcast "Subgroup" %scalar_value, %id : f32, i32
+ %1 = spv.GroupNonUniformBroadcast "Workgroup" %vector_value, %id :
+ vector<4xf32>, i32
+ ```
+ }];
+
+ let availability = [
+ MinVersion<SPV_V_1_3>,
+ MaxVersion<SPV_V_1_5>,
+ Extension<[]>,
+ Capability<[SPV_C_GroupNonUniformBallot]>
+ ];
+
+ let arguments = (ins
+ SPV_ScopeAttr:$execution_scope,
+ SPV_Type:$value,
+ SPV_Integer:$id
+ );
+
+ let results = (outs
+ SPV_Type:$result
+ );
+
+ let assemblyFormat = [{
+ $execution_scope operands attr-dict `:` type($value) `,` type($id)
+ }];
+}
+
+// -----
+
def SPV_GroupNonUniformElectOp : SPV_Op<"GroupNonUniformElect", []> {
let summary = [{
Result is true only in the active invocation with the lowest id in the
def SPV_GroupNonUniformIAddOp :
SPV_GroupNonUniformArithmeticOp<"GroupNonUniformIAdd", SPV_Integer, []> {
let summary = [{
- An integer add group operation of all Value operands contributed active
- by invocations in the group.
+ An integer add group operation of all Value operands contributed by
+ active invocations in the group.
}];
let description = [{
#include "mlir/Dialect/SPIRV/SPIRVAttributes.h"
#include "mlir/Dialect/SPIRV/SPIRVDialect.h"
#include "mlir/Dialect/SPIRV/SPIRVTypes.h"
+#include "mlir/Dialect/SPIRV/TargetAndABI.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/Function.h"
#include "mlir/IR/FunctionImplementation.h"
}
//===----------------------------------------------------------------------===//
+// spv.GroupNonUniformBroadcast
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verify(spirv::GroupNonUniformBroadcastOp broadcastOp) {
+ spirv::Scope scope = broadcastOp.execution_scope();
+ if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
+ return broadcastOp.emitOpError(
+ "execution scope must be 'Workgroup' or 'Subgroup'");
+
+ // SPIR-V spec: "Before version 1.5, Id must come from a
+ // constant instruction.
+ auto targetEnv = spirv::getDefaultTargetEnv(broadcastOp.getContext());
+ if (auto spirvModule = broadcastOp.getParentOfType<spirv::ModuleOp>())
+ targetEnv = spirv::lookupTargetEnvOrDefault(spirvModule);
+
+ if (targetEnv.getVersion() < spirv::Version::V_1_5) {
+ auto *idOp = broadcastOp.id().getDefiningOp();
+ if (!idOp || !isa<spirv::ConstantOp, // for normal constant
+ spirv::ReferenceOfOp>(idOp)) // for spec constant
+ return broadcastOp.emitOpError("id must be the result of a constant op");
+ }
+
+ return success();
+}
+
+//===----------------------------------------------------------------------===//
// spv.SubgroupBlockReadINTEL
//===----------------------------------------------------------------------===//
spv.ReturnValue %0: vector<4xi32>
}
+ // CHECK-LABEL: @group_non_uniform_broadcast
+ spv.func @group_non_uniform_broadcast(%value: f32) -> f32 "None" {
+ %one = spv.constant 1 : i32
+ // CHECK: spv.GroupNonUniformBroadcast "Subgroup" %{{.*}}, %{{.*}} : f32, i32
+ %0 = spv.GroupNonUniformBroadcast "Subgroup" %value, %one : f32, i32
+ spv.ReturnValue %0: f32
+ }
+
// CHECK-LABEL: @group_non_uniform_elect
spv.func @group_non_uniform_elect() -> i1 "None" {
// CHECK: %{{.+}} = spv.GroupNonUniformElect "Workgroup" : i1
// -----
//===----------------------------------------------------------------------===//
+// spv.NonUniformGroupBroadcast
+//===----------------------------------------------------------------------===//
+
+func @group_non_uniform_broadcast_scalar(%value: f32) -> f32 {
+ %one = spv.constant 1 : i32
+ // CHECK: spv.GroupNonUniformBroadcast "Workgroup" %{{.*}}, %{{.*}} : f32, i32
+ %0 = spv.GroupNonUniformBroadcast "Workgroup" %value, %one : f32, i32
+ return %0: f32
+}
+
+// -----
+
+func @group_non_uniform_broadcast_vector(%value: vector<4xf32>) -> vector<4xf32> {
+ %one = spv.constant 1 : i32
+ // CHECK: spv.GroupNonUniformBroadcast "Subgroup" %{{.*}}, %{{.*}} : vector<4xf32>, i32
+ %0 = spv.GroupNonUniformBroadcast "Subgroup" %value, %one : vector<4xf32>, i32
+ return %0: vector<4xf32>
+}
+
+// -----
+
+func @group_non_uniform_broadcast_negative_scope(%value: f32, %localid: i32 ) -> f32 {
+ %one = spv.constant 1 : i32
+ // expected-error @+1 {{execution scope must be 'Workgroup' or 'Subgroup'}}
+ %0 = spv.GroupNonUniformBroadcast "Device" %value, %one : f32, i32
+ return %0: f32
+}
+
+// -----
+
+func @group_non_uniform_broadcast_negative_non_const(%value: f32, %localid: i32) -> f32 {
+ // expected-error @+1 {{id must be the result of a constant op}}
+ %0 = spv.GroupNonUniformBroadcast "Subgroup" %value, %localid : f32, i32
+ return %0: f32
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
// spv.GroupNonUniformElect
//===----------------------------------------------------------------------===//