• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//===-- SPIRVGroupOps.td - MLIR SPIR-V (Sub)Group Ops ------*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains group and subgroup ops for the SPIR-V dialect. It
10// corresponds to "3.32.21. Group and Subgroup Instructions" of the SPIR-V
11// specification.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef SPIRV_GROUP_OPS
16#define SPIRV_GROUP_OPS
17
18// -----
19
20def SPV_GroupBroadcastOp : SPV_Op<"GroupBroadcast",
21  [NoSideEffect, AllTypesMatch<["value", "result"]>]> {
22  let summary = [{
23    Return the Value of the invocation identified by the local id LocalId to
24    all invocations in the group.
25  }];
26
27  let description = [{
28    All invocations of this module within Execution must reach this point of
29    execution.
30
31    Behavior is undefined if this instruction is used in control flow that
32    is non-uniform within Execution.
33
34    Result Type  must be a scalar or vector of floating-point type, integer
35    type, or Boolean type.
36
37    Execution must be Workgroup or Subgroup Scope.
38
39     The type of Value must be the same as Result Type.
40
41    LocalId must be an integer datatype. It can be a scalar, or a vector
42    with 2 components or a vector with 3 components. LocalId must be the
43    same for all invocations in the group.
44
45    <!-- End of AutoGen section -->
46
47    ```
48    scope ::= `"Workgroup"` | `"Subgroup"`
49    integer-float-scalar-vector-type ::= integer-type | float-type |
50                               `vector<` integer-literal `x` integer-type `>` |
51                               `vector<` integer-literal `x` float-type `>`
52    localid-type ::= integer-type |
53                   `vector<` integer-literal `x` integer-type `>`
54    group-broadcast-op ::= ssa-id `=` `spv.GroupBroadcast` scope ssa_use,
55                   ssa_use `:` integer-float-scalar-vector-type `,` localid-type
56    ```mlir
57
58    #### Example:
59
60    ```
61    %scalar_value = ... : f32
62    %vector_value = ... : vector<4xf32>
63    %scalar_localid = ... : i32
64    %vector_localid = ... : vector<3xi32>
65    %0 = spv.GroupBroadcast "Subgroup" %scalar_value, %scalar_localid : f32, i32
66    %1 = spv.GroupBroadcast "Workgroup" %vector_value, %vector_localid :
67      vector<4xf32>, vector<3xi32>
68    ```
69  }];
70
71  let availability = [
72    MinVersion<SPV_V_1_0>,
73    MaxVersion<SPV_V_1_5>,
74    Extension<[]>,
75    Capability<[SPV_C_Groups]>
76  ];
77
78  let arguments = (ins
79    SPV_ScopeAttr:$execution_scope,
80    SPV_Type:$value,
81    SPV_ScalarOrVectorOf<SPV_Integer>:$localid
82  );
83
84  let results = (outs
85    SPV_Type:$result
86  );
87
88  let assemblyFormat = [{
89    $execution_scope operands attr-dict `:` type($value) `,` type($localid)
90  }];
91}
92
93// -----
94
95def SPV_SubgroupBallotKHROp : SPV_Op<"SubgroupBallotKHR", []> {
96  let summary = "See extension SPV_KHR_shader_ballot";
97
98  let description = [{
99    Computes a bitfield value combining the Predicate value from all invocations
100    in the current Subgroup that execute the same dynamic instance of this
101    instruction. The bit is set to one if the corresponding invocation is active
102    and the predicate is evaluated to true; otherwise, it is set to zero.
103
104    Predicate must be a Boolean type.
105
106    Result Type must be a 4 component vector of 32 bit integer types.
107
108    Result is a set of bitfields where the first invocation is represented in bit
109    0 of the first vector component and the last (up to SubgroupSize) is the
110    higher bit number of the last bitmask needed to represent all bits of the
111    subgroup invocations.
112
113    <!-- End of AutoGen section -->
114
115    ```
116    subgroup-ballot-op ::= ssa-id `=` `spv.SubgroupBallotKHR`
117                                ssa-use `:` `vector` `<` 4 `x` `i32` `>`
118    ```
119
120    #### Example:
121
122    ```mlir
123    %0 = spv.SubgroupBallotKHR %predicate : vector<4xi32>
124    ```
125  }];
126
127  let availability = [
128    MinVersion<SPV_V_1_0>,
129    MaxVersion<SPV_V_1_5>,
130    Extension<[SPV_KHR_shader_ballot]>,
131    Capability<[SPV_C_SubgroupBallotKHR]>
132  ];
133
134  let arguments = (ins
135    SPV_Bool:$predicate
136  );
137
138  let results = (outs
139    SPV_Int32Vec4:$result
140  );
141
142  let verifier = [{ return success(); }];
143
144  let assemblyFormat = "$predicate attr-dict `:` type($result)";
145}
146
147// -----
148
149def SPV_SubgroupBlockReadINTELOp : SPV_Op<"SubgroupBlockReadINTEL", []> {
150  let summary = "See extension SPV_INTEL_subgroups";
151
152  let description = [{
153    Reads one or more components of Result data for each invocation in the
154    subgroup from the specified Ptr as a block operation.
155
156    The data is read strided, so the first value read is:
157    Ptr[ SubgroupLocalInvocationId ]
158
159    and the second value read is:
160    Ptr[ SubgroupLocalInvocationId + SubgroupMaxSize ]
161    etc.
162
163    Result Type may be a scalar or vector type, and its component type must be
164    equal to the type pointed to by Ptr.
165
166    The type of Ptr must be a pointer type, and must point to a scalar type.
167
168    <!-- End of AutoGen section -->
169
170    ```
171    subgroup-block-read-INTEL-op ::= ssa-id `=` `spv.SubgroupBlockReadINTEL`
172                                storage-class ssa_use `:` spirv-element-type
173    ```mlir
174
175    #### Example:
176
177    ```
178    %0 = spv.SubgroupBlockReadINTEL "StorageBuffer" %ptr : i32
179    ```
180  }];
181
182  let availability = [
183    MinVersion<SPV_V_1_0>,
184    MaxVersion<SPV_V_1_5>,
185    Extension<[SPV_INTEL_subgroups]>,
186    Capability<[SPV_C_SubgroupBufferBlockIOINTEL]>
187  ];
188
189  let arguments = (ins
190    SPV_AnyPtr:$ptr
191  );
192
193  let results = (outs
194    SPV_Type:$value
195  );
196}
197
198// -----
199
200def SPV_SubgroupBlockWriteINTELOp : SPV_Op<"SubgroupBlockWriteINTEL", []> {
201  let summary = "See extension SPV_INTEL_subgroups";
202
203  let description = [{
204    Writes one or more components of Data for each invocation in the subgroup
205    from the specified Ptr as a block operation.
206
207    The data is written strided, so the first value is written to:
208    Ptr[ SubgroupLocalInvocationId ]
209
210    and the second value written is:
211    Ptr[ SubgroupLocalInvocationId + SubgroupMaxSize ]
212    etc.
213
214    The type of Ptr must be a pointer type, and must point to a scalar type.
215
216    The component type of Data must be equal to the type pointed to by Ptr.
217
218    <!-- End of AutoGen section -->
219
220    ```
221    subgroup-block-write-INTEL-op ::= ssa-id `=` `spv.SubgroupBlockWriteINTEL`
222                      storage-class ssa_use `,` ssa-use `:` spirv-element-type
223    ```mlir
224
225    #### Example:
226
227    ```
228    spv.SubgroupBlockWriteINTEL "StorageBuffer" %ptr, %value : i32
229    ```
230  }];
231
232  let availability = [
233    MinVersion<SPV_V_1_0>,
234    MaxVersion<SPV_V_1_5>,
235    Extension<[SPV_INTEL_subgroups]>,
236    Capability<[SPV_C_SubgroupBufferBlockIOINTEL]>
237  ];
238
239  let arguments = (ins
240    SPV_AnyPtr:$ptr,
241    SPV_Type:$value
242  );
243
244  let results = (outs);
245}
246
247// -----
248
249#endif // SPIRV_GROUP_OPS
250