1//===-- SPIRVCompositeOps.td - MLIR SPIR-V Composite 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 composite ops for SPIR-V dialect. It corresponds 10// to "3.32.12. Composite Instructions" of the SPIR-V spec. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef SPIRV_COMPOSITE_OPS 15#define SPIRV_COMPOSITE_OPS 16 17include "mlir/Dialect/SPIRV/SPIRVBase.td" 18include "mlir/Interfaces/SideEffectInterfaces.td" 19 20// ----- 21 22def SPV_CompositeConstructOp : SPV_Op<"CompositeConstruct", [NoSideEffect]> { 23 let summary = [{ 24 Construct a new composite object from a set of constituent objects that 25 will fully form it. 26 }]; 27 28 let description = [{ 29 Result Type must be a composite type, whose top-level 30 members/elements/components/columns have the same type as the types of 31 the operands, with one exception. The exception is that for constructing 32 a vector, the operands may also be vectors with the same component type 33 as the Result Type component type. When constructing a vector, the total 34 number of components in all the operands must equal the number of 35 components in Result Type. 36 37 Constituents will become members of a structure, or elements of an 38 array, or components of a vector, or columns of a matrix. There must be 39 exactly one Constituent for each top-level 40 member/element/component/column of the result, with one exception. The 41 exception is that for constructing a vector, a contiguous subset of the 42 scalars consumed can be represented by a vector operand instead. The 43 Constituents must appear in the order needed by the definition of the 44 type of the result. When constructing a vector, there must be at least 45 two Constituent operands. 46 47 <!-- End of AutoGen section --> 48 49 ``` 50 composite-construct-op ::= ssa-id `=` `spv.CompositeConstruct` 51 (ssa-use (`,` ssa-use)* )? `:` composite-type 52 ``` 53 54 #### Example: 55 56 ```mlir 57 %0 = spv.CompositeConstruct %1, %2, %3 : vector<3xf32> 58 ``` 59 }]; 60 61 let arguments = (ins 62 Variadic<SPV_Type>:$constituents 63 ); 64 65 let results = (outs 66 SPV_Composite:$result 67 ); 68} 69 70// ----- 71 72def SPV_CompositeExtractOp : SPV_Op<"CompositeExtract", [NoSideEffect]> { 73 let summary = "Extract a part of a composite object."; 74 75 let description = [{ 76 Result Type must be the type of object selected by the last provided 77 index. The instruction result is the extracted object. 78 79 Composite is the composite to extract from. 80 81 Indexes walk the type hierarchy, potentially down to component 82 granularity, to select the part to extract. All indexes must be in 83 bounds. All composite constituents use zero-based numbering, as 84 described by their OpType… instruction. 85 86 <!-- End of AutoGen section --> 87 88 ``` 89 composite-extract-op ::= ssa-id `=` `spv.CompositeExtract` ssa-use 90 `[` integer-literal (',' integer-literal)* `]` 91 `:` composite-type 92 ``` 93 94 #### Example: 95 96 ```mlir 97 %0 = spv.Variable : !spv.ptr<!spv.array<4x!spv.array<4xf32>>, Function> 98 %1 = spv.Load "Function" %0 ["Volatile"] : !spv.array<4x!spv.array<4xf32>> 99 %2 = spv.CompositeExtract %1[1 : i32] : !spv.array<4x!spv.array<4xf32>> 100 ``` 101 102 }]; 103 104 let arguments = (ins 105 SPV_Composite:$composite, 106 I32ArrayAttr:$indices 107 ); 108 109 let results = (outs 110 SPV_Type:$component 111 ); 112 113 let builders = [ 114 OpBuilderDAG<(ins "Value":$composite, "ArrayRef<int32_t>":$indices)> 115 ]; 116 117 let hasFolder = 1; 118} 119 120// ----- 121 122def SPV_CompositeInsertOp : SPV_Op<"CompositeInsert", [NoSideEffect]> { 123 let summary = [{ 124 Make a copy of a composite object, while modifying one part of it. 125 }]; 126 127 let description = [{ 128 Result Type must be the same type as Composite. 129 130 Object is the object to use as the modified part. 131 132 Composite is the composite to copy all but the modified part from. 133 134 Indexes walk the type hierarchy of Composite to the desired depth, 135 potentially down to component granularity, to select the part to modify. 136 All indexes must be in bounds. All composite constituents use zero-based 137 numbering, as described by their OpType… instruction. The type of the 138 part selected to modify must match the type of Object. 139 140 <!-- End of AutoGen section --> 141 142 ``` 143 composite-insert-op ::= ssa-id `=` `spv.CompositeInsert` ssa-use, ssa-use 144 `[` integer-literal (',' integer-literal)* `]` 145 `:` object-type `into` composite-type 146 ``` 147 148 #### Example: 149 150 ```mlir 151 %0 = spv.CompositeInsert %object, %composite[1 : i32] : f32 into !spv.array<4xf32> 152 ``` 153 }]; 154 155 let arguments = (ins 156 SPV_Type:$object, 157 SPV_Composite:$composite, 158 I32ArrayAttr:$indices 159 ); 160 161 let results = (outs 162 SPV_Composite:$result 163 ); 164 165 let builders = [ 166 OpBuilderDAG<(ins "Value":$object, "Value":$composite, 167 "ArrayRef<int32_t>":$indices)> 168 ]; 169} 170 171// ----- 172 173def SPV_VectorExtractDynamicOp : SPV_Op<"VectorExtractDynamic", 174 [NoSideEffect, 175 TypesMatchWith<"type of 'result' matches element type of 'vector'", 176 "vector", "result", 177 "$_self.cast<mlir::VectorType>().getElementType()">]> { 178 let summary = [{ 179 Extract a single, dynamically selected, component of a vector. 180 }]; 181 182 let description = [{ 183 Result Type must be a scalar type. 184 185 Vector must have a type OpTypeVector whose Component Type is Result 186 Type. 187 188 Index must be a scalar integer. It is interpreted as a 0-based index of 189 which component of Vector to extract. 190 191 Behavior is undefined if Index's value is less than zero or greater than 192 or equal to the number of components in Vector. 193 194 <!-- End of AutoGen section --> 195 196 ``` 197 scalar-type ::= integer-type | float-type | boolean-type 198 vector-extract-dynamic-op ::= `spv.VectorExtractDynamic ` ssa-use `[` ssa-use `]` 199 `:` `vector<` integer-literal `x` scalar-type `>` `,` 200 integer-type 201 ```mlir 202 203 #### Example: 204 205 ``` 206 %2 = spv.VectorExtractDynamic %0[%1] : vector<8xf32>, i32 207 ``` 208 }]; 209 210 let arguments = (ins 211 SPV_Vector:$vector, 212 SPV_Integer:$index 213 ); 214 215 let results = (outs 216 SPV_Scalar:$result 217 ); 218 219 let verifier = [{ return success(); }]; 220 221 let assemblyFormat = [{ 222 $vector `[` $index `]` attr-dict `:` type($vector) `,` type($index) 223 }]; 224 225} 226 227// ----- 228 229def SPV_VectorInsertDynamicOp : SPV_Op<"VectorInsertDynamic", 230 [NoSideEffect, 231 TypesMatchWith<"type of 'component' matches element type of 'vector'", 232 "vector", "component", 233 "$_self.cast<mlir::VectorType>().getElementType()">, 234 AllTypesMatch<["vector", "result"]>]> { 235 let summary = [{ 236 Make a copy of a vector, with a single, variably selected, component 237 modified. 238 }]; 239 240 let description = [{ 241 Result Type must be an OpTypeVector. 242 243 Vector must have the same type as Result Type and is the vector that the 244 non-written components are copied from. 245 246 Component is the value supplied for the component selected by Index. It 247 must have the same type as the type of components in Result Type. 248 249 Index must be a scalar integer. It is interpreted as a 0-based index of 250 which component to modify. 251 252 Behavior is undefined if Index's value is less than zero or greater than 253 or equal to the number of components in Vector. 254 255 <!-- End of AutoGen section --> 256 257 ``` 258 scalar-type ::= integer-type | float-type | boolean-type 259 vector-insert-dynamic-op ::= `spv.VectorInsertDynamic ` ssa-use `,` 260 ssa-use `[` ssa-use `]` 261 `:` `vector<` integer-literal `x` scalar-type `>` `,` 262 integer-type 263 ```mlir 264 265 #### Example: 266 267 ``` 268 %scalar = ... : f32 269 %2 = spv.VectorInsertDynamic %scalar %0[%1] : f32, vector<8xf32>, i32 270 ``` 271 }]; 272 273 let arguments = (ins 274 SPV_Vector:$vector, 275 SPV_Scalar:$component, 276 SPV_Integer:$index 277 ); 278 279 let results = (outs 280 SPV_Vector:$result 281 ); 282 283 let verifier = [{ return success(); }]; 284 285 let assemblyFormat = [{ 286 $component `,` $vector `[` $index `]` attr-dict `:` type($vector) `,` type($index) 287 }]; 288} 289 290// ----- 291 292#endif // SPIRV_COMPOSITE_OPS 293