1 // RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -test-constant-fold | FileCheck %s
5 // CHECK-LABEL: @affine_for
6 // CHECK-SAME: [[ARG:%[a-zA-Z0-9]+]]
7 func.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
14 %2 = arith.addf %0, %1 : f32
16 // CHECK-NEXT: memref.store [[C]], [[ARG]][]
17 memref.store %2, %p[] : memref<f32>
25 // CHECK-LABEL: func @simple_addf
26 func.func @simple_addf() -> f32 {
27 %0 = arith.constant 4.5 : f32
28 %1 = arith.constant 1.5 : f32
30 // CHECK-NEXT: [[C:%.+]] = arith.constant 6.{{0*}}e+00 : f32
31 %2 = arith.addf %0, %1 : f32
33 // CHECK-NEXT: return [[C]]
39 // CHECK-LABEL: func @addf_splat_tensor
40 func.func @addf_splat_tensor() -> tensor<4xf32> {
41 %0 = arith.constant dense<4.5> : tensor<4xf32>
42 %1 = arith.constant dense<1.5> : tensor<4xf32>
44 // CHECK-NEXT: [[C:%.+]] = arith.constant dense<6.{{0*}}e+00> : tensor<4xf32>
45 %2 = arith.addf %0, %1 : tensor<4xf32>
47 // CHECK-NEXT: return [[C]]
48 return %2 : tensor<4xf32>
53 // CHECK-LABEL: func @addf_dense_tensor
54 func.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>
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>
61 // CHECK-NEXT: return [[C]]
62 return %2 : tensor<4xf32>
67 // CHECK-LABEL: func @addf_dense_and_splat_tensors
68 func.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>
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>
75 // CHECK-NEXT: return [[C]]
76 return %2 : tensor<4xf32>
81 // CHECK-LABEL: func @simple_addi
82 func.func @simple_addi() -> i32 {
83 %0 = arith.constant 1 : i32
84 %1 = arith.constant 5 : i32
86 // CHECK-NEXT: [[C:%.+]] = arith.constant 6 : i32
87 %2 = arith.addi %0, %1 : i32
89 // CHECK-NEXT: return [[C]]
95 // CHECK: func @simple_and
96 // CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: i1
97 // CHECK-SAME: [[ARG1:%[a-zA-Z0-9]+]]: i32)
98 func.func @simple_and(%arg0 : i1, %arg1 : i32) -> (i1, i32) {
99 %c1 = arith.constant 1 : i1
100 %cAllOnes_32 = arith.constant 4294967295 : i32
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
107 // CHECK: [[VAL:%.*]] = arith.andi [[ARG1]], [[C31]]
108 %3 = arith.andi %2, %c31 : i32
110 // CHECK: return [[ARG0]], [[VAL]]
111 return %1, %3 : i1, i32
116 // CHECK-LABEL: func @and_index
117 // CHECK-SAME: [[ARG:%[a-zA-Z0-9]+]]
118 func.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
124 // CHECK: arith.andi [[ARG]], [[C31]]
125 %2 = arith.andi %1, %c_AllOnes : index
131 // CHECK: func @tensor_and
132 // CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: tensor<2xi32>
133 func.func @tensor_and(%arg0 : tensor<2xi32>) -> tensor<2xi32> {
134 %cAllOnes_32 = arith.constant dense<4294967295> : tensor<2xi32>
136 // CHECK: [[C31:%.*]] = arith.constant dense<31> : tensor<2xi32>
137 %c31 = arith.constant dense<31> : tensor<2xi32>
139 // CHECK: [[CMIXED:%.*]] = arith.constant dense<[31, -1]> : tensor<2xi32>
140 %c_mixed = arith.constant dense<[31, 4294967295]> : tensor<2xi32>
142 %0 = arith.andi %arg0, %cAllOnes_32 : tensor<2xi32>
144 // CHECK: [[T1:%.*]] = arith.andi [[ARG0]], [[C31]]
145 %1 = arith.andi %0, %c31 : tensor<2xi32>
147 // CHECK: [[T2:%.*]] = arith.andi [[T1]], [[CMIXED]]
148 %2 = arith.andi %1, %c_mixed : tensor<2xi32>
150 // CHECK: return [[T2]]
151 return %2 : tensor<2xi32>
156 // CHECK: func @vector_and
157 // CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: vector<2xi32>
158 func.func @vector_and(%arg0 : vector<2xi32>) -> vector<2xi32> {
159 %cAllOnes_32 = arith.constant dense<4294967295> : vector<2xi32>
161 // CHECK: [[C31:%.*]] = arith.constant dense<31> : vector<2xi32>
162 %c31 = arith.constant dense<31> : vector<2xi32>
164 // CHECK: [[CMIXED:%.*]] = arith.constant dense<[31, -1]> : vector<2xi32>
165 %c_mixed = arith.constant dense<[31, 4294967295]> : vector<2xi32>
167 %0 = arith.andi %arg0, %cAllOnes_32 : vector<2xi32>
169 // CHECK: [[T1:%.*]] = arith.andi [[ARG0]], [[C31]]
170 %1 = arith.andi %0, %c31 : vector<2xi32>
172 // CHECK: [[T2:%.*]] = arith.andi [[T1]], [[CMIXED]]
173 %2 = arith.andi %1, %c_mixed : vector<2xi32>
175 // CHECK: return [[T2]]
176 return %2 : vector<2xi32>
181 // CHECK-LABEL: func @addi_splat_vector
182 func.func @addi_splat_vector() -> vector<8xi32> {
183 %0 = arith.constant dense<1> : vector<8xi32>
184 %1 = arith.constant dense<5> : vector<8xi32>
186 // CHECK-NEXT: [[C:%.+]] = arith.constant dense<6> : vector<8xi32>
187 %2 = arith.addi %0, %1 : vector<8xi32>
189 // CHECK-NEXT: return [[C]]
190 return %2 : vector<8xi32>
195 // CHECK-LABEL: func @simple_subf
196 func.func @simple_subf() -> f32 {
197 %0 = arith.constant 4.5 : f32
198 %1 = arith.constant 1.5 : f32
200 // CHECK-NEXT: [[C:%.+]] = arith.constant 3.{{0*}}e+00 : f32
201 %2 = arith.subf %0, %1 : f32
203 // CHECK-NEXT: return [[C]]
209 // CHECK-LABEL: func @subf_splat_vector
210 func.func @subf_splat_vector() -> vector<4xf32> {
211 %0 = arith.constant dense<4.5> : vector<4xf32>
212 %1 = arith.constant dense<1.5> : vector<4xf32>
214 // CHECK-NEXT: [[C:%.+]] = arith.constant dense<3.{{0*}}e+00> : vector<4xf32>
215 %2 = arith.subf %0, %1 : vector<4xf32>
217 // CHECK-NEXT: return [[C]]
218 return %2 : vector<4xf32>
223 // CHECK: func @simple_subi
224 // CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]
225 func.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
230 // CHECK-NEXT:[[C3:%.+]] = arith.constant 3 : i32
231 %3 = arith.subi %0, %1 : i32
232 %4 = arith.subi %arg0, %2 : i32
234 // CHECK-NEXT: return [[C3]], [[ARG0]]
235 return %3, %4 : i32, i32
240 // CHECK-LABEL: func @subi_splat_tensor
241 func.func @subi_splat_tensor() -> tensor<4xi32> {
242 %0 = arith.constant dense<4> : tensor<4xi32>
243 %1 = arith.constant dense<1> : tensor<4xi32>
245 // CHECK-NEXT: [[C:%.+]] = arith.constant dense<3> : tensor<4xi32>
246 %2 = arith.subi %0, %1 : tensor<4xi32>
248 // CHECK-NEXT: return [[C]]
249 return %2 : tensor<4xi32>
254 // CHECK-LABEL: func @affine_apply
255 func.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
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)>
264 %x1 = affine.apply affine_map<(d0, d1)[S0] -> (128 * (S0 ceildiv 128))>
267 // CHECK:[[C42:%.+]] = arith.constant 42 : index
268 %y = affine.apply affine_map<(d0) -> (42)> (%variable)
270 // CHECK: return [[C1159]], [[C1152]], [[C42]]
271 return %x0, %x1, %y : index, index, index
276 // CHECK-LABEL: func @simple_mulf
277 func.func @simple_mulf() -> f32 {
278 %0 = arith.constant 4.5 : f32
279 %1 = arith.constant 1.5 : f32
281 // CHECK-NEXT: [[C:%.+]] = arith.constant 6.75{{0*}}e+00 : f32
282 %2 = arith.mulf %0, %1 : f32
284 // CHECK-NEXT: return [[C]]
290 // CHECK-LABEL: func @mulf_splat_tensor
291 func.func @mulf_splat_tensor() -> tensor<4xf32> {
292 %0 = arith.constant dense<4.5> : tensor<4xf32>
293 %1 = arith.constant dense<1.5> : tensor<4xf32>
295 // CHECK-NEXT: [[C:%.+]] = arith.constant dense<6.75{{0*}}e+00> : tensor<4xf32>
296 %2 = arith.mulf %0, %1 : tensor<4xf32>
298 // CHECK-NEXT: return [[C]]
299 return %2 : tensor<4xf32>
304 // CHECK-LABEL: func @simple_divi_signed
305 func.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
312 // CHECK-NEXT: [[C3:%.+]] = arith.constant 3 : i32
313 %2 = arith.divsi %0, %1 : i32
315 %3 = arith.constant -2 : i32
317 // CHECK-NEXT: [[CM3:%.+]] = arith.constant -3 : i32
318 %4 = arith.divsi %0, %3 : i32
320 // CHECK-NEXT: [[XZ:%.+]] = arith.divsi [[C6]], [[C0]]
321 %5 = arith.divsi %0, %z : i32
323 // CHECK-NEXT: return [[C3]], [[CM3]], [[XZ]]
324 return %2, %4, %5 : i32, i32, i32
329 // CHECK-LABEL: func @divi_signed_splat_tensor
330 func.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>
337 // CHECK-NEXT: [[C3:%.+]] = arith.constant dense<3> : tensor<4xi32>
338 %2 = arith.divsi %0, %1 : tensor<4xi32>
340 %3 = arith.constant dense<-2> : tensor<4xi32>
342 // CHECK-NEXT: [[CM3:%.+]] = arith.constant dense<-3> : tensor<4xi32>
343 %4 = arith.divsi %0, %3 : tensor<4xi32>
345 // CHECK-NEXT: [[XZ:%.+]] = arith.divsi [[C6]], [[C0]]
346 %5 = arith.divsi %0, %z : tensor<4xi32>
348 // CHECK-NEXT: return [[C3]], [[CM3]], [[XZ]]
349 return %2, %4, %5 : tensor<4xi32>, tensor<4xi32>, tensor<4xi32>
354 // CHECK-LABEL: func @simple_divi_unsigned
355 func.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
361 // CHECK-DAG: [[C3:%.+]] = arith.constant 3 : i32
362 %2 = arith.divui %0, %1 : i32
364 %3 = arith.constant -2 : i32
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
370 // CHECK-NEXT: [[XZ:%.+]] = arith.divui [[C6]], [[C0]]
371 %5 = arith.divui %0, %z : i32
373 // CHECK-NEXT: return [[C3]], [[C0]], [[XZ]]
374 return %2, %4, %5 : i32, i32, i32
380 // CHECK-LABEL: func @divi_unsigned_splat_tensor
381 func.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>
387 // CHECK-DAG: [[C3:%.+]] = arith.constant dense<3> : tensor<4xi32>
388 %2 = arith.divui %0, %1 : tensor<4xi32>
390 %3 = arith.constant dense<-2> : tensor<4xi32>
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>
396 // CHECK-NEXT: [[XZ:%.+]] = arith.divui [[C6]], [[C0]]
397 %5 = arith.divui %0, %z : tensor<4xi32>
399 // CHECK-NEXT: return [[C3]], [[C0]], [[XZ]]
400 return %2, %4, %5 : tensor<4xi32>, tensor<4xi32>, tensor<4xi32>
405 // CHECK-LABEL: func @simple_arith.floordivsi
406 func.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
414 // CHECK-NEXT: [[C3:%.+]] = arith.constant 3 : i32
415 %2 = arith.floordivsi %0, %1 : i32
417 %3 = arith.constant -2 : i32
420 // CHECK-NEXT: [[CM3:%.+]] = arith.constant -4 : i32
421 %4 = arith.floordivsi %0, %3 : i32
423 %5 = arith.constant -9 : i32
426 // CHECK-NEXT: [[CM4:%.+]] = arith.constant -5 : i32
427 %6 = arith.floordivsi %5, %1 : i32
429 %7 = arith.constant -13 : i32
431 // floor(-13, -2) = 6
432 // CHECK-NEXT: [[CM5:%.+]] = arith.constant 6 : i32
433 %8 = arith.floordivsi %7, %3 : i32
435 // CHECK-NEXT: [[XZ:%.+]] = arith.floordivsi [[C6]], [[C0]]
436 %9 = arith.floordivsi %0, %z : i32
438 return %2, %4, %6, %8, %9 : i32, i32, i32, i32, i32
443 // CHECK-LABEL: func @simple_arith.ceildivsi
444 func.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
452 // CHECK-NEXT: [[C3:%.+]] = arith.constant 4 : i32
453 %2 = arith.ceildivsi %0, %1 : i32
455 %3 = arith.constant -2 : i32
458 // CHECK-NEXT: [[CM3:%.+]] = arith.constant -3 : i32
459 %4 = arith.ceildivsi %0, %3 : i32
461 %5 = arith.constant -9 : i32
464 // CHECK-NEXT: [[CM4:%.+]] = arith.constant -4 : i32
465 %6 = arith.ceildivsi %5, %1 : i32
467 %7 = arith.constant -15 : i32
470 // CHECK-NEXT: [[CM5:%.+]] = arith.constant 8 : i32
471 %8 = arith.ceildivsi %7, %3 : i32
473 // CHECK-NEXT: [[XZ:%.+]] = arith.ceildivsi [[C6]], [[C0]]
474 %9 = arith.ceildivsi %0, %z : i32
476 return %2, %4, %6, %8, %9 : i32, i32, i32, i32, i32
481 // CHECK-LABEL: func @simple_arith.ceildivsi_overflow
482 func.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
489 // TODO: The folder should be able to fold the following by avoiding
490 // intermediate operations that overflow.
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
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
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
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
514 return %2, %5, %8 : i8, i16, i32
519 // CHECK-LABEL: func @simple_arith.ceildivui
520 func.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
528 // CHECK-NEXT: [[C3:%.+]] = arith.constant 4 : i32
529 %2 = arith.ceildivui %0, %1 : i32
531 %3 = arith.constant -2 : i32
534 // CHECK-NEXT: [[CM1:%.+]] = arith.constant 1 : i32
535 %4 = arith.ceildivui %0, %3 : i32
537 %5 = arith.constant -8 : i32
539 // ceil(-8, 2) = 2147483644
540 // CHECK-NEXT: [[CM4:%.+]] = arith.constant 2147483644 : i32
541 %6 = arith.ceildivui %5, %1 : i32
543 %7 = arith.constant -15 : i32
546 // CHECK-NOT: arith.constant 1 : i32
547 %8 = arith.ceildivui %7, %3 : i32
549 // CHECK-NEXT: [[XZ:%.+]] = arith.ceildivui [[C6]], [[C0]]
550 %9 = arith.ceildivui %0, %z : i32
552 return %2, %4, %6, %8, %9 : i32, i32, i32, i32, i32
557 // CHECK-LABEL: func @simple_arith.remsi
558 func.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
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
570 // CHECK-NEXT: return [[C1]], [[C1]], [[C0]] : i32, i32, i32
571 return %4, %5, %6 : i32, i32, i32
576 // CHECK-LABEL: func @simple_arith.remui
577 func.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
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
590 // CHECK-NEXT: return [[C1]], [[C5]], [[C0]] : i32, i32, i32
591 return %4, %5, %6 : i32, i32, i32
596 // CHECK-LABEL: func @muli
597 func.func @muli() -> i32 {
598 %0 = arith.constant 4 : i32
599 %1 = arith.constant 2 : i32
601 // CHECK-NEXT:[[C8:%.+]] = arith.constant 8 : i32
602 %2 = arith.muli %0, %1 : i32
604 // CHECK-NEXT: return [[C8]]
610 // CHECK-LABEL: func @muli_splat_vector
611 func.func @muli_splat_vector() -> vector<4xi32> {
612 %0 = arith.constant dense<4> : vector<4xi32>
613 %1 = arith.constant dense<2> : vector<4xi32>
615 // CHECK-NEXT: [[C:%.+]] = arith.constant dense<8> : vector<4xi32>
616 %2 = arith.muli %0, %1 : vector<4xi32>
618 // CHECK-NEXT: return [[C]]
619 return %2 : vector<4xi32>
622 // CHECK-LABEL: func @dim
623 func.func @dim(%x : tensor<8x4xf32>) -> index {
625 // CHECK:[[C4:%.+]] = arith.constant 4 : index
626 %c1 = arith.constant 1 : index
627 %0 = tensor.dim %x, %c1 : tensor<8x4xf32>
629 // CHECK-NEXT: return [[C4]]
635 // CHECK-LABEL: func @cmpi
636 func.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
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
666 // CHECK-LABEL: func @cmpf_normal_numbers
667 func.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
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
709 // CHECK-LABEL: func @cmpf_nan
710 func.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
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
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
752 // CHECK-LABEL: func @cmpf_inf
753 func.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
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
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
795 // CHECK-LABEL: func @nested_isolated_region
796 func.func @nested_isolated_region() {
797 // CHECK-NEXT: builtin.module {
798 // CHECK-NEXT: func @isolated_op
799 // CHECK-NEXT: arith.constant 2
801 func.func @isolated_op() {
802 %0 = arith.constant 1 : i32
803 %2 = arith.addi %0, %0 : i32
804 "foo.yield"(%2) : (i32) -> ()
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) -> ()
820 // CHECK-LABEL: func @custom_insertion_position
821 func.func @custom_insertion_position() {
822 // CHECK: test.one_region_op
823 // CHECK-NEXT: arith.constant 2
824 "test.one_region_op"() ({
826 %0 = arith.constant 1 : i32
827 %2 = arith.addi %0, %0 : i32
828 "foo.yield"(%2) : (i32) -> ()
835 // CHECK-LABEL: func @subview_scalar_fold
836 func.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>