712 lines · plain
1// RUN: mlir-opt %s -canonicalize | FileCheck %s2 3// CHECK-LABEL: @add4func.func @add() -> (index, index) {5 %0 = index.constant 16 %1 = index.constant 21007 %2 = index.constant 30000000018 %3 = index.constant 40000021009 // Folds normally.10 %4 = index.add %0, %111 // Folds even though values exceed INT32_MAX.12 %5 = index.add %2, %313 14 // CHECK-DAG: %[[A:.*]] = index.constant 210115 // CHECK-DAG: %[[B:.*]] = index.constant 700000210116 // CHECK: return %[[A]], %[[B]]17 return %4, %5 : index, index18}19 20// CHECK-LABEL: @add_overflow21func.func @add_overflow() -> (index, index) {22 %0 = index.constant 200000000023 %1 = index.constant 800000000000000000024 // Folds normally.25 %2 = index.add %0, %026 // Folds and overflows.27 %3 = index.add %1, %128 29 // CHECK-DAG: %[[A:.*]] = index.constant 4{{0+}}30 // CHECK-DAG: %[[B:.*]] = index.constant -2446{{[0-9]+}}31 // CHECK: return %[[A]], %[[B]]32 return %2, %3 : index, index33}34 35// CHECK-LABEL: @add_fold_constants36func.func @add_fold_constants(%arg: index) -> (index) {37 %0 = index.constant 138 %1 = index.constant 239 %2 = index.add %arg, %040 %3 = index.add %2, %141 42 // CHECK: [[C3:%.*]] = index.constant 343 // CHECK: [[V0:%.*]] = index.add %arg0, [[C3]]44 // CHECK: return [[V0]]45 return %3 : index46}47 48// CHECK-LABEL: @sub49func.func @sub() -> index {50 %0 = index.constant -200000000051 %1 = index.constant 300000000052 %2 = index.sub %0, %153 // CHECK: %[[A:.*]] = index.constant -5{{0+}}54 // CHECK: return %[[A]]55 return %2 : index56}57 58// CHECK-LABEL: @mul59func.func @mul() -> index {60 %0 = index.constant 800000000200000000061 %1 = index.constant 262 %2 = index.mul %0, %163 // CHECK: %[[A:.*]] = index.constant -2446{{[0-9]+}}64 // CHECK: return %[[A]]65 return %2 : index66}67 68// CHECK-LABEL: @mul_fold_constants69func.func @mul_fold_constants(%arg: index) -> (index) {70 %0 = index.constant 271 %1 = index.constant 372 %2 = index.mul %arg, %073 %3 = index.mul %2, %174 75 // CHECK: [[C6:%.*]] = index.constant 676 // CHECK: [[V0:%.*]] = index.mul %arg0, [[C6]]77 // CHECK: return [[V0]]78 return %3 : index79}80 81// CHECK-LABEL: @divs82func.func @divs() -> index {83 %0 = index.constant -284 %1 = index.constant 0x20000000085 %2 = index.divs %1, %086 // CHECK: %[[A:.*]] = index.constant -429{{[0-9]+}}87 // CHECK: return %[[A]]88 return %2 : index89}90 91// CHECK-LABEL: @divs_nofold92func.func @divs_nofold() -> (index, index) {93 %0 = index.constant 094 %1 = index.constant 0x10000000095 %2 = index.constant 296 97 // Divide by zero.98 // CHECK: index.divs99 %3 = index.divs %2, %0100 // 32-bit result differs from 64-bit.101 // CHECK: index.divs102 %4 = index.divs %1, %2103 104 return %3, %4 : index, index105}106 107// CHECK-LABEL: @divu108func.func @divu() -> index {109 %0 = index.constant -2110 %1 = index.constant 0x200000000111 %2 = index.divu %1, %0112 // CHECK: %[[A:.*]] = index.constant 0113 // CHECK: return %[[A]]114 return %2 : index115}116 117// CHECK-LABEL: @divu_nofold118func.func @divu_nofold() -> (index, index) {119 %0 = index.constant 0120 %1 = index.constant 0x100000000121 %2 = index.constant 2122 123 // Divide by zero.124 // CHECK: index.divu125 %3 = index.divu %2, %0126 // 32-bit result differs from 64-bit.127 // CHECK: index.divu128 %4 = index.divu %1, %2129 130 return %3, %4 : index, index131}132 133// CHECK-LABEL: @ceildivs134func.func @ceildivs() -> (index, index, index) {135 %c0 = index.constant 0136 %c2 = index.constant 2137 %c5 = index.constant 5138 139 // CHECK-DAG: %[[A:.*]] = index.constant 0140 %0 = index.ceildivs %c0, %c5141 142 // CHECK-DAG: %[[B:.*]] = index.constant 1143 %1 = index.ceildivs %c2, %c5144 145 // CHECK-DAG: %[[C:.*]] = index.constant 3146 %2 = index.ceildivs %c5, %c2147 148 // CHECK: return %[[A]], %[[B]], %[[C]]149 return %0, %1, %2 : index, index, index150}151 152// CHECK-LABEL: @ceildivs_neg153func.func @ceildivs_neg() -> index {154 %c5 = index.constant -5155 %c2 = index.constant 2156 // CHECK: %[[A:.*]] = index.constant -2157 %0 = index.ceildivs %c5, %c2158 // CHECK: return %[[A]]159 return %0 : index160}161 162// CHECK-LABEL: @ceildivs_edge163func.func @ceildivs_edge() -> (index, index) {164 %cn1 = index.constant -1165 %cIntMin = index.constant -2147483648166 %cIntMax = index.constant 2147483647167 168 // The result is 0 on 32-bit.169 // CHECK-DAG: %[[A:.*]] = index.constant 2147483648170 %0 = index.ceildivs %cIntMin, %cn1171 172 // CHECK-DAG: %[[B:.*]] = index.constant -2147483647173 %1 = index.ceildivs %cIntMax, %cn1174 175 // CHECK: return %[[A]], %[[B]]176 return %0, %1 : index, index177}178 179// CHECK-LABEL: @ceildivu180func.func @ceildivu() -> index {181 %0 = index.constant 0x200000001182 %1 = index.constant 2183 // CHECK: %[[A:.*]] = index.constant 429{{[0-9]+}}7184 %2 = index.ceildivu %0, %1185 // CHECK: return %[[A]]186 return %2 : index187}188 189// CHECK-LABEL: @floordivs190func.func @floordivs() -> index {191 %0 = index.constant -5192 %1 = index.constant 2193 // CHECK: %[[A:.*]] = index.constant -3194 %2 = index.floordivs %0, %1195 // CHECK: return %[[A]]196 return %2 : index197}198 199// CHECK-LABEL: @floordivs_edge200func.func @floordivs_edge() -> (index, index) {201 %cIntMin = index.constant -2147483648202 %cIntMax = index.constant 2147483647203 %n1 = index.constant -1204 %p1 = index.constant 1205 206 // CHECK-DAG: %[[A:.*]] = index.constant -2147483648207 // CHECK-DAG: %[[B:.*]] = index.constant -2147483647208 %0 = index.floordivs %cIntMin, %p1209 %1 = index.floordivs %cIntMax, %n1210 211 // CHECK: return %[[A]], %[[B]]212 return %0, %1 : index, index213}214 215// CHECK-LABEL: @floordivs_nofold216func.func @floordivs_nofold() -> index {217 %lhs = index.constant 0x100000000218 %c2 = index.constant 2219 220 // 32-bit result differs from 64-bit.221 // CHECK: index.floordivs222 %0 = index.floordivs %lhs, %c2223 224 return %0 : index225}226 227// CHECK-LABEL: @rems_zerodiv_nofold228func.func @rems_zerodiv_nofold() -> index {229 %lhs = index.constant 2230 %rhs = index.constant 0231 // CHECK: index.rems232 %0 = index.rems %lhs, %rhs233 return %0 : index234}235 236// CHECK-LABEL: @remu_zerodiv_nofold237func.func @remu_zerodiv_nofold() -> index {238 %lhs = index.constant 2239 %rhs = index.constant 0240 // CHECK: index.remu241 %0 = index.remu %lhs, %rhs242 return %0 : index243}244 245// CHECK-LABEL: @rems246func.func @rems() -> index {247 %lhs = index.constant -5248 %rhs = index.constant 2249 // CHECK: %[[A:.*]] = index.constant -1250 %0 = index.rems %lhs, %rhs251 // CHECK: return %[[A]]252 return %0 : index253}254 255// CHECK-LABEL: @rems_nofold256func.func @rems_nofold() -> index {257 %lhs = index.constant 2258 %rhs = index.constant 0x100000001259 // 32-bit result differs from 64-bit.260 // CHECK: index.rems261 %0 = index.rems %lhs, %rhs262 return %0 : index263}264 265// CHECK-LABEL: @remu266func.func @remu() -> index {267 %lhs = index.constant 2268 %rhs = index.constant -1269 // CHECK: %[[A:.*]] = index.constant 2270 %0 = index.remu %lhs, %rhs271 // CHECK: return %[[A]]272 return %0 : index273}274 275// CHECK-LABEL: @remu_nofold276func.func @remu_nofold() -> index {277 %lhs = index.constant 2278 %rhs = index.constant 0x100000001279 // 32-bit result differs from 64-bit.280 // CHECK: index.remu281 %0 = index.remu %lhs, %rhs282 return %0 : index283}284 285// CHECK-LABEL: @maxs286func.func @maxs() -> index {287 %lhs = index.constant -4288 %rhs = index.constant 2289 // CHECK: %[[A:.*]] = index.constant 2290 %0 = index.maxs %lhs, %rhs291 // CHECK: return %[[A]]292 return %0 : index293}294 295// CHECK-LABEL: @maxs_nofold296func.func @maxs_nofold() -> index {297 %lhs = index.constant 1298 %rhs = index.constant 0x100000000299 // 32-bit result differs from 64-bit.300 // CHECK: index.maxs301 %0 = index.maxs %lhs, %rhs302 return %0 : index303}304 305// CHECK-LABEL: @maxs_edge306func.func @maxs_edge() -> index {307 %lhs = index.constant 1308 %rhs = index.constant 0x100000001309 // Truncated 64-bit result is the same as 32-bit.310 // CHECK: %[[A:.*]] = index.constant 429{{[0-9]+}}311 %0 = index.maxs %lhs, %rhs312 // CHECK: return %[[A]]313 return %0 : index314}315 316// CHECK-LABEL: @maxs_fold_constants317func.func @maxs_fold_constants(%arg: index) -> (index) {318 %0 = index.constant -2319 %1 = index.constant 3320 %2 = index.maxs %arg, %0321 %3 = index.maxs %2, %1322 323 // CHECK: [[C3:%.*]] = index.constant 3324 // CHECK: [[V0:%.*]] = index.maxs %arg0, [[C3]]325 // CHECK: return [[V0]]326 return %3 : index327}328 329// CHECK-LABEL: @maxu330func.func @maxu() -> index {331 %lhs = index.constant -1332 %rhs = index.constant 1333 // CHECK: %[[A:.*]] = index.constant -1334 %0 = index.maxu %lhs, %rhs335 // CHECK: return %[[A]]336 return %0 : index337}338 339// CHECK-LABEL: @maxu_fold_constants340func.func @maxu_fold_constants(%arg: index) -> (index) {341 %0 = index.constant 2342 %1 = index.constant 3343 %2 = index.maxu %arg, %0344 %3 = index.maxu %2, %1345 346 // CHECK: [[C3:%.*]] = index.constant 3347 // CHECK: [[V0:%.*]] = index.maxu %arg0, [[C3]]348 // CHECK: return [[V0]]349 return %3 : index350}351 352// CHECK-LABEL: @mins353func.func @mins() -> index {354 %lhs = index.constant -4355 %rhs = index.constant 2356 // CHECK: %[[A:.*]] = index.constant -4357 %0 = index.mins %lhs, %rhs358 // CHECK: return %[[A]]359 return %0 : index360}361 362// CHECK-LABEL: @mins_nofold363func.func @mins_nofold() -> index {364 %lhs = index.constant 1365 %rhs = index.constant 0x100000000366 // 32-bit result differs from 64-bit.367 // CHECK: index.mins368 %0 = index.mins %lhs, %rhs369 return %0 : index370}371 372// CHECK-LABEL: @mins_nofold_2373func.func @mins_nofold_2() -> index {374 %lhs = index.constant 0x7fffffff375 %rhs = index.constant 0x80000000376 // 32-bit result differs from 64-bit.377 // CHECK: index.mins378 %0 = index.mins %lhs, %rhs379 return %0 : index380}381 382// CHECK-LABEL: @mins_fold_constants383func.func @mins_fold_constants(%arg: index) -> (index) {384 %0 = index.constant -2385 %1 = index.constant 3386 %2 = index.mins %arg, %0387 %3 = index.mins %2, %1388 389 // CHECK: [[C2:%.*]] = index.constant -2390 // CHECK: [[V0:%.*]] = index.mins %arg0, [[C2]]391 // CHECK: return [[V0]]392 return %3 : index393}394 395// CHECK-LABEL: @minu396func.func @minu() -> index {397 %lhs = index.constant -1398 %rhs = index.constant 1399 // CHECK: %[[A:.*]] = index.constant 1400 %0 = index.minu %lhs, %rhs401 // CHECK: return %[[A]]402 return %0 : index403}404 405// CHECK-LABEL: @minu_fold_constants406func.func @minu_fold_constants(%arg: index) -> (index) {407 %0 = index.constant 2408 %1 = index.constant 3409 %2 = index.minu %arg, %0410 %3 = index.minu %2, %1411 412 // CHECK: [[C2:%.*]] = index.constant 2413 // CHECK: [[V0:%.*]] = index.minu %arg0, [[C2]]414 // CHECK: return [[V0]]415 return %3 : index416}417 418// CHECK-LABEL: @shl419func.func @shl() -> index {420 %lhs = index.constant 128421 %rhs = index.constant 2422 // CHECK: %[[A:.*]] = index.constant 512423 %0 = index.shl %lhs, %rhs424 // CHECK: return %[[A]]425 return %0 : index426}427 428// CHECK-LABEL: @shl_32429func.func @shl_32() -> index {430 %lhs = index.constant 1431 %rhs = index.constant 32432 // CHECK: index.shl433 %0 = index.shl %lhs, %rhs434 return %0 : index435}436 437// CHECK-LABEL: @shl_edge438func.func @shl_edge() -> index {439 %lhs = index.constant 4000000000440 %rhs = index.constant 31441 // CHECK: %[[A:.*]] = index.constant 858{{[0-9]+}}442 %0 = index.shl %lhs, %rhs443 // CHECK: return %[[A]]444 return %0 : index445}446 447// CHECK-LABEL: @shrs448func.func @shrs() -> index {449 %lhs = index.constant 128450 %rhs = index.constant 2451 // CHECK: %[[A:.*]] = index.constant 32452 %0 = index.shrs %lhs, %rhs453 // CHECK: return %[[A]]454 return %0 : index455}456 457// CHECK-LABEL: @shrs_32458func.func @shrs_32() -> index {459 %lhs = index.constant 4000000000000460 %rhs = index.constant 32461 // CHECK: index.shrs462 %0 = index.shrs %lhs, %rhs463 return %0 : index464}465 466// CHECK-LABEL: @shrs_nofold467func.func @shrs_nofold() -> index {468 %lhs = index.constant 0x100000000469 %rhs = index.constant 1470 // CHECK: index.shrs471 %0 = index.shrs %lhs, %rhs472 return %0 : index473}474 475// CHECK-LABEL: @shrs_edge476func.func @shrs_edge() -> index {477 %lhs = index.constant 0x10000000000478 %rhs = index.constant 3479 // CHECK: %[[A:.*]] = index.constant 137{{[0-9]+}}480 %0 = index.shrs %lhs, %rhs481 // CHECK: return %[[A]]482 return %0 : index483}484 485// CHECK-LABEL: @shru486func.func @shru() -> index {487 %lhs = index.constant 128488 %rhs = index.constant 2489 // CHECK: %[[A:.*]] = index.constant 32490 %0 = index.shru %lhs, %rhs491 // CHECK: return %[[A]]492 return %0 : index493}494 495// CHECK-LABEL: @shru_32496func.func @shru_32() -> index {497 %lhs = index.constant 4000000000000498 %rhs = index.constant 32499 // CHECK: index.shru500 %0 = index.shru %lhs, %rhs501 return %0 : index502}503 504// CHECK-LABEL: @shru_nofold505func.func @shru_nofold() -> index {506 %lhs = index.constant 0x100000000507 %rhs = index.constant 1508 // CHECK: index.shru509 %0 = index.shru %lhs, %rhs510 return %0 : index511}512 513// CHECK-LABEL: @shru_edge514func.func @shru_edge() -> index {515 %lhs = index.constant 0x10000000000516 %rhs = index.constant 3517 // CHECK: %[[A:.*]] = index.constant 137{{[0-9]+}}518 %0 = index.shru %lhs, %rhs519 // CHECK: return %[[A]]520 return %0 : index521}522 523// CHECK-LABEL: @and524func.func @and() -> index {525 %lhs = index.constant 5526 %rhs = index.constant 1527 // CHECK: %[[A:.*]] = index.constant 1528 %0 = index.and %lhs, %rhs529 // CHECK: return %[[A]]530 return %0 : index531}532 533// CHECK-LABEL: @and_fold_constants534func.func @and_fold_constants(%arg: index) -> (index) {535 %0 = index.constant 5536 %1 = index.constant 1537 %2 = index.and %arg, %0538 %3 = index.and %2, %1539 540 // CHECK: [[C1:%.*]] = index.constant 1541 // CHECK: [[V0:%.*]] = index.and %arg0, [[C1]]542 // CHECK: return [[V0]]543 return %3 : index544}545 546// CHECK-LABEL: @or547func.func @or() -> index {548 %lhs = index.constant 5549 %rhs = index.constant 2550 // CHECK: %[[A:.*]] = index.constant 7551 %0 = index.or %lhs, %rhs552 // CHECK: return %[[A]]553 return %0 : index554}555 556// CHECK-LABEL: @or_fold_constants557func.func @or_fold_constants(%arg: index) -> (index) {558 %0 = index.constant 5559 %1 = index.constant 1560 %2 = index.or %arg, %0561 %3 = index.or %2, %1562 563 // CHECK: [[C5:%.*]] = index.constant 5564 // CHECK: [[V0:%.*]] = index.or %arg0, [[C5]]565 // CHECK: return [[V0]]566 return %3 : index567}568 569// CHECK-LABEL: @xor570func.func @xor() -> index {571 %lhs = index.constant 5572 %rhs = index.constant 1573 // CHECK: %[[A:.*]] = index.constant 4574 %0 = index.xor %lhs, %rhs575 // CHECK: return %[[A]]576 return %0 : index577}578 579// CHECK-LABEL: @xor_fold_constants580func.func @xor_fold_constants(%arg: index) -> (index) {581 %0 = index.constant 5582 %1 = index.constant 1583 %2 = index.xor %arg, %0584 %3 = index.xor %2, %1585 586 // CHECK: [[C4:%.*]] = index.constant 4587 // CHECK: [[V0:%.*]] = index.xor %arg0, [[C4]]588 // CHECK: return [[V0]]589 return %3 : index590}591 592// CHECK-LABEL: @cmp593func.func @cmp(%arg0: index) -> (i1, i1, i1, i1, i1, i1) {594 %a = index.constant 0595 %b = index.constant -1596 %c = index.constant -2597 %d = index.constant 4598 599 %0 = index.cmp slt(%a, %b)600 %1 = index.cmp ugt(%b, %a)601 %2 = index.cmp ne(%d, %a)602 %3 = index.cmp sgt(%b, %a)603 604 %4 = index.sub %a, %arg0605 %5 = index.cmp sgt(%4, %a)606 607 %6 = index.sub %a, %arg0608 %7 = index.cmp sgt(%a, %6)609 610 // CHECK-DAG: %[[TRUE:.*]] = index.bool.constant true611 // CHECK-DAG: %[[FALSE:.*]] = index.bool.constant false612 // CHECK-DAG: [[IDX0:%.*]] = index.constant 0613 // CHECK-DAG: [[V4:%.*]] = index.cmp sgt([[IDX0]], %arg0)614 // CHECK-DAG: [[V5:%.*]] = index.cmp sgt(%arg0, [[IDX0]])615 // CHECK: return %[[FALSE]], %[[TRUE]], %[[TRUE]], %[[FALSE]]616 return %0, %1, %2, %3, %5, %7 : i1, i1, i1, i1, i1, i1617}618 619// CHECK-LABEL: @cmp_same_args620func.func @cmp_same_args(%a: index) -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {621 %0 = index.cmp eq(%a, %a)622 %1 = index.cmp sge(%a, %a)623 %2 = index.cmp sle(%a, %a)624 %3 = index.cmp uge(%a, %a)625 %4 = index.cmp ule(%a, %a)626 %5 = index.cmp ne(%a, %a)627 %6 = index.cmp sgt(%a, %a)628 %7 = index.cmp slt(%a, %a)629 %8 = index.cmp ugt(%a, %a)630 %9 = index.cmp ult(%a, %a)631 632 // CHECK-DAG: %[[TRUE:.*]] = index.bool.constant true633 // CHECK-DAG: %[[FALSE:.*]] = index.bool.constant false634 // CHECK-NEXT: return %[[TRUE]], %[[TRUE]], %[[TRUE]], %[[TRUE]], %[[TRUE]],635 // CHECK-SAME: %[[FALSE]], %[[FALSE]], %[[FALSE]], %[[FALSE]], %[[FALSE]]636 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1637}638 639// CHECK-LABEL: @cmp_nofold640func.func @cmp_nofold() -> i1 {641 %lhs = index.constant 1642 %rhs = index.constant 0x100000000643 // 32-bit result differs from 64-bit.644 // CHECK: index.cmp slt645 %0 = index.cmp slt(%lhs, %rhs)646 return %0 : i1647}648 649// CHECK-LABEL: @cmp_edge650func.func @cmp_edge() -> i1 {651 %lhs = index.constant 1652 %rhs = index.constant 0x100000002653 // 64-bit result is the same as 32-bit.654 // CHECK: %[[TRUE:.*]] = index.bool.constant true655 %0 = index.cmp slt(%lhs, %rhs)656 // CHECK: return %[[TRUE]]657 return %0 : i1658}659 660// CHECK-LABEL: @cmp_maxs661func.func @cmp_maxs(%arg0: index) -> (i1, i1) {662 %idx0 = index.constant 0663 %idx1 = index.constant 1664 %0 = index.maxs %arg0, %idx1665 %1 = index.cmp sgt(%0, %idx0)666 %2 = index.cmp eq(%0, %idx0)667 // CHECK: return %true, %false668 return %1, %2 : i1, i1669}670 671// CHECK-LABEL: @mul_identity672func.func @mul_identity(%arg0: index) -> (index, index) {673 %idx0 = index.constant 0674 %idx1 = index.constant 1675 %0 = index.mul %arg0, %idx0676 %1 = index.mul %arg0, %idx1677 // CHECK: return %idx0, %arg0678 return %0, %1 : index, index679}680 681// CHECK-LABEL: @add_identity682func.func @add_identity(%arg0: index) -> index {683 %idx0 = index.constant 0684 %0 = index.add %arg0, %idx0685 // CHECK-NEXT: return %arg0686 return %0 : index687}688 689// CHECK-LABEL: @sub_identity690func.func @sub_identity(%arg0: index) -> index {691 %idx0 = index.constant 0692 %0 = index.sub %arg0, %idx0693 // CHECK-NEXT: return %arg0694 return %0 : index695}696 697// CHECK-LABEL: @castu_to_index698func.func @castu_to_index() -> index {699 // CHECK: index.constant 8000000000000700 %0 = arith.constant 8000000000000 : i48701 %1 = index.castu %0 : i48 to index702 return %1 : index703}704 705// CHECK-LABEL: @casts_to_index706func.func @casts_to_index() -> index {707 // CHECK: index.constant -1000708 %0 = arith.constant -1000 : i48709 %1 = index.casts %0 : i48 to index710 return %1 : index711}712