23 template <
typename OpTy>
28 OpTy::getExecutionScopeAttrName(groupOp->
getName()))
30 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
32 "execution scope must be 'Workgroup' or 'Subgroup'");
34 GroupOperation operation =
37 OpTy::getGroupOperationAttrName(groupOp->
getName()))
39 if (operation == GroupOperation::ClusteredReduce &&
41 return groupOp->
emitOpError(
"cluster size operand must be provided for "
42 "'ClusteredReduce' group operation");
45 int32_t clusterSize = 0;
50 "cluster size operand must come from a constant op");
52 if (!llvm::isPowerOf2_32(clusterSize))
54 "cluster size operand must be a power of two");
64 spirv::Scope scope = getExecutionScope();
65 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
66 return emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
68 if (
auto localIdTy = llvm::dyn_cast<VectorType>(getLocalid().
getType()))
69 if (localIdTy.getNumElements() != 2 && localIdTy.getNumElements() != 3)
70 return emitOpError(
"localid is a vector and can be with only "
71 " 2 or 3 components, actual number is ")
72 << localIdTy.getNumElements();
82 spirv::Scope scope = getExecutionScope();
83 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
84 return emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
94 spirv::Scope scope = getExecutionScope();
95 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
96 return emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
106 spirv::Scope scope = getExecutionScope();
107 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
108 return emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
118 spirv::Scope scope = getExecutionScope();
119 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
120 return emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
125 if (
auto spirvModule = (*this)->getParentOfType<spirv::ModuleOp>())
128 if (targetEnv.getVersion() < spirv::Version::V_1_5) {
129 auto *idOp = getId().getDefiningOp();
130 if (!idOp || !isa<spirv::ConstantOp,
131 spirv::ReferenceOfOp>(idOp))
132 return emitOpError(
"id must be the result of a constant op");
142 template <
typename OpTy>
144 spirv::Scope scope = op.getExecutionScope();
145 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
146 return op.emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
148 if (op.getOperands().back().getType().isSignedInteger())
149 return op.emitOpError(
"second operand must be a singless/unsigned integer");
172 spirv::Scope scope = getExecutionScope();
173 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
174 return emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
184 return verifyGroupNonUniformArithmeticOp<GroupNonUniformFAddOp>(*
this);
192 return verifyGroupNonUniformArithmeticOp<GroupNonUniformFMaxOp>(*
this);
200 return verifyGroupNonUniformArithmeticOp<GroupNonUniformFMinOp>(*
this);
208 return verifyGroupNonUniformArithmeticOp<GroupNonUniformFMulOp>(*
this);
216 return verifyGroupNonUniformArithmeticOp<GroupNonUniformIAddOp>(*
this);
224 return verifyGroupNonUniformArithmeticOp<GroupNonUniformIMulOp>(*
this);
232 return verifyGroupNonUniformArithmeticOp<GroupNonUniformSMaxOp>(*
this);
240 return verifyGroupNonUniformArithmeticOp<GroupNonUniformSMinOp>(*
this);
248 return verifyGroupNonUniformArithmeticOp<GroupNonUniformUMaxOp>(*
this);
256 return verifyGroupNonUniformArithmeticOp<GroupNonUniformUMinOp>(*
this);
264 return verifyGroupNonUniformArithmeticOp<GroupNonUniformBitwiseAndOp>(*
this);
272 return verifyGroupNonUniformArithmeticOp<GroupNonUniformBitwiseOrOp>(*
this);
280 return verifyGroupNonUniformArithmeticOp<GroupNonUniformBitwiseXorOp>(*
this);
288 return verifyGroupNonUniformArithmeticOp<GroupNonUniformLogicalAndOp>(*
this);
296 return verifyGroupNonUniformArithmeticOp<GroupNonUniformLogicalOrOp>(*
this);
304 return verifyGroupNonUniformArithmeticOp<GroupNonUniformLogicalXorOp>(*
this);
311 template <
typename Op>
313 spirv::Scope scope = op.getExecutionScope();
314 if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
315 return op.
emitOpError(
"execution scope must be 'Workgroup' or 'Subgroup'");
static MLIRContext * getContext(OpFoldResult val)
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
This provides public APIs that all operations should have.
Operation is the basic unit of execution within MLIR.
Value getOperand(unsigned idx)
AttrClass getAttrOfType(StringAttr name)
unsigned getNumOperands()
OperationName getName()
The name of an operation is the key identifier for it.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
static LogicalResult verifyGroupNonUniformArithmeticOp(Operation *groupOp)
TargetEnvAttr lookupTargetEnvOrDefault(Operation *op)
Queries the target environment recursively from enclosing symbol table ops containing the given op or...
static LogicalResult verifyGroupNonUniformShuffleOp(OpTy op)
static LogicalResult verifyGroupOp(Op op)
LogicalResult extractValueFromConstOp(Operation *op, int32_t &value)
TargetEnvAttr getDefaultTargetEnv(MLIRContext *context)
Returns the default target environment: SPIR-V 1.0 with Shader capability and no extra extensions.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...