xref: /llvm-project/mlir/include/mlir/Dialect/Math/IR/MathOps.td (revision 990837f91de329b1e045f90fadb86ffe21611d9a)
1//===- MathOps.td - Math op definitions --------------------*- 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#ifndef MATH_OPS
10#define MATH_OPS
11
12include "mlir/Dialect/Arith/IR/ArithBase.td"
13include "mlir/Dialect/Arith/IR/ArithOpsInterfaces.td"
14include "mlir/Dialect/Math/IR/MathBase.td"
15include "mlir/Interfaces/InferTypeOpInterface.td"
16include "mlir/Interfaces/VectorInterfaces.td"
17include "mlir/Interfaces/SideEffectInterfaces.td"
18
19// Base class for math dialect ops. Ops in this dialect have no side effects and
20// can be applied element-wise to vectors and tensors.
21class Math_Op<string mnemonic, list<Trait> traits = []> :
22    Op<Math_Dialect, mnemonic, traits # [Pure,
23    DeclareOpInterfaceMethods<VectorUnrollOpInterface>] #
24    ElementwiseMappable.traits>;
25
26// Base class for unary math operations on integer types. Require an operand
27// and result of the same type. This type can be an integer type, vector or
28// tensor thereof.
29class Math_IntegerUnaryOp<string mnemonic, list<Trait> traits = []> :
30    Math_Op<mnemonic, traits # [SameOperandsAndResultType]> {
31  let arguments = (ins SignlessIntegerOrIndexLike:$operand);
32  let results = (outs SignlessIntegerOrIndexLike:$result);
33
34  let assemblyFormat = "$operand attr-dict `:` type($result)";
35}
36
37// Base class for unary math operations on floating point types. Require an
38// operand and result of the same type. This type can be a floating point type,
39// vector or tensor thereof.
40class Math_FloatUnaryOp<string mnemonic, list<Trait> traits = []> :
41    Math_Op<mnemonic,
42        traits # [SameOperandsAndResultType,
43                  DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
44  let arguments = (ins FloatLike:$operand,
45      DefaultValuedAttr<Arith_FastMathAttr,
46                        "::mlir::arith::FastMathFlags::none">:$fastmath);
47  let results = (outs FloatLike:$result);
48
49  let assemblyFormat = [{ $operand (`fastmath` `` $fastmath^)?
50                          attr-dict `:` type($result) }];
51}
52
53// Base class for binary math operations on integer types. Require two
54// operands and one result of the same type. This type can be an integer
55// type, vector or tensor thereof.
56class Math_IntegerBinaryOp<string mnemonic, list<Trait> traits = []> :
57    Math_Op<mnemonic, traits # [SameOperandsAndResultType]> {
58  let arguments = (ins SignlessIntegerOrIndexLike:$lhs, SignlessIntegerOrIndexLike:$rhs);
59  let results = (outs SignlessIntegerOrIndexLike:$result);
60
61  let assemblyFormat = "$lhs `,` $rhs attr-dict `:` type($result)";
62}
63
64// Base class for binary math operations on floating point types. Require two
65// operands and one result of the same type. This type can be a floating point
66// type, vector or tensor thereof.
67class Math_FloatBinaryOp<string mnemonic, list<Trait> traits = []> :
68    Math_Op<mnemonic,
69        traits # [SameOperandsAndResultType,
70                  DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
71  let arguments = (ins FloatLike:$lhs, FloatLike:$rhs,
72      DefaultValuedAttr<Arith_FastMathAttr,
73                        "::mlir::arith::FastMathFlags::none">:$fastmath);
74  let results = (outs FloatLike:$result);
75
76  let assemblyFormat = [{ $lhs `,` $rhs (`fastmath` `` $fastmath^)?
77                          attr-dict `:` type($result) }];
78}
79
80// Base class for floating point ternary operations. Require three operands and
81// one result of the same type. This type can be a floating point type, vector
82// or tensor thereof.
83class Math_FloatTernaryOp<string mnemonic, list<Trait> traits = []> :
84    Math_Op<mnemonic,
85        traits # [SameOperandsAndResultType,
86                  DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
87  let arguments = (ins FloatLike:$a, FloatLike:$b, FloatLike:$c,
88      DefaultValuedAttr<Arith_FastMathAttr,
89                        "::mlir::arith::FastMathFlags::none">:$fastmath);
90  let results = (outs FloatLike:$result);
91
92  let assemblyFormat = [{ $a `,` $b `,` $c (`fastmath` `` $fastmath^)?
93                          attr-dict `:` type($result) }];
94}
95
96//===----------------------------------------------------------------------===//
97// AbsFOp
98//===----------------------------------------------------------------------===//
99
100def Math_AbsFOp : Math_FloatUnaryOp<"absf"> {
101  let summary = "floating point absolute-value operation";
102  let description = [{
103    The `absf` operation computes the absolute value. It takes one operand of
104    floating point type (i.e., scalar, tensor or vector) and returns one result
105    of the same type.
106
107    Example:
108
109    ```mlir
110    // Scalar absolute value.
111    %a = math.absf %b : f64
112    ```
113  }];
114  let hasFolder = 1;
115}
116
117//===----------------------------------------------------------------------===//
118// AbsIOp
119//===----------------------------------------------------------------------===//
120
121def Math_AbsIOp : Math_IntegerUnaryOp<"absi"> {
122  let summary = "integer absolute-value operation";
123  let description = [{
124    The `absi` operation computes the absolute value. It takes one operand of
125    integer type (i.e., scalar, tensor or vector) and returns one result of the
126    same type.
127
128    Example:
129
130    ```mlir
131    // Scalar absolute value.
132    %a = math.absi %b : i64
133    ```
134  }];
135  let hasFolder = 1;
136}
137
138//===----------------------------------------------------------------------===//
139// AcoshOp
140//===----------------------------------------------------------------------===//
141
142def Math_AcoshOp : Math_FloatUnaryOp<"acosh">{
143  let summary = "Hyperbolic arcus cosine of the given value";
144  let description = [{
145    Syntax:
146
147    ```
148    operation ::= ssa-id `=` `math.acosh` ssa-use `:` type
149    ```
150
151    The `acosh` operation computes the arcus cosine of a given value.  It takes
152    one operand of floating point type (i.e., scalar, tensor or vector) and returns
153    one result of the same type. It has no standard attributes.
154
155    Example:
156
157    ```mlir
158    // Hyperbolic arcus cosine of scalar value.
159    %a = math.acosh %b : f64
160    ```
161  }];
162  let hasFolder = 1;
163}
164
165//===----------------------------------------------------------------------===//
166// AsinOp
167//===----------------------------------------------------------------------===//
168
169def Math_AsinOp : Math_FloatUnaryOp<"asin">{
170  let summary = "arcus sine of the given value";
171  let description = [{
172    Syntax:
173
174    ```
175    operation ::= ssa-id `=` `math.asin` ssa-use `:` type
176    ```
177
178    The `asin` operation computes the arcus sine of a given value.  It takes
179    one operand of floating point type (i.e., scalar, tensor or vector) and returns
180    one result of the same type. It has no standard attributes.
181
182    Example:
183
184    ```mlir
185    // Arcus sine of scalar value.
186    %a = math.asin %b : f64
187    ```
188  }];
189  let hasFolder = 1;
190}
191
192//===----------------------------------------------------------------------===//
193// AsinhOp
194//===----------------------------------------------------------------------===//
195
196def Math_AsinhOp : Math_FloatUnaryOp<"asinh">{
197  let summary = "hyperbolic arcus sine of the given value";
198  let description = [{
199    Syntax:
200
201    ```
202    operation ::= ssa-id `=` `math.asinh` ssa-use `:` type
203    ```
204
205    The `asinh` operation computes the hyperbolic arcus sine of a given value.  It takes
206    one operand of floating point type (i.e., scalar, tensor or vector) and returns
207    one result of the same type. It has no standard attributes.
208
209    Example:
210
211    ```mlir
212    // Hyperbolic arcus sine of scalar value.
213    %a = math.asinh %b : f64
214    ```
215  }];
216  let hasFolder = 1;
217}
218
219//===----------------------------------------------------------------------===//
220// AtanOp
221//===----------------------------------------------------------------------===//
222
223def Math_AtanOp : Math_FloatUnaryOp<"atan">{
224  let summary = "arcus tangent of the given value";
225  let description = [{
226    The `atan` operation computes the arcus tangent of a given value.  It takes
227    one operand of floating point type (i.e., scalar, tensor or vector) and returns
228    one result of the same type. It has no standard attributes.
229
230    Example:
231
232    ```mlir
233    // Arcus tangent of scalar value.
234    %a = math.atan %b : f64
235    ```
236  }];
237  let hasFolder = 1;
238}
239
240//===----------------------------------------------------------------------===//
241// AtanhOp
242//===----------------------------------------------------------------------===//
243
244def Math_AtanhOp : Math_FloatUnaryOp<"atanh">{
245  let summary = "hyperbolic arcus tangent of the given value";
246  let description = [{
247    Syntax:
248
249    ```
250    operation ::= ssa-id `=` `math.atanh` ssa-use `:` type
251    ```
252
253    The `atanh` operation computes the hyperbolic arcus tangent of a given value.  It takes
254    one operand of floating point type (i.e., scalar, tensor or vector) and returns
255    one result of the same type. It has no standard attributes.
256
257    Example:
258
259    ```mlir
260    // Hyperbolic arcus tangent of scalar value.
261    %a = math.atanh %b : f64
262    ```
263  }];
264  let hasFolder = 1;
265}
266
267//===----------------------------------------------------------------------===//
268// Atan2Op
269//===----------------------------------------------------------------------===//
270
271def Math_Atan2Op : Math_FloatBinaryOp<"atan2">{
272  let summary = "2-argument arcus tangent of the given values";
273  let description = [{
274    The `atan2` operation takes two operands and returns one result, all of
275    which must be of the same type.  The operands must be of floating point type
276    (i.e., scalar, tensor or vector).
277
278    The 2-argument arcus tangent `atan2(y, x)` returns the angle in the
279    Euclidian plane between the positive x-axis and the ray through the point
280    (x, y).  It is a generalization of the 1-argument arcus tangent which
281    returns the angle on the basis of the ratio y/x.
282
283    See also https://en.wikipedia.org/wiki/Atan2
284
285    Example:
286
287    ```mlir
288    // Scalar variant.
289    %a = math.atan2 %b, %c : f32
290    ```
291  }];
292  let hasFolder = 1;
293}
294
295//===----------------------------------------------------------------------===//
296// CbrtOp
297//===----------------------------------------------------------------------===//
298
299def Math_CbrtOp : Math_FloatUnaryOp<"cbrt"> {
300  let summary = "cube root of the specified value";
301  let description = [{
302    The `cbrt` operation computes the cube root. It takes one operand of
303    floating point type (i.e., scalar, tensor or vector) and returns one result
304    of the same type. It has no standard attributes.
305
306    Example:
307
308    ```mlir
309    // Scalar cube root value.
310    %a = math.cbrt %b : f64
311    ```
312
313    Note: This op is not equivalent to powf(..., 1/3.0).
314  }];
315}
316
317//===----------------------------------------------------------------------===//
318// CeilOp
319//===----------------------------------------------------------------------===//
320
321def Math_CeilOp : Math_FloatUnaryOp<"ceil"> {
322  let summary = "ceiling of the specified value";
323  let description = [{
324    The `ceil` operation computes the ceiling of a given value. It takes one
325    operand of floating point type (i.e., scalar, tensor or vector) and returns one
326    result of the same type.  It has no standard attributes.
327
328    Example:
329
330    ```mlir
331    // Scalar ceiling value.
332    %a = math.ceil %b : f64
333    ```
334  }];
335  let hasFolder = 1;
336}
337
338//===----------------------------------------------------------------------===//
339// CopySignOp
340//===----------------------------------------------------------------------===//
341
342def Math_CopySignOp : Math_FloatBinaryOp<"copysign"> {
343  let summary = "A copysign operation";
344  let description = [{
345    The `copysign` returns a value with the magnitude of the first operand and
346    the sign of the second operand. It takes two operands and returns one result of
347    the same type. The operands must be of floating point type (i.e., scalar,
348    tensor or vector). It has no standard attributes.
349
350    Example:
351
352    ```mlir
353    // Scalar copysign value.
354    %a = math.copysign %b, %c : f64
355    ```
356  }];
357  let hasFolder = 1;
358}
359
360//===----------------------------------------------------------------------===//
361// CosOp
362//===----------------------------------------------------------------------===//
363
364def Math_CosOp : Math_FloatUnaryOp<"cos"> {
365  let summary = "cosine of the specified value";
366  let description = [{
367    The `cos` operation computes the cosine of a given value. It takes one
368    operand of floating point type (i.e., scalar, tensor or vector) and returns one
369    result of the same type.  It has no standard attributes.
370
371    Example:
372
373    ```mlir
374    // Scalar cosine value.
375    %a = math.cos %b : f64
376    ```
377  }];
378  let hasFolder = 1;
379}
380
381//===----------------------------------------------------------------------===//
382// AcosOp
383//===----------------------------------------------------------------------===//
384
385def Math_AcosOp : Math_FloatUnaryOp<"acos"> {
386  let summary = "arcus cosine of the specified value";
387  let description = [{
388    The `acos` operation computes the arcus cosine of a given value. It takes one
389    operand of floating point type (i.e., scalar, tensor or vector) and returns one
390    result of the same type.  It has no standard attributes.
391
392    Example:
393
394    ```mlir
395    // Scalar arcus cosine value.
396    %a = math.acos %b : f64
397    ```
398  }];
399  let hasFolder = 1;
400}
401
402//===----------------------------------------------------------------------===//
403// CoshOp
404//===----------------------------------------------------------------------===//
405
406def Math_CoshOp : Math_FloatUnaryOp<"cosh"> {
407  let summary = "hyperbolic cosine of the specified value";
408  let description = [{
409    The `cosh` operation computes the hyperbolic cosine. It takes one operand
410    of floating point type (i.e., scalar, tensor or vector) and returns one
411    result of the same type. It has no standard attributes.
412
413    Example:
414
415    ```mlir
416    // Scalar hyperbolic cosine value.
417    %a = math.cosh %b : f64
418    ```
419  }];
420  let hasFolder = 1;
421}
422
423//===----------------------------------------------------------------------===//
424// SinOp
425//===----------------------------------------------------------------------===//
426
427def Math_SinOp : Math_FloatUnaryOp<"sin"> {
428  let summary = "sine of the specified value";
429  let description = [{
430    The `sin` operation computes the sine of a given value. It takes one
431    operand of floating point type (i.e., scalar, tensor or vector) and returns one
432    result of the same type.  It has no standard attributes.
433
434    Example:
435
436    ```mlir
437    // Scalar sine value.
438    %a = math.sin %b : f64
439    ```
440  }];
441  let hasFolder = 1;
442}
443
444//===----------------------------------------------------------------------===//
445// SinhOp
446//===----------------------------------------------------------------------===//
447
448def Math_SinhOp : Math_FloatUnaryOp<"sinh"> {
449  let summary = "hyperbolic sine of the specified value";
450  let description = [{
451    The `sinh` operation computes the hyperbolic sine. It takes one operand
452    of floating point type (i.e., scalar, tensor or vector) and returns one
453    result of the same type. It has no standard attributes.
454
455    Example:
456
457    ```mlir
458    // Scalar hyperbolic sine value.
459    %a = math.sinh %b : f64
460    ```
461  }];
462  let hasFolder = 1;
463}
464
465//===----------------------------------------------------------------------===//
466// CountLeadingZerosOp
467//===----------------------------------------------------------------------===//
468
469def Math_CountLeadingZerosOp : Math_IntegerUnaryOp<"ctlz"> {
470  let summary = "counts the leading zeros an integer value";
471  let description = [{
472    The `ctlz` operation computes the number of leading zeros of an integer value.
473    It operates on scalar, tensor or vector.
474
475    Example:
476
477    ```mlir
478    // Scalar ctlz function value.
479    %a = math.ctlz %b : i32
480    ```
481  }];
482  let hasFolder = 1;
483}
484
485//===----------------------------------------------------------------------===//
486// CountTrailingZerosOp
487//===----------------------------------------------------------------------===//
488
489def Math_CountTrailingZerosOp : Math_IntegerUnaryOp<"cttz"> {
490  let summary = "counts the trailing zeros an integer value";
491  let description = [{
492    The `cttz` operation computes the number of trailing zeros of an integer value.
493    It operates on scalar, tensor or vector.
494
495    Example:
496
497    ```mlir
498    // Scalar cttz function value.
499    %a = math.cttz %b : i32
500    ```
501  }];
502  let hasFolder = 1;
503}
504
505//===----------------------------------------------------------------------===//
506// CtPopOp
507//===----------------------------------------------------------------------===//
508
509def Math_CtPopOp : Math_IntegerUnaryOp<"ctpop"> {
510  let summary = "counts the number of set bits of an integer value";
511  let description = [{
512    The `ctpop` operation computes the number of set bits of an integer value.
513    It operates on scalar, tensor or vector.
514
515    Example:
516
517    ```mlir
518    // Scalar ctpop function value.
519    %a = math.ctpop %b : i32
520    ```
521  }];
522  let hasFolder = 1;
523}
524
525//===----------------------------------------------------------------------===//
526// ErfOp
527//===----------------------------------------------------------------------===//
528
529def Math_ErfOp : Math_FloatUnaryOp<"erf"> {
530  let summary = "error function of the specified value";
531  let description = [{
532    The `erf` operation computes the error function. It takes one operand of
533    floating point type (i.e., scalar, tensor or vector) and returns one result of
534    the same type. It has no standard attributes.
535
536    Example:
537
538    ```mlir
539    // Scalar error function value.
540    %a = math.erf %b : f64
541    ```
542  }];
543  let hasFolder = 1;
544}
545
546
547//===----------------------------------------------------------------------===//
548// ExpOp
549//===----------------------------------------------------------------------===//
550
551def Math_ExpOp : Math_FloatUnaryOp<"exp"> {
552  let summary = "base-e exponential of the specified value";
553  let description = [{
554    The `exp` operation takes one operand of floating point type (i.e., scalar,
555    tensor or vector) and returns one result of the same type. It has no standard
556    attributes.
557
558    Example:
559
560    ```mlir
561    // Scalar natural exponential.
562    %a = math.exp %b : f64
563    ```
564  }];
565  let hasFolder = 1;
566}
567
568//===----------------------------------------------------------------------===//
569// Exp2Op
570//===----------------------------------------------------------------------===//
571
572def Math_Exp2Op : Math_FloatUnaryOp<"exp2"> {
573  let summary = "base-2 exponential of the specified value";
574
575  let description = [{
576    The `exp` operation takes one operand of floating point type (i.e., scalar,
577    tensor or vector) and returns one result of the same type. It has no standard
578    attributes.
579
580    Example:
581
582    ```mlir
583    // Scalar natural exponential.
584    %a = math.exp2 %b : f64
585    ```
586  }];
587  let hasFolder = 1;
588}
589
590//===----------------------------------------------------------------------===//
591// ExpM1Op
592//===----------------------------------------------------------------------===//
593
594def Math_ExpM1Op : Math_FloatUnaryOp<"expm1"> {
595  let summary = "base-e exponential of the specified value minus 1";
596  let description = [{
597    expm1(x) := exp(x) - 1
598
599    The `expm1` operation takes one operand of floating point type (i.e.,
600    scalar, tensor or vector) and returns one result of the same type. It has no
601    standard attributes.
602
603    Example:
604
605    ```mlir
606    // Scalar natural exponential minus 1.
607    %a = math.expm1 %b : f64
608    ```
609  }];
610  let hasFolder = 1;
611}
612
613//===----------------------------------------------------------------------===//
614// FloorOp
615//===----------------------------------------------------------------------===//
616
617def Math_FloorOp : Math_FloatUnaryOp<"floor"> {
618  let summary = "floor of the specified value";
619  let description = [{
620    The `floor` operation computes the floor of a given value. It takes one
621    operand of floating point type (i.e., scalar, tensor or vector) and returns one
622    result of the same type.  It has no standard attributes.
623
624    Example:
625
626    ```mlir
627    // Scalar floor value.
628    %a = math.floor %b : f64
629    ```
630  }];
631
632  let hasFolder = 1;
633}
634
635//===----------------------------------------------------------------------===//
636// FmaOp
637//===----------------------------------------------------------------------===//
638
639def Math_FmaOp : Math_FloatTernaryOp<"fma"> {
640  let summary = "floating point fused multipy-add operation";
641  let description = [{
642    The `fma` operation takes three operands and returns one result, each of
643    these is required to be the same type. Operands must be of floating point type
644    (i.e., scalar, tensor or vector).
645
646    Example:
647
648    ```mlir
649    // Scalar fused multiply-add: d = a*b + c
650    %d = math.fma %a, %b, %c : f64
651    ```
652
653    The semantics of the operation correspond to those of the `llvm.fma`
654    [intrinsic](https://llvm.org/docs/LangRef.html#llvm-fma-intrinsic). In the
655    particular case of lowering to LLVM, this is guaranteed to lower
656    to the `llvm.fma.*` intrinsic.
657  }];
658}
659
660//===----------------------------------------------------------------------===//
661// IPowIOp
662//===----------------------------------------------------------------------===//
663
664def Math_IPowIOp : Math_IntegerBinaryOp<"ipowi"> {
665  let summary = "signed integer raised to the power of operation";
666  let description = [{
667    The `ipowi` operation takes two operands of integer type (i.e., scalar,
668    tensor or vector) and returns one result of the same type. Operands
669    must have the same type.
670
671    Example:
672
673    ```mlir
674    // Scalar signed integer exponentiation.
675    %a = math.ipowi %b, %c : i32
676    ```
677  }];
678  let hasFolder = 1;
679}
680
681//===----------------------------------------------------------------------===//
682// LogOp
683//===----------------------------------------------------------------------===//
684
685def Math_LogOp : Math_FloatUnaryOp<"log"> {
686  let summary = "base-e logarithm of the specified value";
687
688  let description = [{
689    Computes the base-e logarithm of the given value. It takes one operand of
690    floating point type (i.e., scalar, tensor or vector) and returns one result of
691    the same type.
692
693    Example:
694
695    ```mlir
696    // Scalar log operation.
697    %y = math.log %x : f64
698    ```
699  }];
700  let hasFolder = 1;
701}
702
703//===----------------------------------------------------------------------===//
704// Log10Op
705//===----------------------------------------------------------------------===//
706
707def Math_Log10Op : Math_FloatUnaryOp<"log10"> {
708  let summary = "base-10 logarithm of the specified value";
709
710  let description = [{
711    Computes the base-10 logarithm of the given value. It takes one operand of
712    floating point type (i.e., scalar, tensor or vector) and returns one result of
713    the same type.
714
715    Example:
716
717    ```mlir
718    // Scalar log10 operation.
719    %y = math.log10 %x : f64
720    ```
721  }];
722  let hasFolder = 1;
723}
724
725//===----------------------------------------------------------------------===//
726// Log1pOp
727//===----------------------------------------------------------------------===//
728
729def Math_Log1pOp : Math_FloatUnaryOp<"log1p"> {
730  let summary = "Computes the natural logarithm of one plus the given value";
731
732  let description = [{
733    Computes the base-e logarithm of one plus the given value. It takes one
734    operand of floating point type (i.e., scalar, tensor or vector) and returns one
735    result of the same type.
736
737    log1p(x) := log(1 + x)
738
739    Example:
740
741    ```mlir
742    // Scalar log1p operation.
743    %y = math.log1p %x : f64
744    ```
745  }];
746  let hasFolder = 1;
747}
748
749//===----------------------------------------------------------------------===//
750// Log2Op
751//===----------------------------------------------------------------------===//
752
753def Math_Log2Op : Math_FloatUnaryOp<"log2"> {
754  let summary = "base-2 logarithm of the specified value";
755
756  let description = [{
757    Computes the base-2 logarithm of the given value. It takes one operand of
758    floating point type (i.e., scalar, tensor or vector) and returns one result of
759    the same type.
760
761    Example:
762
763    ```mlir
764    // Scalar log2 operation.
765    %y = math.log2 %x : f64
766    ```
767  }];
768  let hasFolder = 1;
769}
770
771//===----------------------------------------------------------------------===//
772// PowFOp
773//===----------------------------------------------------------------------===//
774
775def Math_PowFOp : Math_FloatBinaryOp<"powf"> {
776  let summary = "floating point raised to the power of operation";
777  let description = [{
778    The `powf` operation takes two operands of floating point type (i.e.,
779    scalar, tensor or vector) and returns one result of the same type. Operands
780    must have the same type.
781
782    Example:
783
784    ```mlir
785    // Scalar exponentiation.
786    %a = math.powf %b, %c : f64
787    ```
788  }];
789  let hasFolder = 1;
790}
791
792//===----------------------------------------------------------------------===//
793// RsqrtOp
794//===----------------------------------------------------------------------===//
795
796def Math_RsqrtOp : Math_FloatUnaryOp<"rsqrt"> {
797  let summary = "reciprocal of sqrt (1 / sqrt of the specified value)";
798  let description = [{
799    The `rsqrt` operation computes the reciprocal of the square root. It takes
800    one operand of floating point type (i.e., scalar, tensor or vector) and returns
801    one result of the same type. It has no standard attributes.
802
803    Example:
804
805    ```mlir
806    // Scalar reciprocal square root value.
807    %a = math.rsqrt %b : f64
808    ```
809  }];
810}
811
812//===----------------------------------------------------------------------===//
813// SqrtOp
814//===----------------------------------------------------------------------===//
815
816def Math_SqrtOp : Math_FloatUnaryOp<"sqrt"> {
817  let summary = "sqrt of the specified value";
818  let description = [{
819    The `sqrt` operation computes the square root. It takes one operand of
820    floating point type (i.e., scalar, tensor or vector) and returns one result of
821    the same type. It has no standard attributes.
822
823    Example:
824
825    ```mlir
826    // Scalar square root value.
827    %a = math.sqrt %b : f64
828    ```
829  }];
830  let hasFolder = 1;
831}
832
833//===----------------------------------------------------------------------===//
834// TanOp
835//===----------------------------------------------------------------------===//
836
837def Math_TanOp : Math_FloatUnaryOp<"tan"> {
838  let summary = "tangent of the specified value";
839  let description = [{
840    The `tan` operation computes the tangent. It takes one operand
841    of floating point type (i.e., scalar, tensor or vector) and returns one
842    result of the same type. It has no standard attributes.
843
844    Example:
845
846    ```mlir
847    // Scalar tangent value.
848    %a = math.tan %b : f64
849    ```
850  }];
851  let hasFolder = 1;
852}
853
854//===----------------------------------------------------------------------===//
855// TanhOp
856//===----------------------------------------------------------------------===//
857
858def Math_TanhOp : Math_FloatUnaryOp<"tanh"> {
859  let summary = "hyperbolic tangent of the specified value";
860  let description = [{
861    The `tanh` operation computes the hyperbolic tangent. It takes one operand
862    of floating point type (i.e., scalar, tensor or vector) and returns one
863    result of the same type. It has no standard attributes.
864
865    Example:
866
867    ```mlir
868    // Scalar hyperbolic tangent value.
869    %a = math.tanh %b : f64
870    ```
871  }];
872  let hasFolder = 1;
873}
874
875//===----------------------------------------------------------------------===//
876// RoundEvenOp
877//===----------------------------------------------------------------------===//
878
879def Math_RoundEvenOp : Math_FloatUnaryOp<"roundeven"> {
880  let summary = "round of the specified value with halfway cases to even";
881  let description = [{
882    The `roundeven` operation returns the operand rounded to the nearest integer
883    value in floating-point format. It takes one operand of floating point type
884    (i.e., scalar, tensor or vector) and produces one result of the same type.  The
885    operation rounds the argument to the nearest integer value in floating-point
886    format, rounding halfway cases to even, regardless of the current
887    rounding direction.
888
889    Example:
890
891    ```mlir
892    // Scalar round operation.
893    %a = math.roundeven %b : f64
894    ```
895  }];
896  let hasFolder = 1;
897}
898
899//===----------------------------------------------------------------------===//
900// RoundOp
901//===----------------------------------------------------------------------===//
902
903def Math_RoundOp : Math_FloatUnaryOp<"round"> {
904  let summary = "round of the specified value";
905  let description = [{
906    The `round` operation returns the operand rounded to the nearest integer
907    value in floating-point format. It takes one operand of floating point type
908    (i.e., scalar, tensor or vector) and produces one result of the same type.  The
909    operation rounds the argument to the nearest integer value in floating-point
910    format, rounding halfway cases away from zero, regardless of the current
911    rounding direction.
912
913    Example:
914
915    ```mlir
916    // Scalar round operation.
917    %a = math.round %b : f64
918    ```
919  }];
920  let hasFolder = 1;
921}
922
923//===----------------------------------------------------------------------===//
924// TruncOp
925//===----------------------------------------------------------------------===//
926
927def Math_TruncOp : Math_FloatUnaryOp<"trunc"> {
928  let summary = "trunc of the specified value";
929  let description = [{
930    The `trunc` operation returns the operand rounded to the nearest integer
931    value in floating-point format. It takes one operand of floating point type
932    (i.e., scalar, tensor or vector) and produces one result of the same type.
933    The operation always rounds to the nearest integer not larger in magnitude
934    than the operand, regardless of the current rounding direction.
935
936    Example:
937
938    ```mlir
939    // Scalar trunc operation.
940    %a = math.trunc %b : f64
941    ```
942  }];
943  let hasFolder = 1;
944}
945
946//===----------------------------------------------------------------------===//
947// FPowIOp
948//===----------------------------------------------------------------------===//
949
950def Math_FPowIOp : Math_Op<"fpowi",
951    [SameOperandsAndResultShape, AllTypesMatch<["lhs", "result"]>,
952     DeclareOpInterfaceMethods<ArithFastMathInterface>]> {
953  let summary = "floating point raised to the signed integer power";
954  let description = [{
955    The `fpowi` operation takes a `base` operand of floating point type
956    (i.e. scalar, tensor or vector) and a `power` operand of integer type
957    (also scalar, tensor or vector) and returns one result of the same type
958    as `base`. The result is `base` raised to the power of `power`.
959    The operation is elementwise for non-scalars, e.g.:
960
961    ```mlir
962    %v = math.fpowi %base, %power : vector<2xf32>, vector<2xi32
963    ```
964
965    The result is a vector of:
966
967    ```
968    [<math.fpowi %base[0], %power[0]>, <math.fpowi %base[1], %power[1]>]
969    ```
970
971    Example:
972
973    ```mlir
974    // Scalar exponentiation.
975    %a = math.fpowi %base, %power : f64, i32
976    ```
977  }];
978
979  let arguments = (ins FloatLike:$lhs, SignlessIntegerOrIndexLike:$rhs,
980      DefaultValuedAttr<Arith_FastMathAttr,
981                        "::mlir::arith::FastMathFlags::none">:$fastmath);
982  let results = (outs FloatLike:$result);
983  let assemblyFormat = [{ $lhs `,` $rhs (`fastmath` `` $fastmath^)?
984                          attr-dict `:` type($lhs) `,` type($rhs) }];
985
986  // TODO: add a constant folder using pow[f] for cases, when
987  //       the power argument is exactly representable in floating
988  //       point type of the base.
989}
990
991#endif // MATH_OPS
992