xref: /llvm-project/mlir/test/Transforms/constant-fold.mlir (revision b1da82ae3dba0982b3a9668ca895ddf4164fb3d1)
1// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -test-constant-fold | FileCheck %s
2
3// -----
4
5// CHECK-LABEL: @affine_for
6// CHECK-SAME: [[ARG:%[a-zA-Z0-9]+]]
7func.func @affine_for(%p : memref<f32>) {
8  // CHECK: [[C:%.+]] = arith.constant 6.{{0*}}e+00 : f32
9  affine.for %arg1 = 0 to 128 {
10    affine.for %arg2 = 0 to 8 { // CHECK: affine.for %{{.*}} = 0 to 8 {
11      %0 = arith.constant 4.5 : f32
12      %1 = arith.constant 1.5 : f32
13
14      %2 = arith.addf %0, %1 : f32
15
16      // CHECK-NEXT: memref.store [[C]], [[ARG]][]
17      memref.store %2, %p[] : memref<f32>
18    }
19  }
20  return
21}
22
23// -----
24
25// CHECK-LABEL: func @simple_addf
26func.func @simple_addf() -> f32 {
27  %0 = arith.constant 4.5 : f32
28  %1 = arith.constant 1.5 : f32
29
30  // CHECK-NEXT: [[C:%.+]] = arith.constant 6.{{0*}}e+00 : f32
31  %2 = arith.addf %0, %1 : f32
32
33  // CHECK-NEXT: return [[C]]
34  return %2 : f32
35}
36
37// -----
38
39// CHECK-LABEL: func @addf_splat_tensor
40func.func @addf_splat_tensor() -> tensor<4xf32> {
41  %0 = arith.constant dense<4.5> : tensor<4xf32>
42  %1 = arith.constant dense<1.5> : tensor<4xf32>
43
44  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<6.{{0*}}e+00> : tensor<4xf32>
45  %2 = arith.addf %0, %1 : tensor<4xf32>
46
47  // CHECK-NEXT: return [[C]]
48  return %2 : tensor<4xf32>
49}
50
51// -----
52
53// CHECK-LABEL: func @addf_dense_tensor
54func.func @addf_dense_tensor() -> tensor<4xf32> {
55  %0 = arith.constant dense<[1.5, 2.5, 3.5, 4.5]> : tensor<4xf32>
56  %1 = arith.constant dense<[1.5, 2.5, 3.5, 4.5]> : tensor<4xf32>
57
58  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<[3.{{0*}}e+00, 5.{{0*}}e+00, 7.{{0*}}e+00, 9.{{0*}}e+00]> : tensor<4xf32>
59  %2 = arith.addf %0, %1 : tensor<4xf32>
60
61  // CHECK-NEXT: return [[C]]
62  return %2 : tensor<4xf32>
63}
64
65// -----
66
67// CHECK-LABEL: func @addf_dense_and_splat_tensors
68func.func @addf_dense_and_splat_tensors() -> tensor<4xf32> {
69  %0 = arith.constant dense<[1.5, 2.5, 3.5, 4.5]> : tensor<4xf32>
70  %1 = arith.constant dense<1.5> : tensor<4xf32>
71
72  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<[3.{{0*}}e+00, 4.{{0*}}e+00, 5.{{0*}}e+00, 6.{{0*}}e+00]> : tensor<4xf32>
73  %2 = arith.addf %0, %1 : tensor<4xf32>
74
75  // CHECK-NEXT: return [[C]]
76  return %2 : tensor<4xf32>
77}
78
79// -----
80
81// CHECK-LABEL: func @simple_addi
82func.func @simple_addi() -> i32 {
83  %0 = arith.constant 1 : i32
84  %1 = arith.constant 5 : i32
85
86  // CHECK-NEXT: [[C:%.+]] = arith.constant 6 : i32
87  %2 = arith.addi %0, %1 : i32
88
89  // CHECK-NEXT: return [[C]]
90  return %2 : i32
91}
92
93// -----
94
95// CHECK: func @simple_and
96// CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: i1
97// CHECK-SAME: [[ARG1:%[a-zA-Z0-9]+]]: i32)
98func.func @simple_and(%arg0 : i1, %arg1 : i32) -> (i1, i32) {
99  %c1 = arith.constant 1 : i1
100  %cAllOnes_32 = arith.constant 4294967295 : i32
101
102  // CHECK: [[C31:%.*]] = arith.constant 31 : i32
103  %c31 = arith.constant 31 : i32
104  %1 = arith.andi %arg0, %c1 : i1
105  %2 = arith.andi %arg1, %cAllOnes_32 : i32
106
107  // CHECK: [[VAL:%.*]] = arith.andi [[ARG1]], [[C31]]
108  %3 = arith.andi %2, %c31 : i32
109
110  // CHECK: return [[ARG0]], [[VAL]]
111  return %1, %3 : i1, i32
112}
113
114// -----
115
116// CHECK-LABEL: func @and_index
117//  CHECK-SAME:   [[ARG:%[a-zA-Z0-9]+]]
118func.func @and_index(%arg0 : index) -> (index) {
119  // CHECK: [[C31:%.*]] = arith.constant 31 : index
120  %c31 = arith.constant 31 : index
121  %c_AllOnes = arith.constant -1 : index
122  %1 = arith.andi %arg0, %c31 : index
123
124  // CHECK: arith.andi [[ARG]], [[C31]]
125  %2 = arith.andi %1, %c_AllOnes : index
126  return %2 : index
127}
128
129// -----
130
131// CHECK: func @tensor_and
132// CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: tensor<2xi32>
133func.func @tensor_and(%arg0 : tensor<2xi32>) -> tensor<2xi32> {
134  %cAllOnes_32 = arith.constant dense<4294967295> : tensor<2xi32>
135
136  // CHECK: [[C31:%.*]] = arith.constant dense<31> : tensor<2xi32>
137  %c31 = arith.constant dense<31> : tensor<2xi32>
138
139  // CHECK: [[CMIXED:%.*]] = arith.constant dense<[31, -1]> : tensor<2xi32>
140  %c_mixed = arith.constant dense<[31, 4294967295]> : tensor<2xi32>
141
142  %0 = arith.andi %arg0, %cAllOnes_32 : tensor<2xi32>
143
144  // CHECK: [[T1:%.*]] = arith.andi [[ARG0]], [[C31]]
145  %1 = arith.andi %0, %c31 : tensor<2xi32>
146
147  // CHECK: [[T2:%.*]] = arith.andi [[T1]], [[CMIXED]]
148  %2 = arith.andi %1, %c_mixed : tensor<2xi32>
149
150  // CHECK: return [[T2]]
151  return %2 : tensor<2xi32>
152}
153
154// -----
155
156// CHECK: func @vector_and
157// CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: vector<2xi32>
158func.func @vector_and(%arg0 : vector<2xi32>) -> vector<2xi32> {
159  %cAllOnes_32 = arith.constant dense<4294967295> : vector<2xi32>
160
161  // CHECK: [[C31:%.*]] = arith.constant dense<31> : vector<2xi32>
162  %c31 = arith.constant dense<31> : vector<2xi32>
163
164  // CHECK: [[CMIXED:%.*]] = arith.constant dense<[31, -1]> : vector<2xi32>
165  %c_mixed = arith.constant dense<[31, 4294967295]> : vector<2xi32>
166
167  %0 = arith.andi %arg0, %cAllOnes_32 : vector<2xi32>
168
169  // CHECK: [[T1:%.*]] = arith.andi [[ARG0]], [[C31]]
170  %1 = arith.andi %0, %c31 : vector<2xi32>
171
172  // CHECK: [[T2:%.*]] = arith.andi [[T1]], [[CMIXED]]
173  %2 = arith.andi %1, %c_mixed : vector<2xi32>
174
175  // CHECK: return [[T2]]
176  return %2 : vector<2xi32>
177}
178
179// -----
180
181// CHECK-LABEL: func @addi_splat_vector
182func.func @addi_splat_vector() -> vector<8xi32> {
183  %0 = arith.constant dense<1> : vector<8xi32>
184  %1 = arith.constant dense<5> : vector<8xi32>
185
186  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<6> : vector<8xi32>
187  %2 = arith.addi %0, %1 : vector<8xi32>
188
189  // CHECK-NEXT: return [[C]]
190  return %2 : vector<8xi32>
191}
192
193// -----
194
195// CHECK-LABEL: func @simple_subf
196func.func @simple_subf() -> f32 {
197  %0 = arith.constant 4.5 : f32
198  %1 = arith.constant 1.5 : f32
199
200  // CHECK-NEXT: [[C:%.+]] = arith.constant 3.{{0*}}e+00 : f32
201  %2 = arith.subf %0, %1 : f32
202
203  // CHECK-NEXT: return [[C]]
204  return %2 : f32
205}
206
207// -----
208
209// CHECK-LABEL: func @subf_splat_vector
210func.func @subf_splat_vector() -> vector<4xf32> {
211  %0 = arith.constant dense<4.5> : vector<4xf32>
212  %1 = arith.constant dense<1.5> : vector<4xf32>
213
214  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<3.{{0*}}e+00> : vector<4xf32>
215  %2 = arith.subf %0, %1 : vector<4xf32>
216
217  // CHECK-NEXT: return [[C]]
218  return %2 : vector<4xf32>
219}
220
221// -----
222
223//      CHECK: func @simple_subi
224// CHECK-SAME:   [[ARG0:%[a-zA-Z0-9]+]]
225func.func @simple_subi(%arg0 : i32) -> (i32, i32) {
226  %0 = arith.constant 4 : i32
227  %1 = arith.constant 1 : i32
228  %2 = arith.constant 0 : i32
229
230  // CHECK-NEXT:[[C3:%.+]] = arith.constant 3 : i32
231  %3 = arith.subi %0, %1 : i32
232  %4 = arith.subi %arg0, %2 : i32
233
234  // CHECK-NEXT: return [[C3]], [[ARG0]]
235  return %3, %4 : i32, i32
236}
237
238// -----
239
240// CHECK-LABEL: func @subi_splat_tensor
241func.func @subi_splat_tensor() -> tensor<4xi32> {
242  %0 = arith.constant dense<4> : tensor<4xi32>
243  %1 = arith.constant dense<1> : tensor<4xi32>
244
245  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<3> : tensor<4xi32>
246  %2 = arith.subi %0, %1 : tensor<4xi32>
247
248  // CHECK-NEXT: return [[C]]
249  return %2 : tensor<4xi32>
250}
251
252// -----
253
254// CHECK-LABEL: func @affine_apply
255func.func @affine_apply(%variable : index) -> (index, index, index) {
256  %c177 = arith.constant 177 : index
257  %c211 = arith.constant 211 : index
258  %N = arith.constant 1075 : index
259
260  // CHECK:[[C1159:%.+]] = arith.constant 1159 : index
261  // CHECK:[[C1152:%.+]] = arith.constant 1152 : index
262  %x0 = affine.apply affine_map<(d0, d1)[S0] -> ( (d0 + 128 * S0) floordiv 128 + d1 mod 128)>
263           (%c177, %c211)[%N]
264  %x1 = affine.apply affine_map<(d0, d1)[S0] -> (128 * (S0 ceildiv 128))>
265           (%c177, %c211)[%N]
266
267  // CHECK:[[C42:%.+]] = arith.constant 42 : index
268  %y = affine.apply affine_map<(d0) -> (42)> (%variable)
269
270  // CHECK: return [[C1159]], [[C1152]], [[C42]]
271  return %x0, %x1, %y : index, index, index
272}
273
274// -----
275
276// CHECK-LABEL: func @simple_mulf
277func.func @simple_mulf() -> f32 {
278  %0 = arith.constant 4.5 : f32
279  %1 = arith.constant 1.5 : f32
280
281  // CHECK-NEXT: [[C:%.+]] = arith.constant 6.75{{0*}}e+00 : f32
282  %2 = arith.mulf %0, %1 : f32
283
284  // CHECK-NEXT: return [[C]]
285  return %2 : f32
286}
287
288// -----
289
290// CHECK-LABEL: func @mulf_splat_tensor
291func.func @mulf_splat_tensor() -> tensor<4xf32> {
292  %0 = arith.constant dense<4.5> : tensor<4xf32>
293  %1 = arith.constant dense<1.5> : tensor<4xf32>
294
295  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<6.75{{0*}}e+00> : tensor<4xf32>
296  %2 = arith.mulf %0, %1 : tensor<4xf32>
297
298  // CHECK-NEXT: return [[C]]
299  return %2 : tensor<4xf32>
300}
301
302// -----
303
304// CHECK-LABEL: func @simple_divi_signed
305func.func @simple_divi_signed() -> (i32, i32, i32) {
306  // CHECK-DAG: [[C0:%.+]] = arith.constant 0
307  %z = arith.constant 0 : i32
308  // CHECK-DAG: [[C6:%.+]] = arith.constant 6
309  %0 = arith.constant 6 : i32
310  %1 = arith.constant 2 : i32
311
312  // CHECK-NEXT: [[C3:%.+]] = arith.constant 3 : i32
313  %2 = arith.divsi %0, %1 : i32
314
315  %3 = arith.constant -2 : i32
316
317  // CHECK-NEXT: [[CM3:%.+]] = arith.constant -3 : i32
318  %4 = arith.divsi %0, %3 : i32
319
320  // CHECK-NEXT: [[XZ:%.+]] = arith.divsi [[C6]], [[C0]]
321  %5 = arith.divsi %0, %z : i32
322
323  // CHECK-NEXT: return [[C3]], [[CM3]], [[XZ]]
324  return %2, %4, %5 : i32, i32, i32
325}
326
327// -----
328
329// CHECK-LABEL: func @divi_signed_splat_tensor
330func.func @divi_signed_splat_tensor() -> (tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
331  // CHECK-DAG: [[C0:%.+]] = arith.constant dense<0>
332  %z = arith.constant dense<0> : tensor<4xi32>
333  // CHECK-DAG: [[C6:%.+]] = arith.constant dense<6>
334  %0 = arith.constant dense<6> : tensor<4xi32>
335  %1 = arith.constant dense<2> : tensor<4xi32>
336
337  // CHECK-NEXT: [[C3:%.+]] = arith.constant dense<3> : tensor<4xi32>
338  %2 = arith.divsi %0, %1 : tensor<4xi32>
339
340  %3 = arith.constant dense<-2> : tensor<4xi32>
341
342  // CHECK-NEXT: [[CM3:%.+]] = arith.constant dense<-3> : tensor<4xi32>
343  %4 = arith.divsi %0, %3 : tensor<4xi32>
344
345  // CHECK-NEXT: [[XZ:%.+]] = arith.divsi [[C6]], [[C0]]
346  %5 = arith.divsi %0, %z : tensor<4xi32>
347
348  // CHECK-NEXT: return [[C3]], [[CM3]], [[XZ]]
349  return %2, %4, %5 : tensor<4xi32>, tensor<4xi32>, tensor<4xi32>
350}
351
352// -----
353
354// CHECK-LABEL: func @simple_divi_unsigned
355func.func @simple_divi_unsigned() -> (i32, i32, i32) {
356  %z = arith.constant 0 : i32
357  // CHECK-DAG: [[C6:%.+]] = arith.constant 6
358  %0 = arith.constant 6 : i32
359  %1 = arith.constant 2 : i32
360
361  // CHECK-DAG: [[C3:%.+]] = arith.constant 3 : i32
362  %2 = arith.divui %0, %1 : i32
363
364  %3 = arith.constant -2 : i32
365
366  // Unsigned division interprets -2 as 2^32-2, so the result is 0.
367  // CHECK-DAG: [[C0:%.+]] = arith.constant 0 : i32
368  %4 = arith.divui %0, %3 : i32
369
370  // CHECK-NEXT: [[XZ:%.+]] = arith.divui [[C6]], [[C0]]
371  %5 = arith.divui %0, %z : i32
372
373  // CHECK-NEXT: return [[C3]], [[C0]], [[XZ]]
374  return %2, %4, %5 : i32, i32, i32
375}
376
377
378// -----
379
380// CHECK-LABEL: func @divi_unsigned_splat_tensor
381func.func @divi_unsigned_splat_tensor() -> (tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
382  %z = arith.constant dense<0> : tensor<4xi32>
383  // CHECK-DAG: [[C6:%.+]] = arith.constant dense<6>
384  %0 = arith.constant dense<6> : tensor<4xi32>
385  %1 = arith.constant dense<2> : tensor<4xi32>
386
387  // CHECK-DAG: [[C3:%.+]] = arith.constant dense<3> : tensor<4xi32>
388  %2 = arith.divui %0, %1 : tensor<4xi32>
389
390  %3 = arith.constant dense<-2> : tensor<4xi32>
391
392  // Unsigned division interprets -2 as 2^32-2, so the result is 0.
393  // CHECK-DAG: [[C0:%.+]] = arith.constant dense<0> : tensor<4xi32>
394  %4 = arith.divui %0, %3 : tensor<4xi32>
395
396  // CHECK-NEXT: [[XZ:%.+]] = arith.divui [[C6]], [[C0]]
397  %5 = arith.divui %0, %z : tensor<4xi32>
398
399  // CHECK-NEXT: return [[C3]], [[C0]], [[XZ]]
400  return %2, %4, %5 : tensor<4xi32>, tensor<4xi32>, tensor<4xi32>
401}
402
403// -----
404
405// CHECK-LABEL: func @simple_arith.floordivsi
406func.func @simple_arith.floordivsi() -> (i32, i32, i32, i32, i32) {
407  // CHECK-DAG: [[C0:%.+]] = arith.constant 0
408  %z = arith.constant 0 : i32
409  // CHECK-DAG: [[C6:%.+]] = arith.constant 7
410  %0 = arith.constant 7 : i32
411  %1 = arith.constant 2 : i32
412
413  // floor(7, 2) = 3
414  // CHECK-NEXT: [[C3:%.+]] = arith.constant 3 : i32
415  %2 = arith.floordivsi %0, %1 : i32
416
417  %3 = arith.constant -2 : i32
418
419  // floor(7, -2) = -4
420  // CHECK-NEXT: [[CM3:%.+]] = arith.constant -4 : i32
421  %4 = arith.floordivsi %0, %3 : i32
422
423  %5 = arith.constant -9 : i32
424
425  // floor(-9, 2) = -5
426  // CHECK-NEXT: [[CM4:%.+]] = arith.constant -5 : i32
427  %6 = arith.floordivsi %5, %1 : i32
428
429  %7 = arith.constant -13 : i32
430
431  // floor(-13, -2) = 6
432  // CHECK-NEXT: [[CM5:%.+]] = arith.constant 6 : i32
433  %8 = arith.floordivsi %7, %3 : i32
434
435  // CHECK-NEXT: [[XZ:%.+]] = arith.floordivsi [[C6]], [[C0]]
436  %9 = arith.floordivsi %0, %z : i32
437
438  return %2, %4, %6, %8, %9 : i32, i32, i32, i32, i32
439}
440
441// -----
442
443// CHECK-LABEL: func @simple_arith.ceildivsi
444func.func @simple_arith.ceildivsi() -> (i32, i32, i32, i32, i32) {
445  // CHECK-DAG: [[C0:%.+]] = arith.constant 0
446  %z = arith.constant 0 : i32
447  // CHECK-DAG: [[C6:%.+]] = arith.constant 7
448  %0 = arith.constant 7 : i32
449  %1 = arith.constant 2 : i32
450
451  // ceil(7, 2) = 4
452  // CHECK-NEXT: [[C3:%.+]] = arith.constant 4 : i32
453  %2 = arith.ceildivsi %0, %1 : i32
454
455  %3 = arith.constant -2 : i32
456
457  // ceil(7, -2) = -3
458  // CHECK-NEXT: [[CM3:%.+]] = arith.constant -3 : i32
459  %4 = arith.ceildivsi %0, %3 : i32
460
461  %5 = arith.constant -9 : i32
462
463  // ceil(-9, 2) = -4
464  // CHECK-NEXT: [[CM4:%.+]] = arith.constant -4 : i32
465  %6 = arith.ceildivsi %5, %1 : i32
466
467  %7 = arith.constant -15 : i32
468
469  // ceil(-15, -2) = 8
470  // CHECK-NEXT: [[CM5:%.+]] = arith.constant 8 : i32
471  %8 = arith.ceildivsi %7, %3 : i32
472
473  // CHECK-NEXT: [[XZ:%.+]] = arith.ceildivsi [[C6]], [[C0]]
474  %9 = arith.ceildivsi %0, %z : i32
475
476  return %2, %4, %6, %8, %9 : i32, i32, i32, i32, i32
477}
478
479// -----
480
481// CHECK-LABEL: func @simple_arith.ceildivsi_overflow
482func.func @simple_arith.ceildivsi_overflow() -> (i8, i16, i32) {
483  // The negative values below are MININTs for the corresponding bit-width. The
484  // folder will try to negate them (so that the division operates on two
485  // positive numbers), but that would cause overflow (negating MININT
486  // overflows). Hence folding should not happen and the original ceildivsi is
487  // preserved.
488
489  // TODO: The folder should be able to fold the following by avoiding
490  // intermediate operations that overflow.
491
492  // CHECK-DAG: %[[C_1:.*]] = arith.constant 7 : i8
493  // CHECK-DAG: %[[MIN_I8:.*]] = arith.constant -128 : i8
494  // CHECK-DAG: %[[C_2:.*]] = arith.constant 7 : i16
495  // CHECK-DAG: %[[MIN_I16:.*]] = arith.constant -32768 : i16
496  // CHECK-DAG: %[[C_3:.*]] = arith.constant 7 : i32
497  // CHECK-DAG: %[[MIN_I32:.*]] = arith.constant -2147483648 : i32
498
499  // CHECK-NEXT: %[[CEILDIV_1:.*]] = arith.ceildivsi %[[MIN_I8]], %[[C_1]]  : i8
500  %0 = arith.constant 7 : i8
501  %min_int_i8 = arith.constant -128 : i8
502  %2 = arith.ceildivsi %min_int_i8, %0 : i8
503
504  // CHECK-NEXT: %[[CEILDIV_2:.*]] = arith.ceildivsi %[[MIN_I16]], %[[C_2]]  : i16
505  %3 = arith.constant 7 : i16
506  %min_int_i16 = arith.constant -32768 : i16
507  %5 = arith.ceildivsi %min_int_i16, %3 : i16
508
509  // CHECK-NEXT: %[[CEILDIV_2:.*]] = arith.ceildivsi %[[MIN_I32]], %[[C_3]]  : i32
510  %6 = arith.constant 7 : i32
511  %min_int_i32 = arith.constant -2147483648 : i32
512  %8 = arith.ceildivsi %min_int_i32, %6 : i32
513
514  return %2, %5, %8 : i8, i16, i32
515}
516
517// -----
518
519// CHECK-LABEL: func @simple_arith.ceildivui
520func.func @simple_arith.ceildivui() -> (i32, i32, i32, i32, i32) {
521  // CHECK-DAG: [[C0:%.+]] = arith.constant 0
522  %z = arith.constant 0 : i32
523  // CHECK-DAG: [[C6:%.+]] = arith.constant 7
524  %0 = arith.constant 7 : i32
525  %1 = arith.constant 2 : i32
526
527  // ceil(7, 2) = 4
528  // CHECK-NEXT: [[C3:%.+]] = arith.constant 4 : i32
529  %2 = arith.ceildivui %0, %1 : i32
530
531  %3 = arith.constant -2 : i32
532
533  // ceil(7, -2) = 0
534  // CHECK-NEXT: [[CM1:%.+]] = arith.constant 1 : i32
535  %4 = arith.ceildivui %0, %3 : i32
536
537  %5 = arith.constant -8 : i32
538
539  // ceil(-8, 2) = 2147483644
540  // CHECK-NEXT: [[CM4:%.+]] = arith.constant 2147483644 : i32
541  %6 = arith.ceildivui %5, %1 : i32
542
543  %7 = arith.constant -15 : i32
544
545  // ceil(-15, -2) = 0
546  // CHECK-NOT: arith.constant 1 : i32
547  %8 = arith.ceildivui %7, %3 : i32
548
549  // CHECK-NEXT: [[XZ:%.+]] = arith.ceildivui [[C6]], [[C0]]
550  %9 = arith.ceildivui %0, %z : i32
551
552  return %2, %4, %6, %8, %9 : i32, i32, i32, i32, i32
553}
554
555// -----
556
557// CHECK-LABEL: func @simple_arith.remsi
558func.func @simple_arith.remsi(%a : i32) -> (i32, i32, i32) {
559  %0 = arith.constant 5 : i32
560  %1 = arith.constant 2 : i32
561  %2 = arith.constant 1 : i32
562  %3 = arith.constant -2 : i32
563
564  // CHECK-NEXT:[[C1:%.+]] = arith.constant 1 : i32
565  %4 = arith.remsi %0, %1 : i32
566  %5 = arith.remsi %0, %3 : i32
567  // CHECK-NEXT:[[C0:%.+]] = arith.constant 0 : i32
568  %6 = arith.remsi %a, %2 : i32
569
570  // CHECK-NEXT: return [[C1]], [[C1]], [[C0]] : i32, i32, i32
571  return %4, %5, %6 : i32, i32, i32
572}
573
574// -----
575
576// CHECK-LABEL: func @simple_arith.remui
577func.func @simple_arith.remui(%a : i32) -> (i32, i32, i32) {
578  %0 = arith.constant 5 : i32
579  %1 = arith.constant 2 : i32
580  %2 = arith.constant 1 : i32
581  %3 = arith.constant -2 : i32
582
583  // CHECK-DAG:[[C1:%.+]] = arith.constant 1 : i32
584  %4 = arith.remui %0, %1 : i32
585  // CHECK-DAG:[[C5:%.+]] = arith.constant 5 : i32
586  %5 = arith.remui %0, %3 : i32
587  // CHECK-DAG:[[C0:%.+]] = arith.constant 0 : i32
588  %6 = arith.remui %a, %2 : i32
589
590  // CHECK-NEXT: return [[C1]], [[C5]], [[C0]] : i32, i32, i32
591  return %4, %5, %6 : i32, i32, i32
592}
593
594// -----
595
596// CHECK-LABEL: func @muli
597func.func @muli() -> i32 {
598  %0 = arith.constant 4 : i32
599  %1 = arith.constant 2 : i32
600
601  // CHECK-NEXT:[[C8:%.+]] = arith.constant 8 : i32
602  %2 = arith.muli %0, %1 : i32
603
604  // CHECK-NEXT: return [[C8]]
605  return %2 : i32
606}
607
608// -----
609
610// CHECK-LABEL: func @muli_splat_vector
611func.func @muli_splat_vector() -> vector<4xi32> {
612  %0 = arith.constant dense<4> : vector<4xi32>
613  %1 = arith.constant dense<2> : vector<4xi32>
614
615  // CHECK-NEXT: [[C:%.+]] = arith.constant dense<8> : vector<4xi32>
616  %2 = arith.muli %0, %1 : vector<4xi32>
617
618  // CHECK-NEXT: return [[C]]
619  return %2 : vector<4xi32>
620}
621
622// CHECK-LABEL: func @dim
623func.func @dim(%x : tensor<8x4xf32>) -> index {
624
625  // CHECK:[[C4:%.+]] = arith.constant 4 : index
626  %c1 = arith.constant 1 : index
627  %0 = tensor.dim %x, %c1 : tensor<8x4xf32>
628
629  // CHECK-NEXT: return [[C4]]
630  return %0 : index
631}
632
633// -----
634
635// CHECK-LABEL: func @cmpi
636func.func @cmpi() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
637  %c42 = arith.constant 42 : i32
638  %cm1 = arith.constant -1 : i32
639  // CHECK-DAG: [[F:%.+]] = arith.constant false
640  // CHECK-DAG: [[T:%.+]] = arith.constant true
641  // CHECK-NEXT: return [[F]],
642  %0 = arith.cmpi eq, %c42, %cm1 : i32
643  // CHECK-SAME: [[T]],
644  %1 = arith.cmpi ne, %c42, %cm1 : i32
645  // CHECK-SAME: [[F]],
646  %2 = arith.cmpi slt, %c42, %cm1 : i32
647  // CHECK-SAME: [[F]],
648  %3 = arith.cmpi sle, %c42, %cm1 : i32
649  // CHECK-SAME: [[T]],
650  %4 = arith.cmpi sgt, %c42, %cm1 : i32
651  // CHECK-SAME: [[T]],
652  %5 = arith.cmpi sge, %c42, %cm1 : i32
653  // CHECK-SAME: [[T]],
654  %6 = arith.cmpi ult, %c42, %cm1 : i32
655  // CHECK-SAME: [[T]],
656  %7 = arith.cmpi ule, %c42, %cm1 : i32
657  // CHECK-SAME: [[F]],
658  %8 = arith.cmpi ugt, %c42, %cm1 : i32
659  // CHECK-SAME: [[F]]
660  %9 = arith.cmpi uge, %c42, %cm1 : i32
661  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1
662}
663
664// -----
665
666// CHECK-LABEL: func @cmpf_normal_numbers
667func.func @cmpf_normal_numbers() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
668  %c42 = arith.constant 42. : f32
669  %cm1 = arith.constant -1. : f32
670  // CHECK-DAG: [[F:%.+]] = arith.constant false
671  // CHECK-DAG: [[T:%.+]] = arith.constant true
672  // CHECK-NEXT: return [[F]],
673  %0 = arith.cmpf false, %c42, %cm1 : f32
674  // CHECK-SAME: [[F]],
675  %1 = arith.cmpf oeq, %c42, %cm1 : f32
676  // CHECK-SAME: [[T]],
677  %2 = arith.cmpf ogt, %c42, %cm1 : f32
678  // CHECK-SAME: [[T]],
679  %3 = arith.cmpf oge, %c42, %cm1 : f32
680  // CHECK-SAME: [[F]],
681  %4 = arith.cmpf olt, %c42, %cm1 : f32
682  // CHECK-SAME: [[F]],
683  %5 = arith.cmpf ole, %c42, %cm1 : f32
684  // CHECK-SAME: [[T]],
685  %6 = arith.cmpf one, %c42, %cm1 : f32
686  // CHECK-SAME: [[T]],
687  %7 = arith.cmpf ord, %c42, %cm1 : f32
688  // CHECK-SAME: [[F]],
689  %8 = arith.cmpf ueq, %c42, %cm1 : f32
690  // CHECK-SAME: [[T]],
691  %9 = arith.cmpf ugt, %c42, %cm1 : f32
692  // CHECK-SAME: [[T]],
693  %10 = arith.cmpf uge, %c42, %cm1 : f32
694  // CHECK-SAME: [[F]],
695  %11 = arith.cmpf ult, %c42, %cm1 : f32
696  // CHECK-SAME: [[F]],
697  %12 = arith.cmpf ule, %c42, %cm1 : f32
698  // CHECK-SAME: [[T]],
699  %13 = arith.cmpf une, %c42, %cm1 : f32
700  // CHECK-SAME: [[F]],
701  %14 = arith.cmpf uno, %c42, %cm1 : f32
702  // CHECK-SAME: [[T]]
703  %15 = arith.cmpf true, %c42, %cm1 : f32
704  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1
705}
706
707// -----
708
709// CHECK-LABEL: func @cmpf_nan
710func.func @cmpf_nan() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
711  %c42 = arith.constant 42. : f32
712  %cqnan = arith.constant 0xFFFFFFFF : f32
713  // CHECK-DAG: [[F:%.+]] = arith.constant false
714  // CHECK-DAG: [[T:%.+]] = arith.constant true
715  // CHECK-NEXT: return [[F]],
716  %0 = arith.cmpf false, %c42, %cqnan : f32
717  // CHECK-SAME: [[F]]
718  %1 = arith.cmpf oeq, %c42, %cqnan : f32
719  // CHECK-SAME: [[F]],
720  %2 = arith.cmpf ogt, %c42, %cqnan : f32
721  // CHECK-SAME: [[F]],
722  %3 = arith.cmpf oge, %c42, %cqnan : f32
723  // CHECK-SAME: [[F]],
724  %4 = arith.cmpf olt, %c42, %cqnan : f32
725  // CHECK-SAME: [[F]],
726  %5 = arith.cmpf ole, %c42, %cqnan : f32
727  // CHECK-SAME: [[F]],
728  %6 = arith.cmpf one, %c42, %cqnan : f32
729  // CHECK-SAME: [[F]],
730  %7 = arith.cmpf ord, %c42, %cqnan : f32
731  // CHECK-SAME: [[T]],
732  %8 = arith.cmpf ueq, %c42, %cqnan : f32
733  // CHECK-SAME: [[T]],
734  %9 = arith.cmpf ugt, %c42, %cqnan : f32
735  // CHECK-SAME: [[T]],
736  %10 = arith.cmpf uge, %c42, %cqnan : f32
737  // CHECK-SAME: [[T]],
738  %11 = arith.cmpf ult, %c42, %cqnan : f32
739  // CHECK-SAME: [[T]],
740  %12 = arith.cmpf ule, %c42, %cqnan : f32
741  // CHECK-SAME: [[T]],
742  %13 = arith.cmpf une, %c42, %cqnan : f32
743  // CHECK-SAME: [[T]],
744  %14 = arith.cmpf uno, %c42, %cqnan : f32
745  // CHECK-SAME: [[T]]
746  %15 = arith.cmpf true, %c42, %cqnan : f32
747  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1
748}
749
750// -----
751
752// CHECK-LABEL: func @cmpf_inf
753func.func @cmpf_inf() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
754  %c42 = arith.constant 42. : f32
755  %cpinf = arith.constant 0x7F800000 : f32
756  // CHECK-DAG: [[F:%.+]] = arith.constant false
757  // CHECK-DAG: [[T:%.+]] = arith.constant true
758  // CHECK-NEXT: return [[F]],
759  %0 = arith.cmpf false, %c42, %cpinf: f32
760  // CHECK-SAME: [[F]]
761  %1 = arith.cmpf oeq, %c42, %cpinf: f32
762  // CHECK-SAME: [[F]],
763  %2 = arith.cmpf ogt, %c42, %cpinf: f32
764  // CHECK-SAME: [[F]],
765  %3 = arith.cmpf oge, %c42, %cpinf: f32
766  // CHECK-SAME: [[T]],
767  %4 = arith.cmpf olt, %c42, %cpinf: f32
768  // CHECK-SAME: [[T]],
769  %5 = arith.cmpf ole, %c42, %cpinf: f32
770  // CHECK-SAME: [[T]],
771  %6 = arith.cmpf one, %c42, %cpinf: f32
772  // CHECK-SAME: [[T]],
773  %7 = arith.cmpf ord, %c42, %cpinf: f32
774  // CHECK-SAME: [[F]],
775  %8 = arith.cmpf ueq, %c42, %cpinf: f32
776  // CHECK-SAME: [[F]],
777  %9 = arith.cmpf ugt, %c42, %cpinf: f32
778  // CHECK-SAME: [[F]],
779  %10 = arith.cmpf uge, %c42, %cpinf: f32
780  // CHECK-SAME: [[T]],
781  %11 = arith.cmpf ult, %c42, %cpinf: f32
782  // CHECK-SAME: [[T]],
783  %12 = arith.cmpf ule, %c42, %cpinf: f32
784  // CHECK-SAME: [[T]],
785  %13 = arith.cmpf une, %c42, %cpinf: f32
786  // CHECK-SAME: [[F]],
787  %14 = arith.cmpf uno, %c42, %cpinf: f32
788  // CHECK-SAME: [[T]]
789  %15 = arith.cmpf true, %c42, %cpinf: f32
790  return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14, %15 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1
791}
792
793// -----
794
795// CHECK-LABEL: func @nested_isolated_region
796func.func @nested_isolated_region() {
797  // CHECK-NEXT: builtin.module {
798  // CHECK-NEXT: func @isolated_op
799  // CHECK-NEXT: arith.constant 2
800  builtin.module {
801    func.func @isolated_op() {
802      %0 = arith.constant 1 : i32
803      %2 = arith.addi %0, %0 : i32
804      "foo.yield"(%2) : (i32) -> ()
805    }
806  }
807
808  // CHECK: "foo.unknown_region"
809  // CHECK-NEXT: arith.constant 2
810  "foo.unknown_region"() ({
811    %0 = arith.constant 1 : i32
812    %2 = arith.addi %0, %0 : i32
813    "foo.yield"(%2) : (i32) -> ()
814  }) : () -> ()
815  return
816}
817
818// -----
819
820// CHECK-LABEL: func @custom_insertion_position
821func.func @custom_insertion_position() {
822  // CHECK: test.one_region_op
823  // CHECK-NEXT: arith.constant 2
824  "test.one_region_op"() ({
825
826    %0 = arith.constant 1 : i32
827    %2 = arith.addi %0, %0 : i32
828    "foo.yield"(%2) : (i32) -> ()
829  }) : () -> ()
830  return
831}
832
833// -----
834
835// CHECK-LABEL: func @subview_scalar_fold
836func.func @subview_scalar_fold(%arg0: memref<f32>) -> memref<f32> {
837  // CHECK-NOT: memref.subview
838  %c = memref.subview %arg0[] [] [] : memref<f32> to memref<f32>
839  return %c : memref<f32>
840}
841