• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//===-- SPIRVArithmeticOps.td - MLIR SPIR-V Arithmetic 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 arithmetic ops for the SPIR-V dialect. It corresponds
10// to "3.32.13. Arithmetic Instructions" of the SPIR-V specification.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef SPIRV_ARITHMETIC_OPS
15#define SPIRV_ARITHMETIC_OPS
16
17include "mlir/Dialect/SPIRV/SPIRVBase.td"
18include "mlir/Interfaces/SideEffectInterfaces.td"
19
20class SPV_ArithmeticBinaryOp<string mnemonic, Type type,
21                       list<OpTrait> traits = []> :
22      // Operands type same as result type.
23      SPV_BinaryOp<mnemonic, type, type,
24                   !listconcat(traits,
25                               [NoSideEffect, SameOperandsAndResultType])> {
26  // In addition to normal types arithmetic instructions can support cooperative
27  // matrix.
28  let arguments = (ins
29    SPV_ScalarOrVectorOrCoopMatrixOf<type>:$operand1,
30    SPV_ScalarOrVectorOrCoopMatrixOf<type>:$operand2
31  );
32
33  let results = (outs
34    SPV_ScalarOrVectorOrCoopMatrixOf<type>:$result
35  );
36}
37
38class SPV_ArithmeticUnaryOp<string mnemonic, Type type,
39                            list<OpTrait> traits = []> :
40      // Operand type same as result type.
41      SPV_UnaryOp<mnemonic, type, type,
42                   !listconcat(traits,
43                               [NoSideEffect, SameOperandsAndResultType])>;
44
45// -----
46
47def SPV_FAddOp : SPV_ArithmeticBinaryOp<"FAdd", SPV_Float, [Commutative]> {
48  let summary = "Floating-point addition of Operand 1 and Operand 2.";
49
50  let description = [{
51    Result Type must be a scalar or vector of floating-point type.
52
53     The types of Operand 1 and Operand 2 both must be the same as Result
54    Type.
55
56     Results are computed per component.
57
58    <!-- End of AutoGen section -->
59    ```
60    float-scalar-vector-type ::= float-type |
61                                 `vector<` integer-literal `x` float-type `>`
62    fadd-op ::= ssa-id `=` `spv.FAdd` ssa-use, ssa-use
63                          `:` float-scalar-vector-type
64    ```
65    #### Example:
66
67    ```mlir
68    %4 = spv.FAdd %0, %1 : f32
69    %5 = spv.FAdd %2, %3 : vector<4xf32>
70    ```
71  }];
72}
73
74// -----
75
76def SPV_FDivOp : SPV_ArithmeticBinaryOp<"FDiv", SPV_Float, []> {
77  let summary = "Floating-point division of Operand 1 divided by Operand 2.";
78
79  let description = [{
80    Result Type must be a scalar or vector of floating-point type.
81
82     The types of Operand 1 and Operand 2 both must be the same as Result
83    Type.
84
85     Results are computed per component.  The resulting value is undefined
86    if Operand 2 is 0.
87
88    <!-- End of AutoGen section -->
89    ```
90    float-scalar-vector-type ::= float-type |
91                                 `vector<` integer-literal `x` float-type `>`
92    fdiv-op ::= ssa-id `=` `spv.FDiv` ssa-use, ssa-use
93                          `:` float-scalar-vector-type
94    ```
95
96    #### Example:
97
98    ```mlir
99    %4 = spv.FDiv %0, %1 : f32
100    %5 = spv.FDiv %2, %3 : vector<4xf32>
101    ```
102  }];
103}
104
105// -----
106
107def SPV_FModOp : SPV_ArithmeticBinaryOp<"FMod", SPV_Float, []> {
108  let summary = [{
109    The floating-point remainder whose sign matches the sign of Operand 2.
110  }];
111
112  let description = [{
113    Result Type must be a scalar or vector of floating-point type.
114
115     The types of Operand 1 and Operand 2 both must be the same as Result
116    Type.
117
118     Results are computed per component.  The resulting value is undefined
119    if Operand 2 is 0.  Otherwise, the result is the remainder r of Operand
120    1 divided by Operand 2 where if r ≠ 0, the sign of r is the same as the
121    sign of Operand 2.
122
123    <!-- End of AutoGen section -->
124    ```
125    float-scalar-vector-type ::= float-type |
126                                 `vector<` integer-literal `x` float-type `>`
127    fmod-op ::= ssa-id `=` `spv.FMod` ssa-use, ssa-use
128                          `:` float-scalar-vector-type
129    ```
130    #### Example:
131
132    ```mlir
133    %4 = spv.FMod %0, %1 : f32
134    %5 = spv.FMod %2, %3 : vector<4xf32>
135    ```
136  }];
137}
138
139// -----
140
141def SPV_FMulOp : SPV_ArithmeticBinaryOp<"FMul", SPV_Float, [Commutative]> {
142  let summary = "Floating-point multiplication of Operand 1 and Operand 2.";
143
144  let description = [{
145    Result Type must be a scalar or vector of floating-point type.
146
147     The types of Operand 1 and Operand 2 both must be the same as Result
148    Type.
149
150     Results are computed per component.
151
152    <!-- End of AutoGen section -->
153
154    ```
155    float-scalar-vector-type ::= float-type |
156                                 `vector<` integer-literal `x` float-type `>`
157    fmul-op ::= `spv.FMul` ssa-use, ssa-use
158                          `:` float-scalar-vector-type
159    ```
160
161    #### Example:
162
163    ```mlir
164    %4 = spv.FMul %0, %1 : f32
165    %5 = spv.FMul %2, %3 : vector<4xf32>
166    ```
167  }];
168}
169
170// -----
171
172def SPV_FNegateOp : SPV_ArithmeticUnaryOp<"FNegate", SPV_Float, []> {
173  let summary = [{
174    Inverts the sign bit of Operand. (Note, however, that OpFNegate is still
175    considered a floating-point instruction, and so is subject to the
176    general floating-point rules regarding, for example, subnormals and NaN
177    propagation).
178  }];
179
180  let description = [{
181    Result Type must be a scalar or vector of floating-point type.
182
183     The type of Operand must be the same as Result Type.
184
185     Results are computed per component.
186
187    <!-- End of AutoGen section -->
188
189    ```
190    float-scalar-vector-type ::= float-type |
191                                 `vector<` integer-literal `x` float-type `>`
192    fmul-op ::= `spv.FNegate` ssa-use `:` float-scalar-vector-type
193    ```
194
195    #### Example:
196
197    ```mlir
198    %1 = spv.FNegate %0 : f32
199    %3 = spv.FNegate %2 : vector<4xf32>
200    ```
201  }];
202}
203
204// -----
205
206def SPV_FRemOp : SPV_ArithmeticBinaryOp<"FRem", SPV_Float, []> {
207  let summary = [{
208    The floating-point remainder whose sign matches the sign of Operand 1.
209  }];
210
211  let description = [{
212    Result Type must be a scalar or vector of floating-point type.
213
214     The types of Operand 1 and Operand 2 both must be the same as Result
215    Type.
216
217     Results are computed per component.  The resulting value is undefined
218    if Operand 2 is 0.  Otherwise, the result is the remainder r of Operand
219    1 divided by Operand 2 where if r ≠ 0, the sign of r is the same as the
220    sign of Operand 1.
221
222    <!-- End of AutoGen section -->
223    ```
224    float-scalar-vector-type ::= float-type |
225                                 `vector<` integer-literal `x` float-type `>`
226    frem-op ::= ssa-id `=` `spv.FRemOp` ssa-use, ssa-use
227                          `:` float-scalar-vector-type
228    ```
229
230    #### Example:
231
232    ```mlir
233    %4 = spv.FRemOp %0, %1 : f32
234    %5 = spv.FRemOp %2, %3 : vector<4xf32>
235    ```
236  }];
237}
238
239// -----
240
241def SPV_FSubOp : SPV_ArithmeticBinaryOp<"FSub", SPV_Float, []> {
242  let summary = "Floating-point subtraction of Operand 2 from Operand 1.";
243
244  let description = [{
245    Result Type must be a scalar or vector of floating-point type.
246
247     The types of Operand 1 and Operand 2 both must be the same as Result
248    Type.
249
250     Results are computed per component.
251
252    <!-- End of AutoGen section -->
253    ```
254    float-scalar-vector-type ::= float-type |
255                                 `vector<` integer-literal `x` float-type `>`
256    fsub-op ::= ssa-id `=` `spv.FRemOp` ssa-use, ssa-use
257                          `:` float-scalar-vector-type
258    ```
259
260    #### Example:
261
262    ```mlir
263    %4 = spv.FRemOp %0, %1 : f32
264    %5 = spv.FRemOp %2, %3 : vector<4xf32>
265    ```
266  }];
267}
268
269// -----
270
271def SPV_IAddOp : SPV_ArithmeticBinaryOp<"IAdd", SPV_Integer, [Commutative]> {
272  let summary = "Integer addition of Operand 1 and Operand 2.";
273
274  let description = [{
275    Result Type must be a scalar or vector of integer type.
276
277     The type of Operand 1 and Operand 2  must be a scalar or vector of
278    integer type.  They must have the same number of components as Result
279    Type. They must have the same component width as Result Type.
280
281    The resulting value will equal the low-order N bits of the correct
282    result R, where N is the component width and R is computed with enough
283    precision to avoid overflow and underflow.
284
285     Results are computed per component.
286
287    <!-- End of AutoGen section -->
288    ```
289    integer-scalar-vector-type ::= integer-type |
290                                 `vector<` integer-literal `x` integer-type `>`
291    iadd-op ::= ssa-id `=` `spv.IAdd` ssa-use, ssa-use
292                          `:` integer-scalar-vector-type
293    ```
294
295    #### Example:
296
297    ```mlir
298    %4 = spv.IAdd %0, %1 : i32
299    %5 = spv.IAdd %2, %3 : vector<4xi32>
300
301    ```
302  }];
303
304  let hasFolder = 1;
305}
306
307// -----
308
309def SPV_IMulOp : SPV_ArithmeticBinaryOp<"IMul", SPV_Integer, [Commutative]> {
310  let summary = "Integer multiplication of Operand 1 and Operand 2.";
311
312  let description = [{
313    Result Type must be a scalar or vector of integer type.
314
315     The type of Operand 1 and Operand 2  must be a scalar or vector of
316    integer type.  They must have the same number of components as Result
317    Type. They must have the same component width as Result Type.
318
319    The resulting value will equal the low-order N bits of the correct
320    result R, where N is the component width and R is computed with enough
321    precision to avoid overflow and underflow.
322
323     Results are computed per component.
324
325    <!-- End of AutoGen section -->
326    ```
327    integer-scalar-vector-type ::= integer-type |
328                                 `vector<` integer-literal `x` integer-type `>`
329    imul-op ::= ssa-id `=` `spv.IMul` ssa-use, ssa-use
330                          `:` integer-scalar-vector-type
331    ```
332
333    #### Example:
334
335    ```mlir
336    %4 = spv.IMul %0, %1 : i32
337    %5 = spv.IMul %2, %3 : vector<4xi32>
338
339    ```
340  }];
341
342  let hasFolder = 1;
343}
344
345// -----
346
347def SPV_ISubOp : SPV_ArithmeticBinaryOp<"ISub", SPV_Integer, []> {
348  let summary = "Integer subtraction of Operand 2 from Operand 1.";
349
350  let description = [{
351    Result Type must be a scalar or vector of integer type.
352
353     The type of Operand 1 and Operand 2  must be a scalar or vector of
354    integer type.  They must have the same number of components as Result
355    Type. They must have the same component width as Result Type.
356
357    The resulting value will equal the low-order N bits of the correct
358    result R, where N is the component width and R is computed with enough
359    precision to avoid overflow and underflow.
360
361     Results are computed per component.
362
363    <!-- End of AutoGen section -->
364    ```
365    integer-scalar-vector-type ::= integer-type |
366                                 `vector<` integer-literal `x` integer-type `>`
367    isub-op ::= `spv.ISub` ssa-use, ssa-use
368                          `:` integer-scalar-vector-type
369    ```
370
371    #### Example:
372
373    ```mlir
374    %4 = spv.ISub %0, %1 : i32
375    %5 = spv.ISub %2, %3 : vector<4xi32>
376
377    ```
378  }];
379
380  let hasFolder = 1;
381}
382
383// -----
384
385def SPV_SDivOp : SPV_ArithmeticBinaryOp<"SDiv", SPV_Integer, []> {
386  let summary = "Signed-integer division of Operand 1 divided by Operand 2.";
387
388  let description = [{
389    Result Type must be a scalar or vector of integer type.
390
391     The type of Operand 1 and Operand 2  must be a scalar or vector of
392    integer type.  They must have the same number of components as Result
393    Type. They must have the same component width as Result Type.
394
395     Results are computed per component.  The resulting value is undefined
396    if Operand 2 is 0.
397
398    <!-- End of AutoGen section -->
399    ```
400    integer-scalar-vector-type ::= integer-type |
401                                 `vector<` integer-literal `x` integer-type `>`
402    sdiv-op ::= ssa-id `=` `spv.SDiv` ssa-use, ssa-use
403                           `:` integer-scalar-vector-type
404    ```
405
406    #### Example:
407
408    ```mlir
409    %4 = spv.SDiv %0, %1 : i32
410    %5 = spv.SDiv %2, %3 : vector<4xi32>
411
412    ```
413  }];
414}
415
416// -----
417
418def SPV_SModOp : SPV_ArithmeticBinaryOp<"SMod", SPV_Integer, []> {
419  let summary = [{
420    Signed remainder operation for the remainder whose sign matches the sign
421    of Operand 2.
422  }];
423
424  let description = [{
425    Result Type must be a scalar or vector of integer type.
426
427     The type of Operand 1 and Operand 2  must be a scalar or vector of
428    integer type.  They must have the same number of components as Result
429    Type. They must have the same component width as Result Type.
430
431     Results are computed per component.  The resulting value is undefined
432    if Operand 2 is 0.  Otherwise, the result is the remainder r of Operand
433    1 divided by Operand 2 where if r ≠ 0, the sign of r is the same as the
434    sign of Operand 2.
435
436    <!-- End of AutoGen section -->
437    ```
438    integer-scalar-vector-type ::= integer-type |
439                                 `vector<` integer-literal `x` integer-type `>`
440    smod-op ::= ssa-id `=` `spv.SMod` ssa-use, ssa-use
441                           `:` integer-scalar-vector-type
442    ```
443    #### Example:
444
445    ```mlir
446    %4 = spv.SMod %0, %1 : i32
447    %5 = spv.SMod %2, %3 : vector<4xi32>
448
449    ```
450  }];
451}
452
453// -----
454
455def SPV_SNegateOp : SPV_ArithmeticUnaryOp<"SNegate", SPV_Integer, []> {
456  let summary = "Signed-integer subtract of Operand from zero.";
457
458  let description = [{
459    Result Type must be a scalar or vector of integer type.
460
461    Operand’s type  must be a scalar or vector of integer type.  It must
462    have the same number of components as Result Type.  The component width
463    must equal the component width in Result Type.
464
465     Results are computed per component.
466
467    <!-- End of AutoGen section -->
468
469    #### Example:
470
471    ```mlir
472    %1 = spv.SNegate %0 : i32
473    %3 = spv.SNegate %2 : vector<4xi32>
474    ```
475  }];
476}
477
478// -----
479
480def SPV_SRemOp : SPV_ArithmeticBinaryOp<"SRem", SPV_Integer, []> {
481  let summary = [{
482    Signed remainder operation for the remainder whose sign matches the sign
483    of Operand 1.
484  }];
485
486  let description = [{
487    Result Type must be a scalar or vector of integer type.
488
489     The type of Operand 1 and Operand 2  must be a scalar or vector of
490    integer type.  They must have the same number of components as Result
491    Type. They must have the same component width as Result Type.
492
493     Results are computed per component.  The resulting value is undefined
494    if Operand 2 is 0.  Otherwise, the result is the remainder r of Operand
495    1 divided by Operand 2 where if r ≠ 0, the sign of r is the same as the
496    sign of Operand 1.
497
498    <!-- End of AutoGen section -->
499    ```
500    integer-scalar-vector-type ::= integer-type |
501                                 `vector<` integer-literal `x` integer-type `>`
502    srem-op ::= ssa-id `=` `spv.SRem` ssa-use, ssa-use
503                           `:` integer-scalar-vector-type
504    ```
505    #### Example:
506
507    ```mlir
508    %4 = spv.SRem %0, %1 : i32
509    %5 = spv.SRem %2, %3 : vector<4xi32>
510
511    ```
512  }];
513}
514
515// -----
516
517def SPV_UDivOp : SPV_ArithmeticBinaryOp<"UDiv", SPV_Integer, []> {
518  let summary = "Unsigned-integer division of Operand 1 divided by Operand 2.";
519
520  let description = [{
521    Result Type must be a scalar or vector of integer type, whose Signedness
522    operand is 0.
523
524     The types of Operand 1 and Operand 2 both must be the same as Result
525    Type.
526
527     Results are computed per component.  The resulting value is undefined
528    if Operand 2 is 0.
529
530    <!-- End of AutoGen section -->
531    ```
532    integer-scalar-vector-type ::= integer-type |
533                                 `vector<` integer-literal `x` integer-type `>`
534    udiv-op ::= ssa-id `=` `spv.UDiv` ssa-use, ssa-use
535                           `:` integer-scalar-vector-type
536    ```
537    #### Example:
538
539    ```mlir
540    %4 = spv.UDiv %0, %1 : i32
541    %5 = spv.UDiv %2, %3 : vector<4xi32>
542
543    ```
544  }];
545}
546
547// -----
548
549def SPV_UModOp : SPV_ArithmeticBinaryOp<"UMod", SPV_Integer> {
550  let summary = "Unsigned modulo operation of Operand 1 modulo Operand 2.";
551
552  let description = [{
553    Result Type must be a scalar or vector of integer type, whose Signedness
554    operand is 0.
555
556     The types of Operand 1 and Operand 2 both must be the same as Result
557    Type.
558
559     Results are computed per component.  The resulting value is undefined
560    if Operand 2 is 0.
561
562    <!-- End of AutoGen section -->
563    ```
564    integer-scalar-vector-type ::= integer-type |
565                                 `vector<` integer-literal `x` integer-type `>`
566    umod-op ::= ssa-id `=` `spv.UMod` ssa-use, ssa-use
567                           `:` integer-scalar-vector-type
568    ```
569    #### Example:
570
571    ```mlir
572    %4 = spv.UMod %0, %1 : i32
573    %5 = spv.UMod %2, %3 : vector<4xi32>
574
575    ```
576  }];
577}
578
579#endif // SPIRV_ARITHMETIC_OPS
580