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