• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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