@@ -103,7 +103,7 @@ class FloatUnaryOp<string mnemonic, list<OpTrait> traits = []> :
103
103
104
104
// Base class for standard arithmetic operations. Requires operands and
105
105
// results to be of the same type, but does not constrain them to specific
106
- // types. Individual classes will have `lhs` and `rhs` accessor to operands.
106
+ // types.
107
107
class ArithmeticOp<string mnemonic, list<OpTrait> traits = []> :
108
108
Op<StandardOps_Dialect, mnemonic,
109
109
!listconcat(traits, [NoSideEffect,
@@ -122,6 +122,32 @@ class ArithmeticOp<string mnemonic, list<OpTrait> traits = []> :
122
122
}];
123
123
}
124
124
125
+ // Base class for standard binary arithmetic operations.
126
+ class ArithmeticBinaryOp<string mnemonic, list<OpTrait> traits = []> :
127
+ ArithmeticOp<mnemonic, traits> {
128
+
129
+ let parser = [{
130
+ return impl::parseOneResultSameOperandTypeOp(parser, result);
131
+ }];
132
+
133
+ let printer = [{
134
+ return printStandardBinaryOp(this->getOperation(), p);
135
+ }];
136
+ }
137
+
138
+ // Base class for standard ternary arithmetic operations.
139
+ class ArithmeticTernaryOp<string mnemonic, list<OpTrait> traits = []> :
140
+ ArithmeticOp<mnemonic, traits> {
141
+
142
+ let parser = [{
143
+ return impl::parseOneResultSameOperandTypeOp(parser, result);
144
+ }];
145
+
146
+ let printer = [{
147
+ return printStandardTernaryOp(this->getOperation(), p);
148
+ }];
149
+ }
150
+
125
151
// Base class for standard arithmetic operations on integers, vectors and
126
152
// tensors thereof. This operation takes two operands and returns one result,
127
153
// each of these is required to be of the same type. This type may be an
@@ -130,8 +156,8 @@ class ArithmeticOp<string mnemonic, list<OpTrait> traits = []> :
130
156
//
131
157
// <op>i %0, %1 : i32
132
158
//
133
- class IntArithmeticOp <string mnemonic, list<OpTrait> traits = []> :
134
- ArithmeticOp <mnemonic,
159
+ class IntBinaryOp <string mnemonic, list<OpTrait> traits = []> :
160
+ ArithmeticBinaryOp <mnemonic,
135
161
!listconcat(traits,
136
162
[DeclareOpInterfaceMethods<VectorUnrollOpInterface>])>,
137
163
Arguments<(ins SignlessIntegerLike:$lhs, SignlessIntegerLike:$rhs)>;
@@ -145,12 +171,27 @@ class IntArithmeticOp<string mnemonic, list<OpTrait> traits = []> :
145
171
//
146
172
// <op>f %0, %1 : f32
147
173
//
148
- class FloatArithmeticOp <string mnemonic, list<OpTrait> traits = []> :
149
- ArithmeticOp <mnemonic,
174
+ class FloatBinaryOp <string mnemonic, list<OpTrait> traits = []> :
175
+ ArithmeticBinaryOp <mnemonic,
150
176
!listconcat(traits,
151
177
[DeclareOpInterfaceMethods<VectorUnrollOpInterface>])>,
152
178
Arguments<(ins FloatLike:$lhs, FloatLike:$rhs)>;
153
179
180
+ // Base class for standard arithmetic ternary operations on floats, vectors and
181
+ // tensors thereof. This operation has three operands and returns one result,
182
+ // each of these is required to be of the same type. This type may be a
183
+ // floating point scalar type, a vector whose element type is a floating point
184
+ // type, or a floating point tensor. The custom assembly form of the operation
185
+ // is as follows
186
+ //
187
+ // <op> %0, %1, %2 : f32
188
+ //
189
+ class FloatTernaryOp<string mnemonic, list<OpTrait> traits = []> :
190
+ ArithmeticTernaryOp<mnemonic,
191
+ !listconcat(traits,
192
+ [DeclareOpInterfaceMethods<VectorUnrollOpInterface>])>,
193
+ Arguments<(ins FloatLike:$a, FloatLike:$b, FloatLike:$c)>;
194
+
154
195
// Base class for memref allocating ops: alloca and alloc.
155
196
//
156
197
// %0 = alloclike(%m)[%s] : memref<8x?xf32, (d0, d1)[s0] -> ((d0 + s0), d1)>
@@ -257,7 +298,7 @@ def AbsFOp : FloatUnaryOp<"absf"> {
257
298
// AddFOp
258
299
//===----------------------------------------------------------------------===//
259
300
260
- def AddFOp : FloatArithmeticOp <"addf"> {
301
+ def AddFOp : FloatBinaryOp <"addf"> {
261
302
let summary = "floating point addition operation";
262
303
let description = [{
263
304
Syntax:
@@ -294,7 +335,7 @@ def AddFOp : FloatArithmeticOp<"addf"> {
294
335
// AddIOp
295
336
//===----------------------------------------------------------------------===//
296
337
297
- def AddIOp : IntArithmeticOp <"addi", [Commutative]> {
338
+ def AddIOp : IntBinaryOp <"addi", [Commutative]> {
298
339
let summary = "integer addition operation";
299
340
let description = [{
300
341
Syntax:
@@ -418,7 +459,7 @@ def AllocaOp : AllocLikeOp<"alloca", AutomaticAllocationScopeResource> {
418
459
// AndOp
419
460
//===----------------------------------------------------------------------===//
420
461
421
- def AndOp : IntArithmeticOp <"and", [Commutative]> {
462
+ def AndOp : IntBinaryOp <"and", [Commutative]> {
422
463
let summary = "integer binary and";
423
464
let description = [{
424
465
Syntax:
@@ -1269,7 +1310,7 @@ def ConstantOp : Std_Op<"constant",
1269
1310
// CopySignOp
1270
1311
//===----------------------------------------------------------------------===//
1271
1312
1272
- def CopySignOp : FloatArithmeticOp <"copysign"> {
1313
+ def CopySignOp : FloatBinaryOp <"copysign"> {
1273
1314
let summary = "A copysign operation";
1274
1315
let description = [{
1275
1316
Syntax:
@@ -1384,11 +1425,49 @@ def DimOp : Std_Op<"dim", [NoSideEffect]> {
1384
1425
// DivFOp
1385
1426
//===----------------------------------------------------------------------===//
1386
1427
1387
- def DivFOp : FloatArithmeticOp <"divf"> {
1428
+ def DivFOp : FloatBinaryOp <"divf"> {
1388
1429
let summary = "floating point division operation";
1389
1430
let hasFolder = 1;
1390
1431
}
1391
1432
1433
+ //===----------------------------------------------------------------------===//
1434
+ // FmaFOp
1435
+ //===----------------------------------------------------------------------===//
1436
+
1437
+ def FmaFOp : FloatTernaryOp<"fmaf"> {
1438
+ let summary = "floating point fused multipy-add operation";
1439
+ let description = [{
1440
+ Syntax:
1441
+
1442
+ ```
1443
+ operation ::= ssa-id `=` `std.fmaf` ssa-use `,` ssa-use `,` ssa-use `:` type
1444
+ ```
1445
+
1446
+ The `fmaf` operation takes three operands and returns one result, each of
1447
+ these is required to be the same type. This type may be a floating point
1448
+ scalar type, a vector whose element type is a floating point type, or a
1449
+ floating point tensor.
1450
+
1451
+ Example:
1452
+
1453
+ ```mlir
1454
+ // Scalar fused multiply-add: d = a*b + c
1455
+ %d = fmaf %a, %b, %c : f64
1456
+
1457
+ // SIMD vector fused multiply-add, e.g. for Intel SSE.
1458
+ %i = fmaf %f, %g, %h : vector<4xf32>
1459
+
1460
+ // Tensor fused multiply-add.
1461
+ %w = fmaf %x, %y, %z : tensor<4x?xbf16>
1462
+ ```
1463
+
1464
+ The semantics of the operation correspond to those of the `llvm.fma`
1465
+ [intrinsic](https://llvm.org/docs/LangRef.html#llvm-fma-intrinsic). In the
1466
+ particular case of lowering to LLVM, this is guaranteed to lower
1467
+ to the `llvm.fma.*` intrinsic.
1468
+ }];
1469
+ }
1470
+
1392
1471
//===----------------------------------------------------------------------===//
1393
1472
// FPExtOp
1394
1473
//===----------------------------------------------------------------------===//
@@ -1854,7 +1933,7 @@ def MemRefReshapeOp: Std_Op<"memref_reshape", [
1854
1933
// MulFOp
1855
1934
//===----------------------------------------------------------------------===//
1856
1935
1857
- def MulFOp : FloatArithmeticOp <"mulf"> {
1936
+ def MulFOp : FloatBinaryOp <"mulf"> {
1858
1937
let summary = "floating point multiplication operation";
1859
1938
let description = [{
1860
1939
Syntax:
@@ -1891,7 +1970,7 @@ def MulFOp : FloatArithmeticOp<"mulf"> {
1891
1970
// MulIOp
1892
1971
//===----------------------------------------------------------------------===//
1893
1972
1894
- def MulIOp : IntArithmeticOp <"muli", [Commutative]> {
1973
+ def MulIOp : IntBinaryOp <"muli", [Commutative]> {
1895
1974
let summary = "integer multiplication operation";
1896
1975
let hasFolder = 1;
1897
1976
}
@@ -1933,7 +2012,7 @@ def NegFOp : FloatUnaryOp<"negf"> {
1933
2012
// OrOp
1934
2013
//===----------------------------------------------------------------------===//
1935
2014
1936
- def OrOp : IntArithmeticOp <"or", [Commutative]> {
2015
+ def OrOp : IntBinaryOp <"or", [Commutative]> {
1937
2016
let summary = "integer binary or";
1938
2017
let description = [{
1939
2018
Syntax:
@@ -2040,7 +2119,7 @@ def RankOp : Std_Op<"rank", [NoSideEffect]> {
2040
2119
// RemFOp
2041
2120
//===----------------------------------------------------------------------===//
2042
2121
2043
- def RemFOp : FloatArithmeticOp <"remf"> {
2122
+ def RemFOp : FloatBinaryOp <"remf"> {
2044
2123
let summary = "floating point division remainder operation";
2045
2124
}
2046
2125
@@ -2141,7 +2220,7 @@ def SelectOp : Std_Op<"select", [NoSideEffect,
2141
2220
// ShiftLeftOp
2142
2221
//===----------------------------------------------------------------------===//
2143
2222
2144
- def ShiftLeftOp : IntArithmeticOp <"shift_left"> {
2223
+ def ShiftLeftOp : IntBinaryOp <"shift_left"> {
2145
2224
let summary = "integer left-shift";
2146
2225
let description = [{
2147
2226
The shift_left operation shifts an integer value to the left by a variable
@@ -2161,7 +2240,7 @@ def ShiftLeftOp : IntArithmeticOp<"shift_left"> {
2161
2240
// SignedDivIOp
2162
2241
//===----------------------------------------------------------------------===//
2163
2242
2164
- def SignedDivIOp : IntArithmeticOp <"divi_signed"> {
2243
+ def SignedDivIOp : IntBinaryOp <"divi_signed"> {
2165
2244
let summary = "signed integer division operation";
2166
2245
let description = [{
2167
2246
Syntax:
@@ -2196,7 +2275,7 @@ def SignedDivIOp : IntArithmeticOp<"divi_signed"> {
2196
2275
// SignedFloorDivIOp
2197
2276
//===----------------------------------------------------------------------===//
2198
2277
2199
- def SignedFloorDivIOp : IntArithmeticOp <"floordivi_signed"> {
2278
+ def SignedFloorDivIOp : IntBinaryOp <"floordivi_signed"> {
2200
2279
let summary = "signed floor integer division operation";
2201
2280
let description = [{
2202
2281
Syntax:
@@ -2225,7 +2304,7 @@ def SignedFloorDivIOp : IntArithmeticOp<"floordivi_signed"> {
2225
2304
// SignedCeilDivIOp
2226
2305
//===----------------------------------------------------------------------===//
2227
2306
2228
- def SignedCeilDivIOp : IntArithmeticOp <"ceildivi_signed"> {
2307
+ def SignedCeilDivIOp : IntBinaryOp <"ceildivi_signed"> {
2229
2308
let summary = "signed ceil integer division operation";
2230
2309
let description = [{
2231
2310
Syntax:
@@ -2253,7 +2332,7 @@ def SignedCeilDivIOp : IntArithmeticOp<"ceildivi_signed"> {
2253
2332
// SignedRemIOp
2254
2333
//===----------------------------------------------------------------------===//
2255
2334
2256
- def SignedRemIOp : IntArithmeticOp <"remi_signed"> {
2335
+ def SignedRemIOp : IntBinaryOp <"remi_signed"> {
2257
2336
let summary = "signed integer division remainder operation";
2258
2337
let description = [{
2259
2338
Syntax:
@@ -2288,7 +2367,7 @@ def SignedRemIOp : IntArithmeticOp<"remi_signed"> {
2288
2367
// SignedShiftRightOp
2289
2368
//===----------------------------------------------------------------------===//
2290
2369
2291
- def SignedShiftRightOp : IntArithmeticOp <"shift_right_signed"> {
2370
+ def SignedShiftRightOp : IntBinaryOp <"shift_right_signed"> {
2292
2371
let summary = "signed integer right-shift";
2293
2372
let description = [{
2294
2373
The shift_right_signed operation shifts an integer value to the right by
@@ -2488,7 +2567,7 @@ def StoreOp : Std_Op<"store",
2488
2567
// SubFOp
2489
2568
//===----------------------------------------------------------------------===//
2490
2569
2491
- def SubFOp : FloatArithmeticOp <"subf"> {
2570
+ def SubFOp : FloatBinaryOp <"subf"> {
2492
2571
let summary = "floating point subtraction operation";
2493
2572
let hasFolder = 1;
2494
2573
}
@@ -2497,7 +2576,7 @@ def SubFOp : FloatArithmeticOp<"subf"> {
2497
2576
// SubIOp
2498
2577
//===----------------------------------------------------------------------===//
2499
2578
2500
- def SubIOp : IntArithmeticOp <"subi"> {
2579
+ def SubIOp : IntBinaryOp <"subi"> {
2501
2580
let summary = "integer subtraction operation";
2502
2581
let hasFolder = 1;
2503
2582
}
@@ -3173,7 +3252,7 @@ def UIToFPOp : ArithmeticCastOp<"uitofp">, Arguments<(ins AnyType:$in)> {
3173
3252
// UnsignedDivIOp
3174
3253
//===----------------------------------------------------------------------===//
3175
3254
3176
- def UnsignedDivIOp : IntArithmeticOp <"divi_unsigned"> {
3255
+ def UnsignedDivIOp : IntBinaryOp <"divi_unsigned"> {
3177
3256
let summary = "unsigned integer division operation";
3178
3257
let description = [{
3179
3258
Syntax:
@@ -3208,7 +3287,7 @@ def UnsignedDivIOp : IntArithmeticOp<"divi_unsigned"> {
3208
3287
// UnsignedRemIOp
3209
3288
//===----------------------------------------------------------------------===//
3210
3289
3211
- def UnsignedRemIOp : IntArithmeticOp <"remi_unsigned"> {
3290
+ def UnsignedRemIOp : IntBinaryOp <"remi_unsigned"> {
3212
3291
let summary = "unsigned integer division remainder operation";
3213
3292
let description = [{
3214
3293
Syntax:
@@ -3243,7 +3322,7 @@ def UnsignedRemIOp : IntArithmeticOp<"remi_unsigned"> {
3243
3322
// UnsignedShiftRightOp
3244
3323
//===----------------------------------------------------------------------===//
3245
3324
3246
- def UnsignedShiftRightOp : IntArithmeticOp <"shift_right_unsigned"> {
3325
+ def UnsignedShiftRightOp : IntBinaryOp <"shift_right_unsigned"> {
3247
3326
let summary = "unsigned integer right-shift";
3248
3327
let description = [{
3249
3328
The shift_right_unsigned operation shifts an integer value to the right by
@@ -3332,7 +3411,7 @@ def ViewOp : Std_Op<"view", [
3332
3411
// XOrOp
3333
3412
//===----------------------------------------------------------------------===//
3334
3413
3335
- def XOrOp : IntArithmeticOp <"xor", [Commutative]> {
3414
+ def XOrOp : IntBinaryOp <"xor", [Commutative]> {
3336
3415
let summary = "integer binary xor";
3337
3416
let description = [{
3338
3417
The `xor` operation takes two operands and returns one result, each of these
0 commit comments