@@ -111,6 +111,95 @@ def SPIRV_INTELConvertBF16ToFOp : SPIRV_IntelVendorOp<"ConvertBF16ToF", []> {
111
111
}
112
112
113
113
114
+ // -----
115
+
116
+ class SPIRV_IntelSplitBarrierOp<string mnemonic>
117
+ : SPIRV_IntelVendorOp<mnemonic, []> {
118
+ let availability = [
119
+ MinVersion<SPIRV_V_1_0>,
120
+ MaxVersion<SPIRV_V_1_6>,
121
+ Extension<[SPV_INTEL_split_barrier]>,
122
+ Capability<[SPIRV_C_SplitBarrierINTEL]>
123
+ ];
124
+
125
+ let arguments = (ins
126
+ SPIRV_ScopeAttr:$execution_scope,
127
+ SPIRV_ScopeAttr:$memory_scope,
128
+ SPIRV_MemorySemanticsAttr:$memory_semantics
129
+ );
130
+
131
+ let results = (outs);
132
+
133
+ let assemblyFormat = [{
134
+ $execution_scope `,` $memory_scope `,` $memory_semantics attr-dict
135
+ }];
136
+
137
+ let hasVerifier = 0;
138
+ }
139
+
140
+ def SPIRV_INTELControlBarrierArriveOp
141
+ : SPIRV_IntelSplitBarrierOp<"ControlBarrierArrive"> {
142
+ let summary = "See extension SPV_INTEL_split_barrier";
143
+
144
+ let description = [{
145
+ Indicates that an invocation has arrived at a split control barrier. This
146
+ may allow other invocations waiting on the split control barrier to continue
147
+ executing.
148
+
149
+ When `Execution` is `Workgroup` or larger, behavior is undefined unless all
150
+ invocations within `Execution` execute the same dynamic instance of this
151
+ instruction. When `Execution` is `Subgroup` or `Invocation`, the behavior of
152
+ this instruction in non-uniform control flow is defined by the client API.
153
+
154
+ If `Semantics` is not `None`, this instruction also serves as the start of a
155
+ memory barrier similar to an `OpMemoryBarrier` instruction with the same
156
+ `Memory` and `Semantics` operands. This allows atomically specifying both a
157
+ control barrier and a memory barrier (that is, without needing two
158
+ instructions). If `Semantics` is `None`, `Memory` is ignored.
159
+
160
+ #### Example:
161
+
162
+ ```mlir
163
+ spirv.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
164
+ ```
165
+ }];
166
+ }
167
+
168
+
169
+ // -----
170
+
171
+ def SPIRV_INTELControlBarrierWaitOp
172
+ : SPIRV_IntelSplitBarrierOp<"ControlBarrierWait"> {
173
+ let summary = "See extension SPV_INTEL_split_barrier";
174
+
175
+ let description = [{
176
+ Waits for other invocations of this module to arrive at a split control
177
+ barrier.
178
+
179
+ When `Execution` is `Workgroup` or larger, behavior is undefined unless all
180
+ invocations within `Execution` execute the same dynamic instance of this
181
+ instruction. When `Execution` is `Subgroup` or `Invocation`, the behavior of
182
+ this instruction in non-uniform control flow is defined by the client API.
183
+
184
+ If `Semantics` is not `None`, this instruction also serves as the end of a
185
+ memory barrier similar to an `OpMemoryBarrier` instruction with the same
186
+ `Memory` and `Semantics` operands. This ensures that memory accesses issued
187
+ before arriving at the split barrier are observed before memory accesses
188
+ issued after this instruction. This control is ensured only for memory
189
+ accesses issued by this invocation and observed by another invocation
190
+ executing within `Memory` scope. This allows atomically specifying both a
191
+ control barrier and a memory barrier (that is, without needing two
192
+ instructions). If `Semantics` is `None`, `Memory` is ignored.
193
+
194
+ #### Example:
195
+
196
+ ```mlir
197
+ spirv.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
198
+ ```
199
+ }];
200
+ }
201
+
202
+
114
203
// -----
115
204
116
205
#endif // MLIR_DIALECT_SPIRV_IR_INTEL_EXT_OPS
0 commit comments