@@ -137,6 +137,20 @@ class Arith_CompareOpOfAnyRank<string mnemonic, list<Trait> traits = []> :
137
137
let results = (outs BoolLikeOfAnyRank:$result);
138
138
}
139
139
140
+ class Arith_IntBinaryOpWithOverflowFlags<string mnemonic, list<Trait> traits = []> :
141
+ Arith_BinaryOp<mnemonic, traits #
142
+ [Pure, DeclareOpInterfaceMethods<InferIntRangeInterface>,
143
+ DeclareOpInterfaceMethods<ArithIntegerOverflowFlagsInterface>]>,
144
+ Arguments<(ins SignlessIntegerLike:$lhs, SignlessIntegerLike:$rhs,
145
+ DefaultValuedAttr<
146
+ Arith_IntegerOverflowAttr,
147
+ "::mlir::arith::IntegerOverflowFlags::none">:$overflowFlags)>,
148
+ Results<(outs SignlessIntegerLike:$result)> {
149
+
150
+ let assemblyFormat = [{ $lhs `,` $rhs (`overflow` `` $overflowFlags^)?
151
+ attr-dict `:` type($result) }];
152
+ }
153
+
140
154
//===----------------------------------------------------------------------===//
141
155
// ConstantOp
142
156
//===----------------------------------------------------------------------===//
@@ -192,7 +206,7 @@ def Arith_ConstantOp : Op<Arith_Dialect, "constant",
192
206
// AddIOp
193
207
//===----------------------------------------------------------------------===//
194
208
195
- def Arith_AddIOp : Arith_TotalIntBinaryOp <"addi", [Commutative]> {
209
+ def Arith_AddIOp : Arith_IntBinaryOpWithOverflowFlags <"addi", [Commutative]> {
196
210
let summary = "integer addition operation";
197
211
let description = [{
198
212
Performs N-bit addition on the operands. The operands are interpreted as
@@ -203,16 +217,23 @@ def Arith_AddIOp : Arith_TotalIntBinaryOp<"addi", [Commutative]> {
203
217
204
218
The `addi` operation takes two operands and returns one result, each of
205
219
these is required to be the same type. This type may be an integer scalar type,
206
- a vector whose element type is integer, or a tensor of integers. It has no
207
- standard attributes.
220
+ a vector whose element type is integer, or a tensor of integers.
221
+
222
+ This op supports `nuw`/`nsw` overflow flags which stands stand for
223
+ "No Unsigned Wrap" and "No Signed Wrap", respectively. If the `nuw` and/or
224
+ `nsw` flags are present, and an unsigned/signed overflow occurs
225
+ (respectively), the result is poison.
208
226
209
227
Example:
210
228
211
229
```mlir
212
230
// Scalar addition.
213
231
%a = arith.addi %b, %c : i64
214
232
215
- // SIMD vector element-wise addition, e.g. for Intel SSE.
233
+ // Scalar addition with overflow flags.
234
+ %a = arith.addi %b, %c overflow<nsw, nuw> : i64
235
+
236
+ // SIMD vector element-wise addition.
216
237
%f = arith.addi %g, %h : vector<4xi32>
217
238
218
239
// Tensor element-wise addition.
@@ -278,21 +299,41 @@ def Arith_AddUIExtendedOp : Arith_Op<"addui_extended", [Pure, Commutative,
278
299
// SubIOp
279
300
//===----------------------------------------------------------------------===//
280
301
281
- def Arith_SubIOp : Arith_TotalIntBinaryOp <"subi"> {
302
+ def Arith_SubIOp : Arith_IntBinaryOpWithOverflowFlags <"subi"> {
282
303
let summary = [{
283
304
Integer subtraction operation.
284
305
}];
285
306
let description = [{
286
- Performs N-bit subtraction on the operands. The operands are interpreted as unsigned
287
- bitvectors. The result is represented by a bitvector containing the mathematical
288
- value of the subtraction modulo 2^n, where `n` is the bitwidth. Because `arith`
289
- integers use a two's complement representation, this operation is applicable on
307
+ Performs N-bit subtraction on the operands. The operands are interpreted as unsigned
308
+ bitvectors. The result is represented by a bitvector containing the mathematical
309
+ value of the subtraction modulo 2^n, where `n` is the bitwidth. Because `arith`
310
+ integers use a two's complement representation, this operation is applicable on
290
311
both signed and unsigned integer operands.
291
312
292
313
The `subi` operation takes two operands and returns one result, each of
293
- these is required to be the same type. This type may be an integer scalar type,
294
- a vector whose element type is integer, or a tensor of integers. It has no
295
- standard attributes.
314
+ these is required to be the same type. This type may be an integer scalar type,
315
+ a vector whose element type is integer, or a tensor of integers.
316
+
317
+ This op supports `nuw`/`nsw` overflow flags which stands stand for
318
+ "No Unsigned Wrap" and "No Signed Wrap", respectively. If the `nuw` and/or
319
+ `nsw` flags are present, and an unsigned/signed overflow occurs
320
+ (respectively), the result is poison.
321
+
322
+ Example:
323
+
324
+ ```mlir
325
+ // Scalar subtraction.
326
+ %a = arith.subi %b, %c : i64
327
+
328
+ // Scalar subtraction with overflow flags.
329
+ %a = arith.subi %b, %c overflow<nsw, nuw> : i64
330
+
331
+ // SIMD vector element-wise subtraction.
332
+ %f = arith.subi %g, %h : vector<4xi32>
333
+
334
+ // Tensor element-wise subtraction.
335
+ %x = arith.subi %y, %z : tensor<4x?xi8>
336
+ ```
296
337
}];
297
338
let hasFolder = 1;
298
339
let hasCanonicalizer = 1;
@@ -302,21 +343,41 @@ def Arith_SubIOp : Arith_TotalIntBinaryOp<"subi"> {
302
343
// MulIOp
303
344
//===----------------------------------------------------------------------===//
304
345
305
- def Arith_MulIOp : Arith_TotalIntBinaryOp <"muli", [Commutative]> {
346
+ def Arith_MulIOp : Arith_IntBinaryOpWithOverflowFlags <"muli", [Commutative]> {
306
347
let summary = [{
307
348
Integer multiplication operation.
308
349
}];
309
350
let description = [{
310
- Performs N-bit multiplication on the operands. The operands are interpreted as
311
- unsigned bitvectors. The result is represented by a bitvector containing the
312
- mathematical value of the multiplication modulo 2^n, where `n` is the bitwidth.
313
- Because `arith` integers use a two's complement representation, this operation is
351
+ Performs N-bit multiplication on the operands. The operands are interpreted as
352
+ unsigned bitvectors. The result is represented by a bitvector containing the
353
+ mathematical value of the multiplication modulo 2^n, where `n` is the bitwidth.
354
+ Because `arith` integers use a two's complement representation, this operation is
314
355
applicable on both signed and unsigned integer operands.
315
356
316
357
The `muli` operation takes two operands and returns one result, each of
317
- these is required to be the same type. This type may be an integer scalar type,
318
- a vector whose element type is integer, or a tensor of integers. It has no
319
- standard attributes.
358
+ these is required to be the same type. This type may be an integer scalar type,
359
+ a vector whose element type is integer, or a tensor of integers.
360
+
361
+ This op supports `nuw`/`nsw` overflow flags which stands stand for
362
+ "No Unsigned Wrap" and "No Signed Wrap", respectively. If the `nuw` and/or
363
+ `nsw` flags are present, and an unsigned/signed overflow occurs
364
+ (respectively), the result is poison.
365
+
366
+ Example:
367
+
368
+ ```mlir
369
+ // Scalar multiplication.
370
+ %a = arith.muli %b, %c : i64
371
+
372
+ // Scalar multiplication with overflow flags.
373
+ %a = arith.muli %b, %c overflow<nsw, nuw> : i64
374
+
375
+ // SIMD vector element-wise multiplication.
376
+ %f = arith.muli %g, %h : vector<4xi32>
377
+
378
+ // Tensor element-wise multiplication.
379
+ %x = arith.muli %y, %z : tensor<4x?xi8>
380
+ ```
320
381
}];
321
382
let hasFolder = 1;
322
383
let hasCanonicalizer = 1;
0 commit comments