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