1//===-- SPIRVCastOps.td - MLIR SPIR-V Cast 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 cast ops for the SPIR-V dialect. It corresponds 10// to "3.32.11. Conversion Instructions" of the SPIR-V specification. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef SPIRV_CAST_OPS 15#define SPIRV_CAST_OPS 16 17include "mlir/Dialect/SPIRV/SPIRVBase.td" 18include "mlir/Interfaces/SideEffectInterfaces.td" 19 20class SPV_CastOp<string mnemonic, Type resultType, Type operandType, 21 list<OpTrait> traits = []> : 22 SPV_Op<mnemonic, 23 !listconcat(traits, 24 [NoSideEffect, SameOperandsAndResultShape])> { 25 let arguments = (ins 26 SPV_ScalarOrVectorOrCoopMatrixOf<operandType>:$operand 27 ); 28 29 let results = (outs 30 SPV_ScalarOrVectorOrCoopMatrixOf<resultType>:$result 31 ); 32 33 let parser = [{ return mlir::impl::parseCastOp(parser, result); }]; 34 let printer = [{ mlir::impl::printCastOp(this->getOperation(), p); }]; 35 let verifier = [{ return verifyCastOp(this->getOperation()); }]; 36} 37 38// ----- 39 40def SPV_BitcastOp : SPV_Op<"Bitcast", [NoSideEffect]> { 41 let summary = "Bit pattern-preserving type conversion."; 42 43 let description = [{ 44 Result Type must be an OpTypePointer, or a scalar or vector of 45 numerical-type. 46 47 Operand must have a type of OpTypePointer, or a scalar or vector of 48 numerical-type. It must be a different type than Result Type. 49 50 If either Result Type or Operand is a pointer, the other must be a 51 pointer (diverges from the SPIR-V spec). 52 53 If Result Type has a different number of components than Operand, the 54 total number of bits in Result Type must equal the total number of bits 55 in Operand. Let L be the type, either Result Type or Operand’s type, 56 that has the larger number of components. Let S be the other type, with 57 the smaller number of components. The number of components in L must be 58 an integer multiple of the number of components in S. The first 59 component (that is, the only or lowest-numbered component) of S maps to 60 the first components of L, and so on, up to the last component of S 61 mapping to the last components of L. Within this mapping, any single 62 component of S (mapping to multiple components of L) maps its lower- 63 ordered bits to the lower-numbered components of L. 64 65 <!-- End of AutoGen section --> 66 67 ``` 68 bitcast-op ::= ssa-id `=` `spv.Bitcast` ssa-use 69 `:` operand-type `to` result-type 70 ``` 71 72 #### Example: 73 74 ```mlir 75 %1 = spv.Bitcast %0 : f32 to i32 76 %1 = spv.Bitcast %0 : vector<2xf32> to i64 77 %1 = spv.Bitcast %0 : !spv.ptr<f32, Function> to !spv.ptr<i32, Function> 78 ``` 79 }]; 80 81 let arguments = (ins 82 SPV_ScalarOrVectorOrPtr:$operand 83 ); 84 85 let results = (outs 86 SPV_ScalarOrVectorOrPtr:$result 87 ); 88 89 let parser = [{ return mlir::impl::parseCastOp(parser, result); }]; 90 let printer = [{ mlir::impl::printCastOp(this->getOperation(), p); }]; 91 92 let hasCanonicalizer = 1; 93} 94 95// ----- 96 97def SPV_ConvertFToSOp : SPV_CastOp<"ConvertFToS", SPV_Integer, SPV_Float, []> { 98 let summary = [{ 99 Convert value numerically from floating point to signed integer, with 100 round toward 0.0. 101 }]; 102 103 let description = [{ 104 Result Type must be a scalar or vector of integer type. 105 106 Float Value must be a scalar or vector of floating-point type. It must 107 have the same number of components as Result Type. 108 109 Results are computed per component. 110 111 <!-- End of AutoGen section --> 112 113 ``` 114 convert-f-to-s-op ::= ssa-id `=` `spv.ConvertFToSOp` ssa-use 115 `:` operand-type `to` result-type 116 ``` 117 118 #### Example: 119 120 ```mlir 121 %1 = spv.ConvertFToS %0 : f32 to i32 122 %3 = spv.ConvertFToS %2 : vector<3xf32> to vector<3xi32> 123 ``` 124 }]; 125 126 let verifier = [{ return verifyCastOp(this->getOperation(), false, true); }]; 127} 128 129// ----- 130 131def SPV_ConvertFToUOp : SPV_CastOp<"ConvertFToU", SPV_Integer, SPV_Float, []> { 132 let summary = [{ 133 Convert value numerically from floating point to unsigned integer, with 134 round toward 0.0. 135 }]; 136 137 let description = [{ 138 Result Type must be a scalar or vector of integer type, whose Signedness 139 operand is 0. 140 141 Float Value must be a scalar or vector of floating-point type. It must 142 have the same number of components as Result Type. 143 144 Results are computed per component. 145 146 <!-- End of AutoGen section --> 147 148 ``` 149 convert-f-to-u-op ::= ssa-id `=` `spv.ConvertFToUOp` ssa-use 150 `:` operand-type `to` result-type 151 ``` 152 153 #### Example: 154 155 ```mlir 156 %1 = spv.ConvertFToU %0 : f32 to i32 157 %3 = spv.ConvertFToU %2 : vector<3xf32> to vector<3xi32> 158 ``` 159 }]; 160 161 let verifier = [{ return verifyCastOp(this->getOperation(), false, true); }]; 162} 163 164// ----- 165 166def SPV_ConvertSToFOp : SPV_CastOp<"ConvertSToF", SPV_Float, SPV_Integer, []> { 167 let summary = [{ 168 Convert value numerically from signed integer to floating point. 169 }]; 170 171 let description = [{ 172 Result Type must be a scalar or vector of floating-point type. 173 174 Signed Value must be a scalar or vector of integer type. It must have 175 the same number of components as Result Type. 176 177 Results are computed per component. 178 179 <!-- End of AutoGen section --> 180 181 ``` 182 convert-s-to-f-op ::= ssa-id `=` `spv.ConvertSToFOp` ssa-use 183 `:` operand-type `to` result-type 184 ``` 185 186 #### Example: 187 188 ```mlir 189 %1 = spv.ConvertSToF %0 : i32 to f32 190 %3 = spv.ConvertSToF %2 : vector<3xi32> to vector<3xf32> 191 ``` 192 }]; 193 194 let verifier = [{ return verifyCastOp(this->getOperation(), false, true); }]; 195} 196 197// ----- 198 199def SPV_ConvertUToFOp : SPV_CastOp<"ConvertUToF", SPV_Float, SPV_Integer, []> { 200 let summary = [{ 201 Convert value numerically from unsigned integer to floating point. 202 }]; 203 204 let description = [{ 205 Result Type must be a scalar or vector of floating-point type. 206 207 Unsigned Value must be a scalar or vector of integer type. It must have 208 the same number of components as Result Type. 209 210 Results are computed per component. 211 212 <!-- End of AutoGen section --> 213 214 ``` 215 convert-u-to-f-op ::= ssa-id `=` `spv.ConvertUToFOp` ssa-use 216 `:` operand-type `to` result-type 217 ``` 218 219 #### Example: 220 221 ```mlir 222 %1 = spv.ConvertUToF %0 : i32 to f32 223 %3 = spv.ConvertUToF %2 : vector<3xi32> to vector<3xf32> 224 ``` 225 }]; 226 227 let verifier = [{ return verifyCastOp(this->getOperation(), false, true); }]; 228} 229 230// ----- 231 232def SPV_FConvertOp : SPV_CastOp<"FConvert", SPV_Float, SPV_Float, []> { 233 let summary = [{ 234 Convert value numerically from one floating-point width to another 235 width. 236 }]; 237 238 let description = [{ 239 Result Type must be a scalar or vector of floating-point type. 240 241 Float Value must be a scalar or vector of floating-point type. It must 242 have the same number of components as Result Type. The component width 243 cannot equal the component width in Result Type. 244 245 Results are computed per component. 246 247 <!-- End of AutoGen section --> 248 249 ``` 250 f-convert-op ::= ssa-id `=` `spv.FConvertOp` ssa-use 251 `:` operand-type `to` result-type 252 ``` 253 254 #### Example: 255 256 ```mlir 257 %1 = spv.FConvertOp %0 : f32 to f64 258 %3 = spv.FConvertOp %2 : vector<3xf32> to vector<3xf64> 259 ``` 260 }]; 261 262 let verifier = [{ return verifyCastOp(this->getOperation(), false); }]; 263} 264 265// ----- 266 267def SPV_SConvertOp : SPV_CastOp<"SConvert", SPV_Integer, SPV_Integer, []> { 268 let summary = [{ 269 Convert signed width. This is either a truncate or a sign extend. 270 }]; 271 272 let description = [{ 273 Result Type must be a scalar or vector of integer type. 274 275 Signed Value must be a scalar or vector of integer type. It must have 276 the same number of components as Result Type. The component width 277 cannot equal the component width in Result Type. 278 279 Results are computed per component. 280 281 <!-- End of AutoGen section --> 282 283 ``` 284 s-convert-op ::= ssa-id `=` `spv.SConvertOp` ssa-use 285 `:` operand-type `to` result-type 286 ``` 287 288 #### Example: 289 290 ```mlir 291 %1 = spv.SConvertOp %0 : i32 to i64 292 %3 = spv.SConvertOp %2 : vector<3xi32> to vector<3xi64> 293 ``` 294 }]; 295 296 let verifier = [{ return verifyCastOp(this->getOperation(), false); }]; 297} 298 299// ----- 300 301def SPV_UConvertOp : SPV_CastOp<"UConvert", SPV_Integer, SPV_Integer, []> { 302 let summary = [{ 303 Convert unsigned width. This is either a truncate or a zero extend. 304 }]; 305 306 let description = [{ 307 Result Type must be a scalar or vector of integer type, whose Signedness 308 operand is 0. 309 310 Unsigned Value must be a scalar or vector of integer type. It must have 311 the same number of components as Result Type. The component width 312 cannot equal the component width in Result Type. 313 314 Results are computed per component. 315 316 <!-- End of AutoGen section --> 317 318 ``` 319 u-convert-op ::= ssa-id `=` `spv.UConvertOp` ssa-use 320 `:` operand-type `to` result-type 321 ``` 322 323 #### Example: 324 325 ```mlir 326 %1 = spv.UConvertOp %0 : i32 to i64 327 %3 = spv.UConvertOp %2 : vector<3xi32> to vector<3xi64> 328 ``` 329 }]; 330 331 let verifier = [{ return verifyCastOp(this->getOperation(), false); }]; 332} 333 334#endif // SPIRV_CAST_OPS 335