brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.5 KiB · 130782b Raw
1043 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect -int-range-optimizations -canonicalize %s | FileCheck %s2 3// CHECK-LABEL: func @add_min_max4// CHECK: %[[c3:.*]] = arith.constant 3 : index5// CHECK: return %[[c3]]6func.func @add_min_max(%a: index, %b: index) -> index {7    %c1 = arith.constant 1 : index8    %c2 = arith.constant 2 : index9    %0 = arith.minsi %a, %c1 : index10    %1 = arith.maxsi %0, %c1 : index11    %2 = arith.minui %b, %c2 : index12    %3 = arith.maxui %2, %c2 : index13    %4 = arith.addi %1, %3 : index14    func.return %4 : index15}16 17// CHECK-LABEL: func @add_lower_bound18// CHECK: %[[sge:.*]] = arith.cmpi sge19// CHECK: return %[[sge]]20func.func @add_lower_bound(%a : i32, %b : i32) -> i1 {21    %c1 = arith.constant 1 : i3222    %c2 = arith.constant 2 : i3223    %0 = arith.maxsi %a, %c1 : i3224    %1 = arith.maxsi %b, %c1 : i3225    %2 = arith.addi %0, %1 : i3226    %3 = arith.cmpi sge, %2, %c2 : i3227    %4 = arith.cmpi uge, %2, %c2 : i3228    %5 = arith.andi %3, %4 : i129    func.return %5 : i130}31 32// CHECK-LABEL: func @sub_signed_vs_unsigned33// CHECK-NOT: arith.cmpi sle34// CHECK: %[[unsigned:.*]] = arith.cmpi ule35// CHECK: return %[[unsigned]] : i136func.func @sub_signed_vs_unsigned(%v : i64) -> i1 {37    %c0 = arith.constant 0 : i6438    %c2 = arith.constant 2 : i6439    %c-5 = arith.constant -5 : i6440    %0 = arith.minsi %v, %c2 : i6441    %1 = arith.maxsi %0, %c-5 : i6442    %2 = arith.subi %1, %c2 : i6443    %3 = arith.cmpi sle, %2, %c0 : i6444    %4 = arith.cmpi ule, %2, %c0 : i6445    %5 = arith.andi %3, %4 : i146    func.return %5 : i147}48 49// CHECK-LABEL: func @multiply_negatives50// CHECK: %[[false:.*]] = arith.constant false51// CHECK: return %[[false]]52func.func @multiply_negatives(%a : index, %b : index) -> i1 {53    %c2 = arith.constant 2 : index54    %c3 = arith.constant 3 : index55    %c_1 = arith.constant -1 : index56    %c_2 = arith.constant -2 : index57    %c_4 = arith.constant -4 : index58    %c_12 = arith.constant -12 : index59    %0 = arith.maxsi %a, %c2 : index60    %1 = arith.minsi %0, %c3 : index61    %2 = arith.minsi %b, %c_1 : index62    %3 = arith.maxsi %2, %c_4 : index63    %4 = arith.muli %1, %3 : index64    %5 = arith.cmpi slt, %4, %c_12 : index65    %6 = arith.cmpi slt, %c_1, %4 : index66    %7 = arith.ori %5, %6 : i167    func.return %7 : i168}69 70// CHECK-LABEL: func @multiply_unsigned_bounds71// CHECK: %[[true:.*]] = arith.constant true72// CHECK: return %[[true]]73func.func @multiply_unsigned_bounds(%a : i16, %b : i16) -> i1 {74    %c0 = arith.constant 0 : i1675    %c4 = arith.constant 4 : i1676    %c_mask = arith.constant 0x3fff : i1677    %c_bound = arith.constant 0xfffc : i1678    %0 = arith.andi %a, %c_mask : i1679    %1 = arith.minui %b, %c4 : i1680    %2 = arith.muli %0, %1 : i1681    %3 = arith.cmpi uge, %2, %c0 : i1682    %4 = arith.cmpi ule, %2, %c_bound : i1683    %5 = arith.andi %3, %4 : i184    func.return %5 : i185}86 87// CHECK-LABEL: @for_loop_with_increasing_arg88// CHECK: %[[ret:.*]] = arith.cmpi ule89// CHECK: return %[[ret]]90func.func @for_loop_with_increasing_arg() -> i1 {91    %c0 = arith.constant 0 : index92    %c1 = arith.constant 1 : index93    %c4 = arith.constant 4 : index94    %c16 = arith.constant 16 : index95    %0 = scf.for %arg0 = %c0 to %c4 step %c1 iter_args(%arg1 = %c0) -> index {96        %10 = arith.addi %arg0, %arg1 : index97        scf.yield %10 : index98    }99    %1 = arith.cmpi ule, %0, %c16 : index100    func.return %1 : i1101}102 103// CHECK-LABEL: @for_loop_with_constant_result104// CHECK: %[[true:.*]] = arith.constant true105// CHECK: return %[[true]]106func.func @for_loop_with_constant_result() -> i1 {107    %c0 = arith.constant 0 : index108    %c1 = arith.constant 1 : index109    %c4 = arith.constant 4 : index110    %true = arith.constant true111    %0 = scf.for %arg0 = %c0 to %c4 step %c1 iter_args(%arg1 = %true) -> i1 {112        %10 = arith.cmpi ule, %arg0, %c4 : index113        %11 = arith.andi %10, %arg1 : i1114        scf.yield %11 : i1115    }116    func.return %0 : i1117}118 119// Test to catch a bug present in some versions of the data flow analysis120// CHECK-LABEL: func @while_false121// CHECK: %[[false:.*]] = arith.constant false122// CHECK: scf.condition(%[[false]])123func.func @while_false(%arg0 : index) -> index {124    %c0 = arith.constant 0 : index125    %c1 = arith.constant 1 : index126    %c2 = arith.constant 2 : index127    %0 = arith.divui %arg0, %c2 : index128    %1 = scf.while (%arg1 = %0) : (index) -> index {129        %2 = arith.cmpi slt, %arg1, %c0 : index130        scf.condition(%2) %arg1 : index131    } do {132    ^bb0(%arg2 : index):133        scf.yield %c2 : index134    }135    func.return %1 : index136}137 138// CHECK-LABEL: func @div_bounds_positive139// CHECK: %[[true:.*]] = arith.constant true140// CHECK: return %[[true]]141func.func @div_bounds_positive(%arg0 : index) -> i1 {142    %c0 = arith.constant 0 : index143    %c2 = arith.constant 2 : index144    %c4 = arith.constant 4 : index145    %0 = arith.maxsi %arg0, %c2 : index146    %1 = arith.divsi %c4, %0 : index147    %2 = arith.divui %c4, %0 : index148 149    %3 = arith.cmpi sge, %1, %c0 : index150    %4 = arith.cmpi sle, %1, %c2 : index151    %5 = arith.cmpi sge, %2, %c0 : index152    %6 = arith.cmpi sle, %1, %c2 : index153 154    %7 = arith.andi %3, %4 : i1155    %8 = arith.andi %7, %5 : i1156    %9 = arith.andi %8, %6 : i1157    func.return %9 : i1158}159 160// CHECK-LABEL: func @div_bounds_negative161// CHECK: %[[true:.*]] = arith.constant true162// CHECK: return %[[true]]163func.func @div_bounds_negative(%arg0 : index) -> i1 {164    %c0 = arith.constant 0 : index165    %c_2 = arith.constant -2 : index166    %c4 = arith.constant 4 : index167    %0 = arith.minsi %arg0, %c_2 : index168    %1 = arith.divsi %c4, %0 : index169    %2 = arith.divui %c4, %0 : index170 171    %3 = arith.cmpi sle, %1, %c0 : index172    %4 = arith.cmpi sge, %1, %c_2 : index173    %5 = arith.cmpi eq, %2, %c0 : index174 175    %7 = arith.andi %3, %4 : i1176    %8 = arith.andi %7, %5 : i1177    func.return %8 : i1178}179 180// CHECK-LABEL: func @div_zero_undefined181// CHECK: %[[true:.*]] = arith.constant true182// CHECK: return %[[true]]183func.func @div_zero_undefined(%arg0 : index) -> i1 {184    %c0 = arith.constant 0 : index185    %c1 = arith.constant 1 : index186    %c4 = arith.constant 4 : index187    %0 = arith.andi %arg0, %c1 : index188    %1 = arith.divui %c4, %0 : index189    %2 = arith.cmpi ule, %1, %c4 : index190    func.return %2 : i1191}192 193// CHECK-LABEL: func @div_refine_min194// CHECK: %[[true:.*]] = arith.constant true195// CHECK: return %[[true]]196func.func @div_refine_min(%arg0 : index) -> i1 {197    %c0 = arith.constant 1 : index198    %c1 = arith.constant 2 : index199    %c4 = arith.constant 4 : index200    %0 = arith.andi %arg0, %c1 : index201    %1 = arith.divui %c4, %0 : index202    %2 = arith.cmpi uge, %1, %c0 : index203    func.return %2 : i1204}205 206// CHECK-LABEL: func @ceil_divui207// CHECK: %[[ret:.*]] = arith.cmpi eq208// CHECK: return %[[ret]]209func.func @ceil_divui(%arg0 : index) -> i1 {210    %c0 = arith.constant 0 : index211    %c1 = arith.constant 1 : index212    %c3 = arith.constant 3 : index213    %c4 = arith.constant 4 : index214 215    %0 = arith.minui %arg0, %c3 : index216    %1 = arith.maxui %0, %c1 : index217    %2 = arith.ceildivui %1, %c4 : index218    %3 = arith.cmpi eq, %2, %c1 : index219 220    %4 = arith.maxui %0, %c0 : index221    %5 = arith.ceildivui %4, %c4 : index222    %6 = arith.cmpi eq, %5, %c1 : index223    %7 = arith.andi %3, %6 : i1224    func.return %7 : i1225}226 227// CHECK-LABEL: func @ceil_divui_by_zero_issue_131273228// CHECK-NEXT: return229func.func @ceil_divui_by_zero_issue_131273() {230    %0 = test.with_bounds {smax = 0 : i32, smin = -1 : i32, umax = 0 : i32, umin = -1 : i32} : i32231    %c7_i32 = arith.constant 7 : i32232    %1 = arith.ceildivui %c7_i32, %0 : i32233    return234}235 236// CHECK-LABEL: func @ceil_divsi237// CHECK: %[[ret:.*]] = arith.cmpi eq238// CHECK: return %[[ret]]239func.func @ceil_divsi(%arg0 : index) -> i1 {240    %c0 = arith.constant 0 : index241    %c1 = arith.constant 1 : index242    %c3 = arith.constant 3 : index243    %c4 = arith.constant 4 : index244    %c-4 = arith.constant -4 : index245 246    %0 = arith.minsi %arg0, %c3 : index247    %1 = arith.maxsi %0, %c1 : index248    %2 = arith.ceildivsi %1, %c4 : index249    %3 = arith.cmpi eq, %2, %c1 : index250    %4 = arith.ceildivsi %1, %c-4 : index251    %5 = arith.cmpi eq, %4, %c0 : index252    %6 = arith.andi %3, %5 : i1253 254    %7 = arith.maxsi %0, %c0 : index255    %8 = arith.ceildivsi %7, %c4 : index256    %9 = arith.cmpi eq, %8, %c1 : index257    %10 = arith.andi %6, %9 : i1258    func.return %10 : i1259}260 261// There was a bug, which was causing this expr errorneously fold to constant262// CHECK-LABEL: func @ceil_divsi_full_range263// CHECK-SAME: (%[[arg:.*]]: index)264// CHECK: %[[c64:.*]] = arith.constant 64 : index265// CHECK: %[[ret:.*]] = arith.ceildivsi %[[arg]], %[[c64]] : index266// CHECK: return %[[ret]]267func.func @ceil_divsi_full_range(%6: index) -> index {268  %c64 = arith.constant 64 : index269  %55 = arith.ceildivsi %6, %c64 : index270  return %55 : index271}272 273// CHECK-LABEL: func @ceil_divsi_intmin_bug_115293274// CHECK: %[[ret:.*]] = arith.constant true275// CHECK: return %[[ret]]276func.func @ceil_divsi_intmin_bug_115293() -> i1 {277    %intMin_i64 = test.with_bounds { smin = -9223372036854775808 : si64, smax = -9223372036854775808 : si64, umin = 9223372036854775808 : ui64, umax = 9223372036854775808 : ui64 } : i64278    %denom_i64 = test.with_bounds { smin = 1189465982 : si64, smax = 1189465982 : si64, umin = 1189465982 : ui64, umax = 1189465982 : ui64 } : i64279    %res_i64 = test.with_bounds { smin = 7754212542 : si64, smax = 7754212542 : si64, umin = 7754212542 : ui64, umax = 7754212542 : ui64 }  : i64280 281    %0 = arith.ceildivsi %intMin_i64, %denom_i64 : i64282    %1 = arith.cmpi eq, %0, %res_i64 : i64283    func.return %1 : i1284}285 286// CHECK-LABEL: func @floor_divsi287// CHECK: %[[true:.*]] = arith.constant true288// CHECK: return %[[true]]289func.func @floor_divsi(%arg0 : index) -> i1 {290    %c4 = arith.constant 4 : index291    %c-1 = arith.constant -1 : index292    %c-3 = arith.constant -3 : index293    %c-4 = arith.constant -4 : index294 295    %0 = arith.minsi %arg0, %c-1 : index296    %1 = arith.maxsi %0, %c-4 : index297    %2 = arith.floordivsi %1, %c4 : index298    %3 = arith.cmpi eq, %2, %c-1 : index299    func.return %3 : i1300}301 302// CHECK-LABEL: func @remui_base303// CHECK: %[[true:.*]] = arith.constant true304// CHECK: return %[[true]]305func.func @remui_base(%arg0 : index, %arg1 : index ) -> i1 {306    %c2 = arith.constant 2 : index307    %c4 = arith.constant 4 : index308 309    %0 = arith.minui %arg1, %c4 : index310    %1 = arith.maxui %0, %c2 : index311    %2 = arith.remui %arg0, %1 : index312    %3 = arith.cmpi ult, %2, %c4 : index313    func.return %3 : i1314}315 316// CHECK-LABEL: func @remui_base_maybe_zero317// CHECK: %[[true:.*]] = arith.constant true318// CHECK: return %[[true]]319func.func @remui_base_maybe_zero(%arg0 : index, %arg1 : index ) -> i1 {320    %c4 = arith.constant 4 : index321    %c5 = arith.constant 5 : index322 323    %0 = arith.minui %arg1, %c4 : index324    %1 = arith.remui %arg0, %0 : index325    %2 = arith.cmpi ult, %1, %c5 : index326    func.return %2 : i1327}328 329// CHECK-LABEL: func @remsi_base330// CHECK: %[[ret:.*]] = arith.cmpi sge331// CHECK: return %[[ret]]332func.func @remsi_base(%arg0 : index, %arg1 : index ) -> i1 {333    %c0 = arith.constant 0 : index334    %c2 = arith.constant 2 : index335    %c4 = arith.constant 4 : index336    %c-4 = arith.constant -4 : index337    %true = arith.constant true338 339    %0 = arith.minsi %arg1, %c4 : index340    %1 = arith.maxsi %0, %c2 : index341    %2 = arith.remsi %arg0, %1 : index342    %3 = arith.cmpi sgt, %2, %c-4 : index343    %4 = arith.cmpi slt, %2, %c4 : index344    %5 = arith.cmpi sge, %2, %c0 : index345    %6 = arith.andi %3, %4 : i1346    %7 = arith.andi %5, %6 : i1347    func.return %7 : i1348}349 350// CHECK-LABEL: func @remsi_positive351// CHECK: %[[true:.*]] = arith.constant true352// CHECK: return %[[true]]353func.func @remsi_positive(%arg0 : index, %arg1 : index ) -> i1 {354    %c0 = arith.constant 0 : index355    %c2 = arith.constant 2 : index356    %c4 = arith.constant 4 : index357    %true = arith.constant true358 359    %0 = arith.minsi %arg1, %c4 : index360    %1 = arith.maxsi %0, %c2 : index361    %2 = arith.maxsi %arg0, %c0 : index362    %3 = arith.remsi %2, %1 : index363    %4 = arith.cmpi sge, %3, %c0 : index364    %5 = arith.cmpi slt, %3, %c4 : index365    %6 = arith.andi %4, %5 : i1366    func.return %6 : i1367}368 369// CHECK-LABEL: func @remui_restricted370// CHECK: %[[true:.*]] = arith.constant true371// CHECK: return %[[true]]372func.func @remui_restricted(%arg0 : index) -> i1 {373    %c2 = arith.constant 2 : index374    %c3 = arith.constant 3 : index375    %c4 = arith.constant 4 : index376 377    %0 = arith.minui %arg0, %c3 : index378    %1 = arith.maxui %0, %c2 : index379    %2 = arith.remui %1, %c4 : index380    %3 = arith.cmpi ule, %2, %c3 : index381    %4 = arith.cmpi uge, %2, %c2 : index382    %5 = arith.andi %3, %4 : i1383    func.return %5 : i1384}385 386// CHECK-LABEL: func @remsi_restricted387// CHECK: %[[true:.*]] = arith.constant true388// CHECK: return %[[true]]389func.func @remsi_restricted(%arg0 : index) -> i1 {390    %c2 = arith.constant 2 : index391    %c3 = arith.constant 3 : index392    %c-4 = arith.constant -4 : index393 394    %0 = arith.minsi %arg0, %c3 : index395    %1 = arith.maxsi %0, %c2 : index396    %2 = arith.remsi %1, %c-4 : index397    %3 = arith.cmpi ule, %2, %c3 : index398    %4 = arith.cmpi uge, %2, %c2 : index399    %5 = arith.andi %3, %4 : i1400    func.return %5 : i1401}402 403// CHECK-LABEL: func @remui_restricted_fails404// CHECK: %[[ret:.*]] = arith.cmpi ne405// CHECK: return %[[ret]]406func.func @remui_restricted_fails(%arg0 : index) -> i1 {407    %c2 = arith.constant 2 : index408    %c3 = arith.constant 3 : index409    %c4 = arith.constant 4 : index410    %c5 = arith.constant 5 : index411 412    %0 = arith.minui %arg0, %c5 : index413    %1 = arith.maxui %0, %c3 : index414    %2 = arith.remui %1, %c4 : index415    %3 = arith.cmpi ne, %2, %c2 : index416    func.return %3 : i1417}418 419// CHECK-LABEL: func @remsi_restricted_fails420// CHECK: %[[ret:.*]] = arith.cmpi ne421// CHECK: return %[[ret]]422func.func @remsi_restricted_fails(%arg0 : index) -> i1 {423    %c2 = arith.constant 2 : index424    %c3 = arith.constant 3 : index425    %c5 = arith.constant 5 : index426    %c-4 = arith.constant -4 : index427 428    %0 = arith.minsi %arg0, %c5 : index429    %1 = arith.maxsi %0, %c3 : index430    %2 = arith.remsi %1, %c-4 : index431    %3 = arith.cmpi ne, %2, %c2 : index432    func.return %3 : i1433}434 435// CHECK-LABEL: func @andi436// CHECK: %[[ret:.*]] = arith.cmpi ugt437// CHECK: return %[[ret]]438func.func @andi(%arg0 : index) -> i1 {439    %c2 = arith.constant 2 : index440    %c5 = arith.constant 5 : index441    %c7 = arith.constant 7 : index442 443    %0 = arith.minsi %arg0, %c5 : index444    %1 = arith.maxsi %0, %c2 : index445    %2 = arith.andi %1, %c7 : index446    %3 = arith.cmpi ugt, %2, %c5 : index447    %4 = arith.cmpi ule, %2, %c7 : index448    %5 = arith.andi %3, %4 : i1449    func.return %5 : i1450}451 452// CHECK-LABEL: func @andi_doesnt_make_nonnegative453// CHECK: %[[ret:.*]] = arith.cmpi sge454// CHECK: return %[[ret]]455func.func @andi_doesnt_make_nonnegative(%arg0 : index) -> i1 {456    %c0 = arith.constant 0 : index457    %c1 = arith.constant 1 : index458    %0 = arith.addi %arg0, %c1 : index459    %1 = arith.andi %arg0, %0 : index460    %2 = arith.cmpi sge, %1, %c0 : index461    func.return %2 : i1462}463 464 465// CHECK-LABEL: func @ori466// CHECK: %[[true:.*]] = arith.constant true467// CHECK: return %[[true]]468func.func @ori(%arg0 : i128, %arg1 : i128) -> i1 {469    %c-1 = arith.constant -1 : i128470    %c0 = arith.constant 0 : i128471 472    %0 = arith.minsi %arg1, %c-1 : i128473    %1 = arith.ori %arg0, %0 : i128474    %2 = arith.cmpi slt, %1, %c0 : i128475    func.return %2 : i1476}477 478// CHECK-LABEL: func @xori_issue_82168479// arith.cmpi was erroneously folded to %false, see Issue #82168.480// CHECK: %[[R:.*]] = arith.cmpi eq, %{{.*}}, %{{.*}} : i64481// CHECK: return %[[R]]482func.func @xori_issue_82168() -> i1 {483    %c0_i64 = arith.constant 0 : i64484    %c2060639849_i64 = arith.constant 2060639849 : i64485    %2 = test.with_bounds { umin = 2060639849 : i64, umax = 2060639850 : i64, smin = 2060639849 : i64, smax = 2060639850 : i64 } : i64486    %3 = arith.xori %2, %c2060639849_i64 : i64487    %4 = arith.cmpi eq, %3, %c0_i64 : i64488    func.return %4 : i1489}490 491// CHECK-LABEL: func @xori_i1492//   CHECK-DAG: %[[true:.*]] = arith.constant true493//   CHECK-DAG: %[[false:.*]] = arith.constant false494//       CHECK: return %[[true]], %[[false]]495func.func @xori_i1() -> (i1, i1) {496    %true = arith.constant true497    %1 = test.with_bounds { umin = 0 : i1, umax = 0 : i1, smin = 0 : i1, smax = 0 : i1 } : i1498    %2 = test.with_bounds { umin = 1 : i1, umax = 1 : i1, smin = 1 : i1, smax = 1 : i1 } : i1499    %3 = arith.xori %1, %true : i1500    %4 = arith.xori %2, %true : i1501    func.return %3, %4 : i1, i1502}503 504// CHECK-LABEL: func @xori505// CHECK: %[[false:.*]] = arith.constant false506// CHECK: return %[[false]]507func.func @xori(%arg0 : i64, %arg1 : i64) -> i1 {508    %c0 = arith.constant 0 : i64509    %c7 = arith.constant 7 : i64510    %c15 = arith.constant 15 : i64511    %true = arith.constant true512 513    %0 = arith.minui %arg0, %c7 : i64514    %1 = arith.minui %arg1, %c15 : i64515    %2 = arith.xori %0, %1 : i64516    %3 = arith.cmpi sle, %2, %c15 : i64517    %4 = arith.xori %3, %true : i1518    func.return %4 : i1519}520 521// CHECK-LABEL: func @extui522// CHECK: %[[true:.*]] = arith.constant true523// CHECK: return %[[true]]524func.func @extui(%arg0 : i16) -> i1 {525    %ci16_max = arith.constant 0xffff : i32526    %0 = arith.extui %arg0 : i16 to i32527    %1 = arith.cmpi ule, %0, %ci16_max : i32528    func.return %1 : i1529}530 531// CHECK-LABEL: func @extsi532// CHECK: %[[true:.*]] = arith.constant true533// CHECK: return %[[true]]534func.func @extsi(%arg0 : i16) -> i1 {535    %ci16_smax = arith.constant 0x7fff : i32536    %ci16_smin = arith.constant 0xffff8000 : i32537    %0 = arith.extsi %arg0 : i16 to i32538    %1 = arith.cmpi sle, %0, %ci16_smax : i32539    %2 = arith.cmpi sge, %0, %ci16_smin : i32540    %3 = arith.andi %1, %2 : i1541    func.return %3 : i1542}543 544// CHECK-LABEL: func @trunci545// CHECK: %[[true:.*]] = arith.constant true546// CHECK: return %[[true]]547func.func @trunci(%arg0 : i32) -> i1 {548    %c-14_i32 = arith.constant -14 : i32549    %c-14_i16 = arith.constant -14 : i16550    %ci16_smin = arith.constant 0xffff8000 : i32551    %0 = arith.minsi %arg0, %c-14_i32 : i32552    %1 = arith.maxsi %0, %ci16_smin : i32553    %2 = arith.trunci %1 : i32 to i16554    %3 = arith.cmpi sle, %2, %c-14_i16 : i16555    %4 = arith.extsi %2 : i16 to i32556    %5 = arith.cmpi sle, %4, %c-14_i32 : i32557    %6 = arith.cmpi sge, %4, %ci16_smin : i32558    %7 = arith.andi %3, %5 : i1559    %8 = arith.andi %7, %6 : i1560    func.return %8 : i1561}562 563// CHECK-LABEL: func @index_cast564// CHECK: %[[true:.*]] = arith.constant true565// CHECK: return %[[true]]566func.func @index_cast(%arg0 : index) -> i1 {567    %ci32_smin = arith.constant 0xffffffff80000000 : i64568    %0 = arith.index_cast %arg0 : index to i32569    %1 = arith.index_cast %0 : i32 to index570    %2 = arith.index_cast %ci32_smin : i64 to index571    %3 = arith.cmpi sge, %1, %2 : index572    func.return %3 : i1573}574 575// CHECK-LABEL: func @shli576// CHECK: %[[ret:.*]] = arith.cmpi sgt577// CHECK: return %[[ret]]578func.func @shli(%arg0 : i32, %arg1 : i1) -> i1 {579    %c2 = arith.constant 2 : i32580    %c4 = arith.constant 4 : i32581    %c8 = arith.constant 8 : i32582    %c32 = arith.constant 32 : i32583    %c-1 = arith.constant -1 : i32584    %c-16 = arith.constant -16 : i32585    %0 = arith.maxsi %arg0, %c-1 : i32586    %1 = arith.minsi %0, %c2 : i32587    %2 = arith.select %arg1, %c2, %c4 : i32588    %3 = arith.shli %1, %2 : i32589    %4 = arith.cmpi sge, %3, %c-16 : i32590    %5 = arith.cmpi sle, %3, %c32 : i32591    %6 = arith.cmpi sgt, %3, %c8 : i32592    %7 = arith.andi %4, %5 : i1593    %8 = arith.andi %7, %6 : i1594    func.return %8 : i1595}596 597// CHECK-LABEL: func @shrui598// CHECK: %[[ret:.*]] = arith.cmpi uge599// CHECK: return %[[ret]]600func.func @shrui(%arg0 : i1) -> i1 {601    %c2 = arith.constant 2 : i32602    %c4 = arith.constant 4 : i32603    %c8 = arith.constant 8 : i32604    %c32 = arith.constant 32 : i32605    %0 = arith.select %arg0, %c2, %c4 : i32606    %1 = arith.shrui %c32, %0 : i32607    %2 = arith.cmpi ule, %1, %c8 : i32608    %3 = arith.cmpi uge, %1, %c2 : i32609    %4 = arith.cmpi uge, %1, %c8 : i32610    %5 = arith.andi %2, %3 : i1611    %6 = arith.andi %5, %4 : i1612    func.return %6 : i1613}614 615// CHECK-LABEL: func @shrsi616// CHECK: %[[ret:.*]] = arith.cmpi slt617// CHECK: return %[[ret]]618func.func @shrsi(%arg0 : i32, %arg1 : i1) -> i1 {619    %c2 = arith.constant 2 : i32620    %c4 = arith.constant 4 : i32621    %c8 = arith.constant 8 : i32622    %c32 = arith.constant 32 : i32623    %c-8 = arith.constant -8 : i32624    %c-32 = arith.constant -32 : i32625    %0 = arith.maxsi %arg0, %c-32 : i32626    %1 = arith.minsi %0, %c32 : i32627    %2 = arith.select %arg1, %c2, %c4 : i32628    %3 = arith.shrsi %1, %2 : i32629    %4 = arith.cmpi sge, %3, %c-8 : i32630    %5 = arith.cmpi sle, %3, %c8 : i32631    %6 = arith.cmpi slt, %3, %c2 : i32632    %7 = arith.andi %4, %5 : i1633    %8 = arith.andi %7, %6 : i1634    func.return %8 : i1635}636 637// CHECK-LABEL: func @no_aggressive_eq638// CHECK: %[[ret:.*]] = arith.cmpi eq639// CHECK: return %[[ret]]640func.func @no_aggressive_eq(%arg0 : index) -> i1 {641    %c1 = arith.constant 1 : index642    %0 = arith.andi %arg0, %c1 : index643    %1 = arith.minui %arg0, %c1 : index644    %2 = arith.cmpi eq, %0, %1 : index645    func.return %2 : i1646}647 648// CHECK-LABEL: func @select_union649// CHECK: %[[ret:.*]] = arith.cmpi ne650// CHECK: return %[[ret]]651 652func.func @select_union(%arg0 : index, %arg1 : i1) -> i1 {653    %c64 = arith.constant 64 : index654    %c100 = arith.constant 100 : index655    %c128 = arith.constant 128 : index656    %c192 = arith.constant 192 : index657    %0 = arith.remui %arg0, %c64 : index658    %1 = arith.addi %0, %c128 : index659    %2 = arith.select %arg1, %0, %1 : index660    %3 = arith.cmpi slt, %2, %c192 : index661    %4 = arith.cmpi ne, %c100, %2 : index662    %5 = arith.andi %3, %4 : i1663    func.return %5 : i1664}665 666// CHECK-LABEL: func @if_union667// CHECK: %[[true:.*]] = arith.constant true668// CHECK: return %[[true]]669func.func @if_union(%arg0 : index, %arg1 : i1) -> i1 {670    %c4 = arith.constant 4 : index671    %c16 = arith.constant 16 : index672    %c-1 = arith.constant -1 : index673    %c-4 = arith.constant -4 : index674    %0 = arith.minui %arg0, %c4 : index675    %1 = scf.if %arg1 -> index {676        %10 = arith.muli %0, %0 : index677        scf.yield %10 : index678    } else {679        %20 = arith.muli %0, %c-1 : index680        scf.yield %20 : index681    }682    %2 = arith.cmpi sle, %1, %c16 : index683    %3 = arith.cmpi sge, %1, %c-4 : index684    %4 = arith.andi %2, %3 : i1685    func.return %4 : i1686}687 688// CHECK-LABEL: func @branch_union689// CHECK: %[[true:.*]] = arith.constant true690// CHECK: return %[[true]]691func.func @branch_union(%arg0 : index, %arg1 : i1) -> i1 {692    %c4 = arith.constant 4 : index693    %c16 = arith.constant 16 : index694    %c-1 = arith.constant -1 : index695    %c-4 = arith.constant -4 : index696    %0 = arith.minui %arg0, %c4 : index697    cf.cond_br %arg1, ^bb1, ^bb2698^bb1 :699    %1 = arith.muli %0, %0 : index700    cf.br ^bb3(%1 : index)701^bb2 :702    %2 = arith.muli %0, %c-1 : index703    cf.br ^bb3(%2 : index)704^bb3(%3 : index) :705    %4 = arith.cmpi sle, %3, %c16 : index706    %5 = arith.cmpi sge, %3, %c-4 : index707    %6 = arith.andi %4, %5 : i1708    func.return %6 : i1709}710 711// CHECK-LABEL: func @loop_bound_not_inferred_with_branch712// CHECK-DAG: %[[min:.*]] = arith.cmpi sge713// CHECK-DAG: %[[max:.*]] = arith.cmpi slt714// CHECK-DAG: %[[ret:.*]] = arith.andi %[[min]], %[[max]]715// CHECK: return %[[ret]]716func.func @loop_bound_not_inferred_with_branch(%arg0 : index, %arg1 : i1) -> i1 {717    %c0 = arith.constant 0 : index718    %c1 = arith.constant 1 : index719    %c4 = arith.constant 4 : index720    %0 = arith.minui %arg0, %c4 : index721    cf.br ^bb2(%c0 : index)722^bb1(%1 : index) :723    %2 = arith.addi %1, %c1 : index724    cf.br ^bb2(%2 : index)725^bb2(%3 : index):726    %4 = arith.cmpi ult, %3, %c4 : index727    cf.cond_br %4, ^bb1(%3 : index), ^bb3(%3 : index)728^bb3(%5 : index) :729    %6 = arith.cmpi sge, %5, %c0 : index730    %7 = arith.cmpi slt, %5, %c4 : index731    %8 = arith.andi %6, %7 : i1732    func.return %8 : i1733}734 735// Test fon a bug where the noive implementation of trunctation led to the cast736// value being set to [0, 0].737// CHECK-LABEL: func.func @truncation_spillover738// CHECK: %[[unreplaced:.*]] = arith.index_cast739// CHECK: memref.store %[[unreplaced]]740func.func @truncation_spillover(%arg0 : memref<?xi32>) -> index {741    %c0 = arith.constant 0 : index742    %c1 = arith.constant 1 : index743    %c2 = arith.constant 2 : index744    %c49 = arith.constant 49 : index745    %0 = scf.for %arg1 = %c0 to %c2 step %c1 iter_args(%arg2 = %c0) -> index {746        %1 = arith.divsi %arg2, %c49 : index747        %2 = arith.index_cast %1 : index to i32748        memref.store %2, %arg0[%c0] : memref<?xi32>749        %3 = arith.addi %arg2, %arg1 : index750        scf.yield %3 : index751    }752  func.return %0 : index753}754 755// CHECK-LABEL: func.func @trunc_catches_overflow756// CHECK: %[[sge:.*]] = arith.cmpi sge757// CHECK: return %[[sge]]758func.func @trunc_catches_overflow(%arg0 : i16) -> i1 {759    %c0_i16 = arith.constant 0 : i16760    %c130_i16 = arith.constant 130 : i16761    %c0_i8 = arith.constant 0 : i8762    %0 = arith.maxui %arg0, %c0_i16 : i16763    %1 = arith.minui %0, %c130_i16 : i16764    %2 = arith.trunci %1 : i16 to i8765    %3 = arith.cmpi sge, %2, %c0_i8 : i8766    %4 = arith.cmpi uge, %2, %c0_i8 : i8767    %5 = arith.andi %3, %4 : i1768    func.return %5 : i1769}770 771// CHECK-LABEL: func.func @trunc_respects_same_high_half772// CHECK: %[[false:.*]] = arith.constant false773// CHECK: return %[[false]]774func.func @trunc_respects_same_high_half(%arg0 : i16) -> i1 {775    %c256_i16 = arith.constant 256 : i16776    %c257_i16 = arith.constant 257 : i16777    %c2_i8 = arith.constant 2 : i8778    %0 = arith.maxui %arg0, %c256_i16 : i16779    %1 = arith.minui %0, %c257_i16 : i16780    %2 = arith.trunci %1 : i16 to i8781    %3 = arith.cmpi sge, %2, %c2_i8 : i8782    func.return %3 : i1783}784 785// CHECK-LABEL: func.func @trunc_handles_small_signed_ranges786// CHECK: %[[true:.*]] = arith.constant true787// CHECK: return %[[true]]788func.func @trunc_handles_small_signed_ranges(%arg0 : i16) -> i1 {789    %c-2_i16 = arith.constant -2 : i16790    %c2_i16 = arith.constant 2 : i16791    %c-2_i8 = arith.constant -2 : i8792    %c2_i8 = arith.constant 2 : i8793    %0 = arith.maxsi %arg0, %c-2_i16 : i16794    %1 = arith.minsi %0, %c2_i16 : i16795    %2 = arith.trunci %1 : i16 to i8796    %3 = arith.cmpi sge, %2, %c-2_i8 : i8797    %4 = arith.cmpi sle, %2, %c2_i8 : i8798    %5 = arith.andi %3, %4 : i1799    func.return %5 : i1800}801 802/// Catch a bug that crept in during an earlier refactoring that made unsigned803/// extension use the signed ranges804 805// CHECK-LABEL: func.func @extui_uses_unsigned806// CHECK: %[[true:.*]] = arith.constant true807// CHECK: return %[[true]]808func.func @extui_uses_unsigned(%arg0 : i32) -> i1 {809    %ci32_smin = arith.constant 0x80000000 : i32810    %ci32_smin_64 = arith.constant 0x80000000 : i64811    %c0_i64 = arith.constant 0 : i64812    %0 = arith.minui %arg0, %ci32_smin : i32813    %1 = arith.extui %0 : i32 to i64814    %2 = arith.cmpi sge, %1, %c0_i64 : i64815    %3 = arith.cmpi ule, %1, %ci32_smin_64 : i64816    %4 = arith.andi %2, %3 : i1817    func.return %4 : i1818}819 820/// Catch a bug that caused a crash in getLoopBoundFromFold when821/// SparseConstantPropagation is loaded in the solver.822 823// CHECK-LABEL:   func.func @caller(824// CHECK-SAME:                      %[[VAL_0:.*]]: memref<?xindex, 4>) {825// CHECK:           call @callee(%[[VAL_0]]) : (memref<?xindex, 4>) -> ()826// CHECK:           return827// CHECK:         }828func.func @caller(%arg0: memref<?xindex, 4>) {829  call @callee(%arg0) : (memref<?xindex, 4>) -> ()830  return831}832 833// CHECK-LABEL:   func.func private @callee(834// CHECK-SAME:                              %[[VAL_0:.*]]: memref<?xindex, 4>) {835// CHECK:           return836// CHECK:         }837func.func private @callee(%arg0: memref<?xindex, 4>) {838  %c1 = arith.constant 1 : index839  %c0 = arith.constant 0 : index840  %0 = affine.load %arg0[0] : memref<?xindex, 4>841  scf.for %arg1 = %c0 to %0 step %c1 {842  }843  return844}845 846// CHECK-LABEL: func @test_i8_bounds847// CHECK: test.reflect_bounds {smax = 127 : si8, smin = -128 : si8, umax = 255 : ui8, umin = 0 : ui8}848func.func @test_i8_bounds() -> i8 {849  %cst1 = arith.constant 1 : i8850  %0 = test.with_bounds { umin = 0 : i8, umax = 255 : i8, smin = -128 : i8, smax = 127 : i8 } : i8851  %1 = arith.addi %0, %cst1 : i8852  %2 = test.reflect_bounds %1 : i8853  return %2: i8854}855 856// CHECK-LABEL: func @test_add_1857// CHECK: test.reflect_bounds {smax = 127 : si8, smin = -128 : si8, umax = 255 : ui8, umin = 0 : ui8}858func.func @test_add_1() -> i8 {859  %cst1 = arith.constant 1 : i8860  %0 = test.with_bounds { umin = 0 : i8, umax = 255 : i8, smin = -128 : i8, smax = 127 : i8 } : i8861  %1 = arith.addi %0, %cst1 : i8862  %2 = test.reflect_bounds %1 : i8863  return %2: i8864}865 866// Tests below check inference with overflow flags.867 868// CHECK-LABEL: func @test_add_i8_wrap1869// CHECK: test.reflect_bounds {smax = 127 : si8, smin = -128 : si8, umax = 128 : ui8, umin = 1 : ui8}870func.func @test_add_i8_wrap1() -> i8 {871  %cst1 = arith.constant 1 : i8872  %0 = test.with_bounds { umin = 0 : i8, umax = 127 : i8, smin = 0 : i8, smax = 127 : i8 } : i8873  // smax overflow874  %1 = arith.addi %0, %cst1 : i8875  %2 = test.reflect_bounds %1 : i8876  return %2: i8877}878 879// CHECK-LABEL: func @test_add_i8_wrap2880// CHECK: test.reflect_bounds {smax = 127 : si8, smin = -128 : si8, umax = 128 : ui8, umin = 1 : ui8}881func.func @test_add_i8_wrap2() -> i8 {882  %cst1 = arith.constant 1 : i8883  %0 = test.with_bounds { umin = 0 : i8, umax = 127 : i8, smin = 0 : i8, smax = 127 : i8 } : i8884  // smax overflow885  %1 = arith.addi %0, %cst1 overflow<nuw> : i8886  %2 = test.reflect_bounds %1 : i8887  return %2: i8888}889 890// CHECK-LABEL: func @test_add_i8_nowrap891// CHECK: test.reflect_bounds {smax = 127 : si8, smin = 1 : si8, umax = 127 : ui8, umin = 1 : ui8}892func.func @test_add_i8_nowrap() -> i8 {893  %cst1 = arith.constant 1 : i8894  %0 = test.with_bounds { umin = 0 : i8, umax = 127 : i8, smin = 0 : i8, smax = 127 : i8 } : i8895  // nsw flag stops smax from overflowing896  %1 = arith.addi %0, %cst1 overflow<nsw> : i8897  %2 = test.reflect_bounds %1 : i8898  return %2: i8899}900 901// CHECK-LABEL: func @test_sub_i8_wrap1902// CHECK: test.reflect_bounds {smax = 5 : si8, smin = -10 : si8, umax = 255 : ui8, umin = 0 : ui8} %1 : i8903func.func @test_sub_i8_wrap1() -> i8 {904  %cst10 = arith.constant 10 : i8905  %0 = test.with_bounds { umin = 0 : i8, umax = 15 : i8, smin = 0 : i8, smax = 15 : i8 } : i8906  // umin underflows907  %1 = arith.subi %0, %cst10 : i8908  %2 = test.reflect_bounds %1 : i8909  return %2: i8910}911 912// CHECK-LABEL: func @test_sub_i8_wrap2913// CHECK: test.reflect_bounds {smax = 5 : si8, smin = -10 : si8, umax = 255 : ui8, umin = 0 : ui8} %1 : i8914func.func @test_sub_i8_wrap2() -> i8 {915  %cst10 = arith.constant 10 : i8916  %0 = test.with_bounds { umin = 0 : i8, umax = 15 : i8, smin = 0 : i8, smax = 15 : i8 } : i8917  // umin underflows918  %1 = arith.subi %0, %cst10 overflow<nsw> : i8919  %2 = test.reflect_bounds %1 : i8920  return %2: i8921}922 923// CHECK-LABEL: func @test_sub_i8_nowrap924// CHECK: test.reflect_bounds {smax = 5 : si8, smin = 0 : si8, umax = 5 : ui8, umin = 0 : ui8}925func.func @test_sub_i8_nowrap() -> i8 {926  %cst10 = arith.constant 10 : i8927  %0 = test.with_bounds { umin = 0 : i8, umax = 15 : i8, smin = 0 : i8, smax = 15 : i8 } : i8928  // nuw flag stops umin from underflowing929  %1 = arith.subi %0, %cst10 overflow<nuw> : i8930  %2 = test.reflect_bounds %1 : i8931  return %2: i8932}933 934// CHECK-LABEL: func @test_mul_i8_wrap935// CHECK: test.reflect_bounds {smax = 127 : si8, smin = -128 : si8, umax = 200 : ui8, umin = 100 : ui8}936func.func @test_mul_i8_wrap() -> i8 {937  %cst10 = arith.constant 10 : i8938  %0 = test.with_bounds { umin = 10 : i8, umax = 20 : i8, smin = 10 : i8, smax = 20 : i8 } : i8939  // smax overflows940  %1 = arith.muli %0, %cst10 : i8941  %2 = test.reflect_bounds %1 : i8942  return %2: i8943}944 945// CHECK-LABEL: func @test_mul_i8_nowrap946// CHECK: test.reflect_bounds {smax = 127 : si8, smin = 100 : si8, umax = 127 : ui8, umin = 100 : ui8}947func.func @test_mul_i8_nowrap() -> i8 {948  %cst10 = arith.constant 10 : i8949  %0 = test.with_bounds { umin = 10 : i8, umax = 20 : i8, smin = 10 : i8, smax = 20 : i8 } : i8950  // nsw stops overflow951  %1 = arith.muli %0, %cst10 overflow<nsw> : i8952  %2 = test.reflect_bounds %1 : i8953  return %2: i8954}955 956// CHECK-LABEL: func @test_shl_i8_wrap1957// CHECK: test.reflect_bounds {smax = 127 : si8, smin = -128 : si8, umax = 160 : ui8, umin = 80 : ui8}958func.func @test_shl_i8_wrap1() -> i8 {959  %cst3 = arith.constant 3 : i8960  %0 = test.with_bounds { umin = 10 : i8, umax = 20 : i8, smin = 10 : i8, smax = 20 : i8 } : i8961  // smax overflows962  %1 = arith.shli %0, %cst3 : i8963  %2 = test.reflect_bounds %1 : i8964  return %2: i8965}966 967// CHECK-LABEL: func @test_shl_i8_wrap2968// CHECK: test.reflect_bounds {smax = 127 : si8, smin = -128 : si8, umax = 160 : ui8, umin = 80 : ui8}969func.func @test_shl_i8_wrap2() -> i8 {970  %cst3 = arith.constant 3 : i8971  %0 = test.with_bounds { umin = 10 : i8, umax = 20 : i8, smin = 10 : i8, smax = 20 : i8 } : i8972  // smax overflows973  %1 = arith.shli %0, %cst3 overflow<nuw> : i8974  %2 = test.reflect_bounds %1 : i8975  return %2: i8976}977 978// CHECK-LABEL: func @test_shl_i8_nowrap979// CHECK: test.reflect_bounds {smax = 127 : si8, smin = 80 : si8, umax = 127 : ui8, umin = 80 : ui8}980func.func @test_shl_i8_nowrap() -> i8 {981  %cst3 = arith.constant 3 : i8982  %0 = test.with_bounds { umin = 10 : i8, umax = 20 : ui8, smin = 10 : i8, smax = 20 : i8 } : i8983  // nsw stops smax overflow984  %1 = arith.shli %0, %cst3 overflow<nsw> : i8985  %2 = test.reflect_bounds %1 : i8986  return %2: i8987}988 989/// A test case to ensure that the ranges for unsupported ops are initialized990/// properly to maxRange, rather than left uninitialized.991/// In this test case, the previous behavior would leave the ranges for %a and992/// %b uninitialized, resulting in arith.cmpf's range not being updated, even993/// though it has an integer valued result.994 995// CHECK-LABEL: func @test_cmpf_propagates996// CHECK: test.reflect_bounds {smax = 2 : index, smin = 1 : index, umax = 2 : index, umin = 1 : index}997func.func @test_cmpf_propagates(%a: f32, %b: f32) -> index {998  %c1 = arith.constant 1 : index999  %c2 = arith.constant 2 : index1000 1001  %0 = arith.cmpf ueq, %a, %b : f321002  %1 = arith.select %0, %c1, %c2 : index1003  %2 = test.reflect_bounds %1 : index1004  func.return %2 : index1005}1006 1007// CHECK-LABEL: func @zero_trip_loop1008func.func @zero_trip_loop() {1009  %idx1 = arith.constant 1 : index1010  scf.for %arg0 = %idx1 to %idx1 step %idx1 {1011    %138 = index.floordivs %arg0, %arg01012  }1013  return1014}1015 1016// CHECK-LABEL: func @zero_trip_loop21017func.func @zero_trip_loop2() {1018  %idx1 = arith.constant 1 : index1019  %idxm1 = arith.constant -1 : index1020  scf.for %arg0 = %idx1 to %idx1 step %idxm1 {1021    %138 = index.floordivs %arg0, %arg01022  }1023  return1024}1025 1026// CHECK-LABEL: @noninteger_operation_result1027func.func @noninteger_operation_result(%lb: index, %ub: index, %step: index, %cond: i1) {1028  %c1_i32 = arith.constant 1 : i321029 1030  %0 = "some_fp_op"() : () -> f321031  // CHECK: [[OUTS:%.*]]:2 = scf.for1032  %outs:2 = scf.for %i = %lb to %ub step %step iter_args(%a = %c1_i32, %b = %0) -> (i32, f32) {1033    %1:2 = "some_op"() : () -> (i32, f32)1034    scf.yield %1#0, %1#1 : i32, f321035  }1036 1037  // CHECK: [[RESULT:%.*]] = arith.select %{{.*}}, %c1_i32, [[OUTS]]#01038  %result = arith.select %cond, %c1_i32, %outs#0 : i321039  // CHECK: "use"([[RESULT]], [[OUTS]]#1)1040  "use"(%result, %outs#1) : (i32, f32) -> ()1041  return1042}1043