Skip to content

Commit 9ecec94

Browse files
committed
[MLIR][SPIRV] Add definition for SPV_INTEL_split_barrier ops
The [`SPV_INTEL_split_barrier` extension](https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/INTEL/SPV_INTEL_split_barrier.html) defines operations to split control barrier semantics in two operations. Add support for these operations (arrive and wait) to the dialect. Signed-off-by: Victor Perez <[email protected]>
1 parent 4981f8c commit 9ecec94

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4466,6 +4466,8 @@ def SPIRV_OC_OpAssumeTrueKHR : I32EnumAttrCase<"OpAssumeTrueKHR",
44664466
def SPIRV_OC_OpAtomicFAddEXT : I32EnumAttrCase<"OpAtomicFAddEXT", 6035>;
44674467
def SPIRV_OC_OpConvertFToBF16INTEL : I32EnumAttrCase<"OpConvertFToBF16INTEL", 6116>;
44684468
def SPIRV_OC_OpConvertBF16ToFINTEL : I32EnumAttrCase<"OpConvertBF16ToFINTEL", 6117>;
4469+
def SPIRV_OC_OpControlBarrierArriveINTEL : I32EnumAttrCase<"OpControlBarrierArriveINTEL", 6142>;
4470+
def SPIRV_OC_OpControlBarrierWaitINTEL : I32EnumAttrCase<"OpControlBarrierWaitINTEL", 6143>;
44694471
def SPIRV_OC_OpGroupIMulKHR : I32EnumAttrCase<"OpGroupIMulKHR", 6401>;
44704472
def SPIRV_OC_OpGroupFMulKHR : I32EnumAttrCase<"OpGroupFMulKHR", 6402>;
44714473

@@ -4556,7 +4558,9 @@ def SPIRV_OpcodeAttr :
45564558
SPIRV_OC_OpCooperativeMatrixLengthKHR, SPIRV_OC_OpSubgroupBlockReadINTEL,
45574559
SPIRV_OC_OpSubgroupBlockWriteINTEL, SPIRV_OC_OpAssumeTrueKHR,
45584560
SPIRV_OC_OpAtomicFAddEXT, SPIRV_OC_OpConvertFToBF16INTEL,
4559-
SPIRV_OC_OpConvertBF16ToFINTEL, SPIRV_OC_OpGroupIMulKHR,
4561+
SPIRV_OC_OpConvertBF16ToFINTEL,
4562+
SPIRV_OC_OpControlBarrierArriveINTEL, SPIRV_OC_OpControlBarrierWaitINTEL,
4563+
SPIRV_OC_OpGroupIMulKHR,
45604564
SPIRV_OC_OpGroupFMulKHR
45614565
]>;
45624566

mlir/include/mlir/Dialect/SPIRV/IR/SPIRVIntelExtOps.td

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

mlir/test/Dialect/SPIRV/IR/intel-ext-ops.mlir

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,17 @@ spirv.func @bf16_to_f32_vec_unsupported(%arg0 : vector<2xi16>) "None" {
6969
%0 = spirv.INTEL.ConvertBF16ToF %arg0 : vector<2xi16> to vector<3xf32>
7070
spirv.Return
7171
}
72+
73+
// -----
74+
75+
//===----------------------------------------------------------------------===//
76+
// spirv.INTEL.SplitBarrier
77+
//===----------------------------------------------------------------------===//
78+
79+
spirv.func @split_barrier() "None" {
80+
// CHECK: spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
81+
spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
82+
// CHECK: spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
83+
spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
84+
spirv.Return
85+
}

mlir/test/Target/SPIRV/intel-ext-ops.mlir

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,21 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Bfloat16ConversionINTEL]
2929
spirv.Return
3030
}
3131
}
32+
33+
// -----
34+
35+
//===----------------------------------------------------------------------===//
36+
// spirv.INTEL.SplitBarrier
37+
//===----------------------------------------------------------------------===//
38+
39+
// CHECK: spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [SplitBarrierINTEL], [SPV_INTEL_split_barrier]>
40+
spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [SplitBarrierINTEL], [SPV_INTEL_split_barrier]> {
41+
// CHECK-LABEL: @split_barrier
42+
spirv.func @split_barrier() "None" {
43+
// CHECK: spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
44+
spirv.INTEL.ControlBarrierArrive <Workgroup>, <Device>, <Acquire|UniformMemory>
45+
// CHECK: spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
46+
spirv.INTEL.ControlBarrierWait <Workgroup>, <Device>, <Acquire|UniformMemory>
47+
spirv.Return
48+
}
49+
}

0 commit comments

Comments
 (0)