@@ -111,6 +111,95 @@ def SPIRV_INTELConvertBF16ToFOp : SPIRV_IntelVendorOp<"ConvertBF16ToF", []> {
111111}
112112
113113
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+
114203// -----
115204
116205#endif // MLIR_DIALECT_SPIRV_IR_INTEL_EXT_OPS
0 commit comments