3406 lines · plain
1// RUN: mlir-opt %s -canonicalize="test-convergence" --split-input-file | FileCheck %s2 3// CHECK-LABEL: @select_same_val4// CHECK: return %arg15func.func @select_same_val(%arg0: i1, %arg1: i64) -> i64 {6 %0 = arith.select %arg0, %arg1, %arg1 : i647 return %0 : i648}9 10// CHECK-LABEL: @select_cmp_eq_select11// CHECK: return %arg112func.func @select_cmp_eq_select(%arg0: i64, %arg1: i64) -> i64 {13 %0 = arith.cmpi eq, %arg0, %arg1 : i6414 %1 = arith.select %0, %arg0, %arg1 : i6415 return %1 : i6416}17 18// CHECK-LABEL: @select_cmp_ne_select19// CHECK: return %arg020func.func @select_cmp_ne_select(%arg0: i64, %arg1: i64) -> i64 {21 %0 = arith.cmpi ne, %arg0, %arg1 : i6422 %1 = arith.select %0, %arg0, %arg1 : i6423 return %1 : i6424}25 26// CHECK-LABEL: @select_extui27// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i6428// CHECK: return %[[res]]29func.func @select_extui(%arg0: i1) -> i64 {30 %c0_i64 = arith.constant 0 : i6431 %c1_i64 = arith.constant 1 : i6432 %res = arith.select %arg0, %c1_i64, %c0_i64 : i6433 return %res : i6434}35 36// CHECK-LABEL: @select_extui237// CHECK-DAG: %true = arith.constant true38// CHECK-DAG: %[[xor:.+]] = arith.xori %arg0, %true : i139// CHECK-DAG: %[[res:.+]] = arith.extui %[[xor]] : i1 to i6440// CHECK: return %[[res]]41func.func @select_extui2(%arg0: i1) -> i64 {42 %c0_i64 = arith.constant 0 : i6443 %c1_i64 = arith.constant 1 : i6444 %res = arith.select %arg0, %c0_i64, %c1_i64 : i6445 return %res : i6446}47 48// CHECK-LABEL: @select_extui_i149// CHECK-NEXT: return %arg050func.func @select_extui_i1(%arg0: i1) -> i1 {51 %c0_i1 = arith.constant false52 %c1_i1 = arith.constant true53 %res = arith.select %arg0, %c1_i1, %c0_i1 : i154 return %res : i155}56 57// CHECK-LABEL: @select_no_fold_ui158// CHECK: %[[CONST_0:.+]] = "test.constant"() <{value = 0 : i32}> : () -> ui159// CHECK: %[[CONST_1:.+]] = "test.constant"() <{value = 1 : i32}> : () -> ui160// CHECK-NEXT: %[[RES:.+]] = arith.select %arg0, %[[CONST_1]], %[[CONST_0]] : ui161// CHECK-NEXT: return %[[RES]]62func.func @select_no_fold_ui1(%arg0: i1) -> ui1 {63 %c0_i1 = "test.constant"() {value = 0 : i32} : () -> ui164 %c1_i1 = "test.constant"() {value = 1 : i32} : () -> ui165 %res = arith.select %arg0, %c1_i1, %c0_i1 : ui166 return %res : ui167}68 69// CHECK-LABEL: @select_cst_false_scalar70// CHECK-SAME: (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)71// CHECK-NEXT: return %[[ARG1]]72func.func @select_cst_false_scalar(%arg0: i32, %arg1: i32) -> i32 {73 %false = arith.constant false74 %res = arith.select %false, %arg0, %arg1 : i3275 return %res : i3276}77 78// CHECK-LABEL: @select_cst_true_scalar79// CHECK-SAME: (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)80// CHECK-NEXT: return %[[ARG0]]81func.func @select_cst_true_scalar(%arg0: i32, %arg1: i32) -> i32 {82 %true = arith.constant true83 %res = arith.select %true, %arg0, %arg1 : i3284 return %res : i3285}86 87// CHECK-LABEL: @select_cst_true_splat88// CHECK: %[[A:.+]] = arith.constant dense<[1, 2, 3]> : vector<3xi32>89// CHECK-NEXT: return %[[A]]90func.func @select_cst_true_splat() -> vector<3xi32> {91 %cond = arith.constant dense<true> : vector<3xi1>92 %a = arith.constant dense<[1, 2, 3]> : vector<3xi32>93 %b = arith.constant dense<[4, 5, 6]> : vector<3xi32>94 %res = arith.select %cond, %a, %b : vector<3xi1>, vector<3xi32>95 return %res : vector<3xi32>96}97 98// CHECK-LABEL: @select_cst_vector_i3299// CHECK: %[[RES:.+]] = arith.constant dense<[1, 5, 3]> : vector<3xi32>100// CHECK-NEXT: return %[[RES]]101func.func @select_cst_vector_i32() -> vector<3xi32> {102 %cond = arith.constant dense<[true, false, true]> : vector<3xi1>103 %a = arith.constant dense<[1, 2, 3]> : vector<3xi32>104 %b = arith.constant dense<[4, 5, 6]> : vector<3xi32>105 %res = arith.select %cond, %a, %b : vector<3xi1>, vector<3xi32>106 return %res : vector<3xi32>107}108 109// CHECK-LABEL: @select_cst_vector_f32110// CHECK: %[[RES:.+]] = arith.constant dense<[4.000000e+00, 2.000000e+00, 6.000000e+00]> : vector<3xf32>111// CHECK-NEXT: return %[[RES]]112func.func @select_cst_vector_f32() -> vector<3xf32> {113 %cond = arith.constant dense<[false, true, false]> : vector<3xi1>114 %a = arith.constant dense<[1.0, 2.0, 3.0]> : vector<3xf32>115 %b = arith.constant dense<[4.0, 5.0, 6.0]> : vector<3xf32>116 %res = arith.select %cond, %a, %b : vector<3xi1>, vector<3xf32>117 return %res : vector<3xf32>118}119 120// CHECK-LABEL: @selToNot121// CHECK: %[[trueval:.+]] = arith.constant true122// CHECK: %[[res:.+]] = arith.xori %arg0, %[[trueval]] : i1123// CHECK: return %[[res]]124func.func @selToNot(%arg0: i1) -> i1 {125 %true = arith.constant true126 %false = arith.constant false127 %res = arith.select %arg0, %false, %true : i1128 return %res : i1129}130 131// CHECK-LABEL: @redundantSelectTrue132// CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg1, %arg3133// CHECK-NEXT: return %[[res]]134func.func @redundantSelectTrue(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32) -> i32 {135 %0 = arith.select %arg0, %arg1, %arg2 : i32136 %res = arith.select %arg0, %0, %arg3 : i32137 return %res : i32138}139 140// CHECK-LABEL: @redundantSelectFalse141// CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg3, %arg2142// CHECK-NEXT: return %[[res]]143func.func @redundantSelectFalse(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32) -> i32 {144 %0 = arith.select %arg0, %arg1, %arg2 : i32145 %res = arith.select %arg0, %arg3, %0 : i32146 return %res : i32147}148 149// CHECK-LABEL: @selNotCond150// CHECK-NEXT: %[[res1:.+]] = arith.select %arg0, %arg2, %arg1151// CHECK-NEXT: %[[res2:.+]] = arith.select %arg0, %arg4, %arg3152// CHECK-NEXT: return %[[res1]], %[[res2]]153func.func @selNotCond(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32, %arg4 : i32) -> (i32, i32) {154 %one = arith.constant 1 : i1155 %cond1 = arith.xori %arg0, %one : i1156 %cond2 = arith.xori %one, %arg0 : i1157 158 %res1 = arith.select %cond1, %arg1, %arg2 : i32159 %res2 = arith.select %cond2, %arg3, %arg4 : i32160 return %res1, %res2 : i32, i32161}162 163// CHECK-LABEL: @cmpiI1eq164// CHECK-SAME: (%[[ARG:.*]]: i1)165// CHECK: return %[[ARG]]166func.func @cmpiI1eq(%arg0: i1) -> i1 {167 %one = arith.constant 1 : i1168 %res = arith.cmpi eq, %arg0, %one : i1169 return %res : i1170}171 172// CHECK-LABEL: @cmpiI1eqVec173// CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)174// CHECK: return %[[ARG]]175func.func @cmpiI1eqVec(%arg0: vector<4xi1>) -> vector<4xi1> {176 %one = arith.constant dense<1> : vector<4xi1>177 %res = arith.cmpi eq, %arg0, %one : vector<4xi1>178 return %res : vector<4xi1>179}180 181// CHECK-LABEL: @cmpiI1ne182// CHECK-SAME: (%[[ARG:.*]]: i1)183// CHECK: return %[[ARG]]184func.func @cmpiI1ne(%arg0: i1) -> i1 {185 %zero = arith.constant 0 : i1186 %res = arith.cmpi ne, %arg0, %zero : i1187 return %res : i1188}189 190// CHECK-LABEL: @cmpiI1neVec191// CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)192// CHECK: return %[[ARG]]193func.func @cmpiI1neVec(%arg0: vector<4xi1>) -> vector<4xi1> {194 %zero = arith.constant dense<0> : vector<4xi1>195 %res = arith.cmpi ne, %arg0, %zero : vector<4xi1>196 return %res : vector<4xi1>197}198 199// CHECK-LABEL: @cmpiI1eqLhs200// CHECK-SAME: (%[[ARG:.*]]: i1)201// CHECK: return %[[ARG]]202func.func @cmpiI1eqLhs(%arg0: i1) -> i1 {203 %one = arith.constant 1 : i1204 %res = arith.cmpi eq, %one, %arg0 : i1205 return %res : i1206}207 208// CHECK-LABEL: @cmpiI1eqVecLhs209// CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)210// CHECK: return %[[ARG]]211func.func @cmpiI1eqVecLhs(%arg0: vector<4xi1>) -> vector<4xi1> {212 %one = arith.constant dense<1> : vector<4xi1>213 %res = arith.cmpi eq, %one, %arg0 : vector<4xi1>214 return %res : vector<4xi1>215}216 217// CHECK-LABEL: @cmpiI1neLhs218// CHECK-SAME: (%[[ARG:.*]]: i1)219// CHECK: return %[[ARG]]220func.func @cmpiI1neLhs(%arg0: i1) -> i1 {221 %zero = arith.constant 0 : i1222 %res = arith.cmpi ne, %zero, %arg0 : i1223 return %res : i1224}225 226// CHECK-LABEL: @cmpiI1neVecLhs227// CHECK-SAME: (%[[ARG:.*]]: vector<4xi1>)228// CHECK: return %[[ARG]]229func.func @cmpiI1neVecLhs(%arg0: vector<4xi1>) -> vector<4xi1> {230 %zero = arith.constant dense<0> : vector<4xi1>231 %res = arith.cmpi ne, %zero, %arg0 : vector<4xi1>232 return %res : vector<4xi1>233}234 235// Test case: Folding of comparisons with equal operands.236// CHECK-LABEL: @cmpi_equal_operands237// CHECK-DAG: %[[T:.*]] = arith.constant true238// CHECK-DAG: %[[F:.*]] = arith.constant false239// CHECK: return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]],240// CHECK-SAME: %[[F]], %[[F]], %[[F]], %[[F]], %[[F]]241func.func @cmpi_equal_operands(%arg0: i64)242 -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {243 %0 = arith.cmpi eq, %arg0, %arg0 : i64244 %1 = arith.cmpi sle, %arg0, %arg0 : i64245 %2 = arith.cmpi sge, %arg0, %arg0 : i64246 %3 = arith.cmpi ule, %arg0, %arg0 : i64247 %4 = arith.cmpi uge, %arg0, %arg0 : i64248 %5 = arith.cmpi ne, %arg0, %arg0 : i64249 %6 = arith.cmpi slt, %arg0, %arg0 : i64250 %7 = arith.cmpi sgt, %arg0, %arg0 : i64251 %8 = arith.cmpi ult, %arg0, %arg0 : i64252 %9 = arith.cmpi ugt, %arg0, %arg0 : i64253 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9254 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1255}256 257// Test case: Folding of comparisons with equal vector operands.258// CHECK-LABEL: @cmpi_equal_vector_operands259// CHECK-DAG: %[[T:.*]] = arith.constant dense<true>260// CHECK-DAG: %[[F:.*]] = arith.constant dense<false>261// CHECK: return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]],262// CHECK-SAME: %[[F]], %[[F]], %[[F]], %[[F]], %[[F]]263func.func @cmpi_equal_vector_operands(%arg0: vector<1x8xi64>)264 -> (vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,265 vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,266 vector<1x8xi1>, vector<1x8xi1>) {267 %0 = arith.cmpi eq, %arg0, %arg0 : vector<1x8xi64>268 %1 = arith.cmpi sle, %arg0, %arg0 : vector<1x8xi64>269 %2 = arith.cmpi sge, %arg0, %arg0 : vector<1x8xi64>270 %3 = arith.cmpi ule, %arg0, %arg0 : vector<1x8xi64>271 %4 = arith.cmpi uge, %arg0, %arg0 : vector<1x8xi64>272 %5 = arith.cmpi ne, %arg0, %arg0 : vector<1x8xi64>273 %6 = arith.cmpi slt, %arg0, %arg0 : vector<1x8xi64>274 %7 = arith.cmpi sgt, %arg0, %arg0 : vector<1x8xi64>275 %8 = arith.cmpi ult, %arg0, %arg0 : vector<1x8xi64>276 %9 = arith.cmpi ugt, %arg0, %arg0 : vector<1x8xi64>277 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9278 : vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,279 vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>,280 vector<1x8xi1>, vector<1x8xi1>281}282 283// -----284 285// Test case: Move constant to the right side.286// CHECK-LABEL: @cmpi_const_right(287// CHECK-SAME: %[[ARG:.*]]:288// CHECK: %[[C:.*]] = arith.constant 1 : i64289// CHECK: %[[R0:.*]] = arith.cmpi eq, %[[ARG]], %[[C]] : i64290// CHECK: %[[R1:.*]] = arith.cmpi sge, %[[ARG]], %[[C]] : i64291// CHECK: %[[R2:.*]] = arith.cmpi sle, %[[ARG]], %[[C]] : i64292// CHECK: %[[R3:.*]] = arith.cmpi uge, %[[ARG]], %[[C]] : i64293// CHECK: %[[R4:.*]] = arith.cmpi ule, %[[ARG]], %[[C]] : i64294// CHECK: %[[R5:.*]] = arith.cmpi ne, %[[ARG]], %[[C]] : i64295// CHECK: %[[R6:.*]] = arith.cmpi sgt, %[[ARG]], %[[C]] : i64296// CHECK: %[[R7:.*]] = arith.cmpi slt, %[[ARG]], %[[C]] : i64297// CHECK: %[[R8:.*]] = arith.cmpi ugt, %[[ARG]], %[[C]] : i64298// CHECK: %[[R9:.*]] = arith.cmpi ult, %[[ARG]], %[[C]] : i64299// CHECK: return %[[R0]], %[[R1]], %[[R2]], %[[R3]], %[[R4]],300// CHECK-SAME: %[[R5]], %[[R6]], %[[R7]], %[[R8]], %[[R9]]301func.func @cmpi_const_right(%arg0: i64)302 -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {303 %c1 = arith.constant 1 : i64304 %0 = arith.cmpi eq, %c1, %arg0 : i64305 %1 = arith.cmpi sle, %c1, %arg0 : i64306 %2 = arith.cmpi sge, %c1, %arg0 : i64307 %3 = arith.cmpi ule, %c1, %arg0 : i64308 %4 = arith.cmpi uge, %c1, %arg0 : i64309 %5 = arith.cmpi ne, %c1, %arg0 : i64310 %6 = arith.cmpi slt, %c1, %arg0 : i64311 %7 = arith.cmpi sgt, %c1, %arg0 : i64312 %8 = arith.cmpi ult, %c1, %arg0 : i64313 %9 = arith.cmpi ugt, %c1, %arg0 : i64314 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9315 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1316}317 318// -----319 320// CHECK-LABEL: @cmpOfExtSI(321// CHECK-NEXT: return %arg0322func.func @cmpOfExtSI(%arg0: i1) -> i1 {323 %ext = arith.extsi %arg0 : i1 to i64324 %c0 = arith.constant 0 : i64325 %res = arith.cmpi ne, %ext, %c0 : i64326 return %res : i1327}328 329// CHECK-LABEL: @cmpOfExtUI(330// CHECK-NEXT: return %arg0331func.func @cmpOfExtUI(%arg0: i1) -> i1 {332 %ext = arith.extui %arg0 : i1 to i64333 %c0 = arith.constant 0 : i64334 %res = arith.cmpi ne, %ext, %c0 : i64335 return %res : i1336}337 338// -----339 340// CHECK-LABEL: @cmpOfExtSIVector(341// CHECK-NEXT: return %arg0342func.func @cmpOfExtSIVector(%arg0: vector<4xi1>) -> vector<4xi1> {343 %ext = arith.extsi %arg0 : vector<4xi1> to vector<4xi64>344 %c0 = arith.constant dense<0> : vector<4xi64>345 %res = arith.cmpi ne, %ext, %c0 : vector<4xi64>346 return %res : vector<4xi1>347}348 349// CHECK-LABEL: @cmpOfExtUIVector(350// CHECK-NEXT: return %arg0351func.func @cmpOfExtUIVector(%arg0: vector<4xi1>) -> vector<4xi1> {352 %ext = arith.extui %arg0 : vector<4xi1> to vector<4xi64>353 %c0 = arith.constant dense<0> : vector<4xi64>354 %res = arith.cmpi ne, %ext, %c0 : vector<4xi64>355 return %res : vector<4xi1>356}357 358// -----359 360// CHECK-LABEL: @extSIOfExtUI361// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i64362// CHECK: return %[[res]]363func.func @extSIOfExtUI(%arg0: i1) -> i64 {364 %ext1 = arith.extui %arg0 : i1 to i8365 %ext2 = arith.extsi %ext1 : i8 to i64366 return %ext2 : i64367}368 369// CHECK-LABEL: @extUIOfExtUI370// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i64371// CHECK: return %[[res]]372func.func @extUIOfExtUI(%arg0: i1) -> i64 {373 %ext1 = arith.extui %arg0 : i1 to i8374 %ext2 = arith.extui %ext1 : i8 to i64375 return %ext2 : i64376}377 378// CHECK-LABEL: @extSIOfExtSI379// CHECK: %[[res:.+]] = arith.extsi %arg0 : i1 to i64380// CHECK: return %[[res]]381func.func @extSIOfExtSI(%arg0: i1) -> i64 {382 %ext1 = arith.extsi %arg0 : i1 to i8383 %ext2 = arith.extsi %ext1 : i8 to i64384 return %ext2 : i64385}386 387// -----388 389// CHECK-LABEL: @cmpIExtSINE390// CHECK: %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8391// CHECK: return %[[comb]]392func.func @cmpIExtSINE(%arg0: i8, %arg1: i8) -> i1 {393 %ext0 = arith.extsi %arg0 : i8 to i64394 %ext1 = arith.extsi %arg1 : i8 to i64395 %res = arith.cmpi ne, %ext0, %ext1 : i64396 return %res : i1397}398 399// CHECK-LABEL: @cmpIExtSIEQ400// CHECK: %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8401// CHECK: return %[[comb]]402func.func @cmpIExtSIEQ(%arg0: i8, %arg1: i8) -> i1 {403 %ext0 = arith.extsi %arg0 : i8 to i64404 %ext1 = arith.extsi %arg1 : i8 to i64405 %res = arith.cmpi eq, %ext0, %ext1 : i64406 return %res : i1407}408 409// CHECK-LABEL: @cmpIExtUINE410// CHECK: %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8411// CHECK: return %[[comb]]412func.func @cmpIExtUINE(%arg0: i8, %arg1: i8) -> i1 {413 %ext0 = arith.extui %arg0 : i8 to i64414 %ext1 = arith.extui %arg1 : i8 to i64415 %res = arith.cmpi ne, %ext0, %ext1 : i64416 return %res : i1417}418 419// CHECK-LABEL: @cmpIExtUIEQ420// CHECK: %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8421// CHECK: return %[[comb]]422func.func @cmpIExtUIEQ(%arg0: i8, %arg1: i8) -> i1 {423 %ext0 = arith.extui %arg0 : i8 to i64424 %ext1 = arith.extui %arg1 : i8 to i64425 %res = arith.cmpi eq, %ext0, %ext1 : i64426 return %res : i1427}428 429// CHECK-LABEL: @cmpIFoldEQ430// CHECK: %[[res:.+]] = arith.constant dense<[true, true, false]> : vector<3xi1>431// CHECK: return %[[res]]432func.func @cmpIFoldEQ() -> vector<3xi1> {433 %lhs = arith.constant dense<[1, 2, 3]> : vector<3xi32>434 %rhs = arith.constant dense<[1, 2, 4]> : vector<3xi32>435 %res = arith.cmpi eq, %lhs, %rhs : vector<3xi32>436 return %res : vector<3xi1>437}438 439// CHECK-LABEL: @cmpIFoldNE440// CHECK: %[[res:.+]] = arith.constant dense<[false, false, true]> : vector<3xi1>441// CHECK: return %[[res]]442func.func @cmpIFoldNE() -> vector<3xi1> {443 %lhs = arith.constant dense<[1, 2, 3]> : vector<3xi32>444 %rhs = arith.constant dense<[1, 2, 4]> : vector<3xi32>445 %res = arith.cmpi ne, %lhs, %rhs : vector<3xi32>446 return %res : vector<3xi1>447}448 449// CHECK-LABEL: @cmpIFoldSGE450// CHECK: %[[res:.+]] = arith.constant dense<[true, true, false]> : vector<3xi1>451// CHECK: return %[[res]]452func.func @cmpIFoldSGE() -> vector<3xi1> {453 %lhs = arith.constant dense<2> : vector<3xi32>454 %rhs = arith.constant dense<[1, 2, 4]> : vector<3xi32>455 %res = arith.cmpi sge, %lhs, %rhs : vector<3xi32>456 return %res : vector<3xi1>457}458 459// CHECK-LABEL: @cmpIFoldULT460// CHECK: %[[res:.+]] = arith.constant dense<false> : vector<3xi1>461// CHECK: return %[[res]]462func.func @cmpIFoldULT() -> vector<3xi1> {463 %lhs = arith.constant dense<2> : vector<3xi32>464 %rhs = arith.constant dense<1> : vector<3xi32>465 %res = arith.cmpi ult, %lhs, %rhs : vector<3xi32>466 return %res : vector<3xi1>467}468 469// -----470 471// CHECK-LABEL: @andOfExtSI472// CHECK: %[[comb:.+]] = arith.andi %arg0, %arg1 : i8473// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64474// CHECK: return %[[ext]]475func.func @andOfExtSI(%arg0: i8, %arg1: i8) -> i64 {476 %ext0 = arith.extsi %arg0 : i8 to i64477 %ext1 = arith.extsi %arg1 : i8 to i64478 %res = arith.andi %ext0, %ext1 : i64479 return %res : i64480}481 482// CHECK-LABEL: @andOfExtUI483// CHECK: %[[comb:.+]] = arith.andi %arg0, %arg1 : i8484// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64485// CHECK: return %[[ext]]486func.func @andOfExtUI(%arg0: i8, %arg1: i8) -> i64 {487 %ext0 = arith.extui %arg0 : i8 to i64488 %ext1 = arith.extui %arg1 : i8 to i64489 %res = arith.andi %ext0, %ext1 : i64490 return %res : i64491}492 493// CHECK-LABEL: @orOfExtSI494// CHECK: %[[comb:.+]] = arith.ori %arg0, %arg1 : i8495// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64496// CHECK: return %[[ext]]497func.func @orOfExtSI(%arg0: i8, %arg1: i8) -> i64 {498 %ext0 = arith.extsi %arg0 : i8 to i64499 %ext1 = arith.extsi %arg1 : i8 to i64500 %res = arith.ori %ext0, %ext1 : i64501 return %res : i64502}503 504// CHECK-LABEL: @orOfExtUI505// CHECK: %[[comb:.+]] = arith.ori %arg0, %arg1 : i8506// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64507// CHECK: return %[[ext]]508func.func @orOfExtUI(%arg0: i8, %arg1: i8) -> i64 {509 %ext0 = arith.extui %arg0 : i8 to i64510 %ext1 = arith.extui %arg1 : i8 to i64511 %res = arith.ori %ext0, %ext1 : i64512 return %res : i64513}514 515// -----516 517// CHECK-LABEL: @indexCastOfSignExtend518// CHECK: %[[res:.+]] = arith.index_cast %arg0 : i8 to index519// CHECK: return %[[res]]520func.func @indexCastOfSignExtend(%arg0: i8) -> index {521 %ext = arith.extsi %arg0 : i8 to i16522 %idx = arith.index_cast %ext : i16 to index523 return %idx : index524}525 526// CHECK-LABEL: @indexCastUIOfUnsignedExtend527// CHECK: %[[res:.+]] = arith.index_castui %arg0 : i8 to index528// CHECK: return %[[res]]529func.func @indexCastUIOfUnsignedExtend(%arg0: i8) -> index {530 %ext = arith.extui %arg0 : i8 to i16531 %idx = arith.index_castui %ext : i16 to index532 return %idx : index533}534 535// CHECK-LABEL: @indexCastFold536// CHECK: %[[res:.*]] = arith.constant -2 : index537// CHECK: return %[[res]]538func.func @indexCastFold() -> index {539 %c-2 = arith.constant -2 : i8540 %idx = arith.index_cast %c-2 : i8 to index541 return %idx : index542}543 544// CHECK-LABEL: @indexCastFoldIndexToInt545// CHECK: %[[res:.*]] = arith.constant 1 : i32546// CHECK: return %[[res]]547func.func @indexCastFoldIndexToInt() -> i32 {548 %c1 = arith.constant 1 : index549 %int = arith.index_cast %c1 : index to i32550 return %int : i32551}552 553// CHECK-LABEL: @indexCastFoldSplatVector554// CHECK: %[[res:.*]] = arith.constant dense<42> : vector<3xindex>555// CHECK: return %[[res]] : vector<3xindex>556func.func @indexCastFoldSplatVector() -> vector<3xindex> {557 %cst = arith.constant dense<42> : vector<3xi32>558 %int = arith.index_cast %cst : vector<3xi32> to vector<3xindex>559 return %int : vector<3xindex>560}561 562// CHECK-LABEL: @indexCastFoldVector563// CHECK: %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xindex>564// CHECK: return %[[res]] : vector<3xindex>565func.func @indexCastFoldVector() -> vector<3xindex> {566 %cst = arith.constant dense<[1, 2, 3]> : vector<3xi32>567 %int = arith.index_cast %cst : vector<3xi32> to vector<3xindex>568 return %int : vector<3xindex>569}570 571// CHECK-LABEL: @indexCastFoldSplatVectorIndexToInt572// CHECK: %[[res:.*]] = arith.constant dense<42> : vector<3xi32>573// CHECK: return %[[res]] : vector<3xi32>574func.func @indexCastFoldSplatVectorIndexToInt() -> vector<3xi32> {575 %cst = arith.constant dense<42> : vector<3xindex>576 %int = arith.index_cast %cst : vector<3xindex> to vector<3xi32>577 return %int : vector<3xi32>578}579 580// CHECK-LABEL: @indexCastFoldVectorIndexToInt581// CHECK: %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xi32>582// CHECK: return %[[res]] : vector<3xi32>583func.func @indexCastFoldVectorIndexToInt() -> vector<3xi32> {584 %cst = arith.constant dense<[1, 2, 3]> : vector<3xindex>585 %int = arith.index_cast %cst : vector<3xindex> to vector<3xi32>586 return %int : vector<3xi32>587}588 589// CHECK-LABEL: @indexCastUIFold590// CHECK: %[[res:.*]] = arith.constant 254 : index591// CHECK: return %[[res]]592func.func @indexCastUIFold() -> index {593 %c-2 = arith.constant -2 : i8594 %idx = arith.index_castui %c-2 : i8 to index595 return %idx : index596}597 598// CHECK-LABEL: @indexCastUIFoldSplatVector599// CHECK: %[[res:.*]] = arith.constant dense<42> : vector<3xindex>600// CHECK: return %[[res]] : vector<3xindex>601func.func @indexCastUIFoldSplatVector() -> vector<3xindex> {602 %cst = arith.constant dense<42> : vector<3xi32>603 %int = arith.index_castui %cst : vector<3xi32> to vector<3xindex>604 return %int : vector<3xindex>605}606 607// CHECK-LABEL: @indexCastUIFoldVector608// CHECK: %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xindex>609// CHECK: return %[[res]] : vector<3xindex>610func.func @indexCastUIFoldVector() -> vector<3xindex> {611 %cst = arith.constant dense<[1, 2, 3]> : vector<3xi32>612 %int = arith.index_castui %cst : vector<3xi32> to vector<3xindex>613 return %int : vector<3xindex>614}615 616// CHECK-LABEL: @indexCastUIFoldIndexToInt617// CHECK: %[[res:.*]] = arith.constant 1 : i32618// CHECK: return %[[res]]619func.func @indexCastUIFoldIndexToInt() -> i32 {620 %c1 = arith.constant 1 : index621 %int = arith.index_castui %c1 : index to i32622 return %int : i32623}624 625// CHECK-LABEL: @indexCastUIFoldSplatVectorIndexToInt626// CHECK: %[[res:.*]] = arith.constant dense<42> : vector<3xi32>627// CHECK: return %[[res]] : vector<3xi32>628func.func @indexCastUIFoldSplatVectorIndexToInt() -> vector<3xi32> {629 %cst = arith.constant dense<42> : vector<3xindex>630 %int = arith.index_castui %cst : vector<3xindex> to vector<3xi32>631 return %int : vector<3xi32>632}633 634// CHECK-LABEL: @indexCastUIFoldVectorIndexToInt635// CHECK: %[[res:.*]] = arith.constant dense<[1, 2, 3]> : vector<3xi32>636// CHECK: return %[[res]] : vector<3xi32>637func.func @indexCastUIFoldVectorIndexToInt() -> vector<3xi32> {638 %cst = arith.constant dense<[1, 2, 3]> : vector<3xindex>639 %int = arith.index_castui %cst : vector<3xindex> to vector<3xi32>640 return %int : vector<3xi32>641}642 643// CHECK-LABEL: @signExtendConstant644// CHECK: %[[cres:.+]] = arith.constant -2 : i16645// CHECK: return %[[cres]]646func.func @signExtendConstant() -> i16 {647 %c-2 = arith.constant -2 : i8648 %ext = arith.extsi %c-2 : i8 to i16649 return %ext : i16650}651 652// CHECK-LABEL: @signExtendConstantSplat653// CHECK: %[[cres:.+]] = arith.constant dense<-2> : vector<4xi16>654// CHECK: return %[[cres]]655func.func @signExtendConstantSplat() -> vector<4xi16> {656 %c-2 = arith.constant -2 : i8657 %splat = vector.broadcast %c-2 : i8 to vector<4xi8>658 %ext = arith.extsi %splat : vector<4xi8> to vector<4xi16>659 return %ext : vector<4xi16>660}661 662// CHECK-LABEL: @signExtendConstantVector663// CHECK: %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>664// CHECK: return %[[cres]]665func.func @signExtendConstantVector() -> vector<4xi16> {666 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>667 %ext = arith.extsi %vector : vector<4xi8> to vector<4xi16>668 return %ext : vector<4xi16>669}670 671// CHECK-LABEL: @unsignedExtendConstant672// CHECK: %[[cres:.+]] = arith.constant 2 : i16673// CHECK: return %[[cres]]674func.func @unsignedExtendConstant() -> i16 {675 %c2 = arith.constant 2 : i8676 %ext = arith.extui %c2 : i8 to i16677 return %ext : i16678}679 680// CHECK-LABEL: @unsignedExtendConstantSplat681// CHECK: %[[cres:.+]] = arith.constant dense<2> : vector<4xi16>682// CHECK: return %[[cres]]683func.func @unsignedExtendConstantSplat() -> vector<4xi16> {684 %c2 = arith.constant 2 : i8685 %splat = vector.broadcast %c2 : i8 to vector<4xi8>686 %ext = arith.extui %splat : vector<4xi8> to vector<4xi16>687 return %ext : vector<4xi16>688}689 690// CHECK-LABEL: @unsignedExtendConstantVector691// CHECK: %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>692// CHECK: return %[[cres]]693func.func @unsignedExtendConstantVector() -> vector<4xi16> {694 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>695 %ext = arith.extui %vector : vector<4xi8> to vector<4xi16>696 return %ext : vector<4xi16>697}698 699// CHECK-LABEL: @extFPConstant700// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : f64701// CHECK: return %[[cres]]702func.func @extFPConstant() -> f64 {703 %cst = arith.constant 1.000000e+00 : f32704 %0 = arith.extf %cst : f32 to f64705 return %0 : f64706}707 708// CHECK-LABEL: @extFPVectorConstant709// CHECK: %[[cres:.+]] = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xf128>710// CHECK: return %[[cres]]711func.func @extFPVectorConstant() -> vector<2xf128> {712 %cst = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xf80>713 %0 = arith.extf %cst : vector<2xf80> to vector<2xf128>714 return %0 : vector<2xf128>715}716 717// CHECK-LABEL: @truncExtf718// CHECK-NOT: truncf719// CHECK: return %arg0720func.func @truncExtf(%arg0: f32) -> f32 {721 %extf = arith.extf %arg0 : f32 to f64722 %trunc = arith.truncf %extf : f64 to f32723 return %trunc : f32724}725 726// CHECK-LABEL: @truncExtf1727// CHECK-NOT: truncf728// CHECK: return %arg0729func.func @truncExtf1(%arg0: bf16) -> bf16 {730 %extf = arith.extf %arg0 : bf16 to f32731 %trunc = arith.truncf %extf : f32 to bf16732 return %trunc : bf16733}734 735// CHECK-LABEL: @truncExtf2736// CHECK: %[[ARG0:.+]]: bf16737// CHECK: %[[EXTF:.*]] = arith.extf %[[ARG0:.+]] : bf16 to f32738// CHECK: %[[TRUNCF:.*]] = arith.truncf %[[EXTF:.*]] : f32 to f16739// CHECK: return %[[TRUNCF:.*]]740func.func @truncExtf2(%arg0: bf16) -> f16 {741 %extf = arith.extf %arg0 : bf16 to f32742 %trunc = arith.truncf %extf : f32 to f16743 return %trunc : f16744}745 746// CHECK-LABEL: @truncExtf3747// CHECK: %[[ARG0:.+]]: f32748// CHECK: %[[CST:.*]] = arith.truncf %[[ARG0:.+]] : f32 to f16749// CHECK: return %[[CST:.*]]750func.func @truncExtf3(%arg0: f32) -> f16 {751 %extf = arith.extf %arg0 : f32 to f64752 %truncf = arith.truncf %extf : f64 to f16753 return %truncf : f16754}755 756// CHECK-LABEL: @truncSitofp757// CHECK: %[[SITOFP:.*]] = arith.sitofp %[[ARG0:.*]] : i32 to f32758// CHECK-NOT: truncf759// CHECK: return %[[SITOFP]]760func.func @truncSitofp(%arg0: i32) -> f32 {761 %sitofp = arith.sitofp %arg0 : i32 to f64762 %trunc = arith.truncf %sitofp : f64 to f32763 return %trunc : f32764}765 766// CHECK-LABEL: @truncSitofpConstrained767// CHECK: truncf768func.func @truncSitofpConstrained(%arg0: i32) -> f32 {769 %sitofp = arith.sitofp %arg0 : i32 to f64770 %trunc = arith.truncf %sitofp to_nearest_even : f64 to f32771 return %trunc : f32772}773 774// TODO: We should also add a test for not folding arith.extf on information loss.775// This may happen when extending f8E5M2FNUZ to f16.776 777// CHECK-LABEL: @truncConstant778// CHECK: %[[cres:.+]] = arith.constant -2 : i16779// CHECK: return %[[cres]]780func.func @truncConstant(%arg0: i8) -> i16 {781 %c-2 = arith.constant -2 : i32782 %tr = arith.trunci %c-2 : i32 to i16783 return %tr : i16784}785 786// CHECK-LABEL: @truncExtui787// CHECK-NOT: trunci788// CHECK: return %arg0789func.func @truncExtui(%arg0: i32) -> i32 {790 %extui = arith.extui %arg0 : i32 to i64791 %trunci = arith.trunci %extui : i64 to i32792 return %trunci : i32793}794 795// CHECK-LABEL: @truncExtui2796// CHECK: %[[ARG0:.+]]: i32797// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : i32 to i16798// CHECK: return %[[CST:.*]]799func.func @truncExtui2(%arg0: i32) -> i16 {800 %extui = arith.extui %arg0 : i32 to i64801 %trunci = arith.trunci %extui : i64 to i16802 return %trunci : i16803}804 805// CHECK-LABEL: @truncExtui3806// CHECK: %[[ARG0:.+]]: i8807// CHECK: %[[CST:.*]] = arith.extui %[[ARG0:.+]] : i8 to i16808// CHECK: return %[[CST:.*]] : i16809func.func @truncExtui3(%arg0: i8) -> i16 {810 %extui = arith.extui %arg0 : i8 to i32811 %trunci = arith.trunci %extui : i32 to i16812 return %trunci : i16813}814 815// CHECK-LABEL: @truncExtuiVector816// CHECK: %[[ARG0:.+]]: vector<2xi32>817// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : vector<2xi32> to vector<2xi16>818// CHECK: return %[[CST:.*]]819func.func @truncExtuiVector(%arg0: vector<2xi32>) -> vector<2xi16> {820 %extsi = arith.extui %arg0 : vector<2xi32> to vector<2xi64>821 %trunci = arith.trunci %extsi : vector<2xi64> to vector<2xi16>822 return %trunci : vector<2xi16>823}824 825// CHECK-LABEL: @truncExtsi826// CHECK-NOT: trunci827// CHECK: return %arg0828func.func @truncExtsi(%arg0: i32) -> i32 {829 %extsi = arith.extsi %arg0 : i32 to i64830 %trunci = arith.trunci %extsi : i64 to i32831 return %trunci : i32832}833 834// CHECK-LABEL: @truncExtsi2835// CHECK: %[[ARG0:.+]]: i32836// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : i32 to i16837// CHECK: return %[[CST:.*]]838func.func @truncExtsi2(%arg0: i32) -> i16 {839 %extsi = arith.extsi %arg0 : i32 to i64840 %trunci = arith.trunci %extsi : i64 to i16841 return %trunci : i16842}843 844// CHECK-LABEL: @truncExtsi3845// CHECK: %[[ARG0:.+]]: i8846// CHECK: %[[CST:.*]] = arith.extsi %[[ARG0:.+]] : i8 to i16847// CHECK: return %[[CST:.*]] : i16848func.func @truncExtsi3(%arg0: i8) -> i16 {849 %extsi = arith.extsi %arg0 : i8 to i32850 %trunci = arith.trunci %extsi : i32 to i16851 return %trunci : i16852}853 854// CHECK-LABEL: @truncExtsiVector855// CHECK: %[[ARG0:.+]]: vector<2xi32>856// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : vector<2xi32> to vector<2xi16>857// CHECK: return %[[CST:.*]]858func.func @truncExtsiVector(%arg0: vector<2xi32>) -> vector<2xi16> {859 %extsi = arith.extsi %arg0 : vector<2xi32> to vector<2xi64>860 %trunci = arith.trunci %extsi : vector<2xi64> to vector<2xi16>861 return %trunci : vector<2xi16>862}863 864// CHECK-LABEL: @truncConstantSplat865// CHECK: %[[cres:.+]] = arith.constant dense<-2> : vector<4xi8>866// CHECK: return %[[cres]]867func.func @truncConstantSplat() -> vector<4xi8> {868 %c-2 = arith.constant -2 : i16869 %splat = vector.broadcast %c-2 : i16 to vector<4xi16>870 %trunc = arith.trunci %splat : vector<4xi16> to vector<4xi8>871 return %trunc : vector<4xi8>872}873 874// CHECK-LABEL: @truncConstantVector875// CHECK: %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8>876// CHECK: return %[[cres]]877func.func @truncConstantVector() -> vector<4xi8> {878 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16>879 %trunc = arith.trunci %vector : vector<4xi16> to vector<4xi8>880 return %trunc : vector<4xi8>881}882 883// CHECK-LABEL: @truncTrunc884// CHECK: %[[cres:.+]] = arith.trunci %arg0 : i64 to i8885// CHECK: return %[[cres]]886func.func @truncTrunc(%arg0: i64) -> i8 {887 %tr1 = arith.trunci %arg0 : i64 to i32888 %tr2 = arith.trunci %tr1 : i32 to i8889 return %tr2 : i8890}891 892// CHECK-LABEL: @truncFPConstant893// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16894// CHECK: return %[[cres]]895func.func @truncFPConstant() -> bf16 {896 %cst = arith.constant 1.000000e+00 : f32897 %0 = arith.truncf %cst : f32 to bf16898 return %0 : bf16899}900 901// CHECK-LABEL: @truncFPToNearestEvenConstant902// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16903// CHECK: return %[[cres]]904func.func @truncFPToNearestEvenConstant() -> bf16 {905 %cst = arith.constant 1.000000e+00 : f32906 %0 = arith.truncf %cst to_nearest_even : f32 to bf16907 return %0 : bf16908}909 910// CHECK-LABEL: @truncFPDownwardConstant911// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16912// CHECK: return %[[cres]]913func.func @truncFPDownwardConstant() -> bf16 {914 %cst = arith.constant 1.000000e+00 : f32915 %0 = arith.truncf %cst downward : f32 to bf16916 return %0 : bf16917}918 919// CHECK-LABEL: @truncFPUpwardConstant920// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16921// CHECK: return %[[cres]]922func.func @truncFPUpwardConstant() -> bf16 {923 %cst = arith.constant 1.000000e+00 : f32924 %0 = arith.truncf %cst upward : f32 to bf16925 return %0 : bf16926}927 928// CHECK-LABEL: @truncFPTowardZeroConstant929// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16930// CHECK: return %[[cres]]931func.func @truncFPTowardZeroConstant() -> bf16 {932 %cst = arith.constant 1.000000e+00 : f32933 %0 = arith.truncf %cst toward_zero : f32 to bf16934 return %0 : bf16935}936 937// CHECK-LABEL: @truncFPToNearestAwayConstant938// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16939// CHECK: return %[[cres]]940func.func @truncFPToNearestAwayConstant() -> bf16 {941 %cst = arith.constant 1.000000e+00 : f32942 %0 = arith.truncf %cst to_nearest_away : f32 to bf16943 return %0 : bf16944}945 946// CHECK-LABEL: @truncFPVectorConstant947// CHECK: %[[cres:.+]] = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xbf16>948// CHECK: return %[[cres]]949func.func @truncFPVectorConstant() -> vector<2xbf16> {950 %cst = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xf32>951 %0 = arith.truncf %cst : vector<2xf32> to vector<2xbf16>952 return %0 : vector<2xbf16>953}954 955// Test that cases with rounding are NOT propagated956// CHECK-LABEL: @truncFPConstantRounding957// CHECK: arith.constant 1.444000e+25 : f32958// CHECK: truncf959func.func @truncFPConstantRounding() -> bf16 {960 %cst = arith.constant 1.444000e+25 : f32961 %0 = arith.truncf %cst : f32 to bf16962 return %0 : bf16963}964 965// CHECK-LABEL: @tripleAddAdd966// CHECK: %[[cres:.+]] = arith.constant 59 : index967// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index968// CHECK: return %[[add]]969func.func @tripleAddAdd(%arg0: index) -> index {970 %c17 = arith.constant 17 : index971 %c42 = arith.constant 42 : index972 %add1 = arith.addi %c17, %arg0 : index973 %add2 = arith.addi %c42, %add1 : index974 return %add2 : index975}976 977// CHECK-LABEL: @tripleAddAddOvf1978// CHECK: %[[cres:.+]] = arith.constant 59 : index979// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index980// CHECK: return %[[add]]981func.func @tripleAddAddOvf1(%arg0: index) -> index {982 %c17 = arith.constant 17 : index983 %c42 = arith.constant 42 : index984 %add1 = arith.addi %c17, %arg0 overflow<nsw, nuw> : index985 %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index986 return %add2 : index987}988 989// CHECK-LABEL: @tripleAddAddOvf2990// CHECK: %[[cres:.+]] = arith.constant 59 : index991// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index992// CHECK: return %[[add]]993func.func @tripleAddAddOvf2(%arg0: index) -> index {994 %c17 = arith.constant 17 : index995 %c42 = arith.constant 42 : index996 %add1 = arith.addi %c17, %arg0 overflow<nsw> : index997 %add2 = arith.addi %c42, %add1 overflow<nuw> : index998 return %add2 : index999}1000 1001 1002// CHECK-LABEL: @foldSubXX_tensor1003// CHECK: %[[c0:.+]] = arith.constant dense<0> : tensor<10xi32>1004// CHECK: %[[sub:.+]] = arith.subi1005// CHECK: return %[[c0]], %[[sub]]1006func.func @foldSubXX_tensor(%static : tensor<10xi32>, %dyn : tensor<?x?xi32>) -> (tensor<10xi32>, tensor<?x?xi32>) {1007 %static_sub = arith.subi %static, %static : tensor<10xi32>1008 %dyn_sub = arith.subi %dyn, %dyn : tensor<?x?xi32>1009 return %static_sub, %dyn_sub : tensor<10xi32>, tensor<?x?xi32>1010}1011 1012// CHECK-LABEL: @foldSubXX_vector1013// CHECK-DAG: %[[c0:.+]] = arith.constant dense<0> : vector<8xi32>1014// CHECK-DAG: %[[c0_scalable:.+]] = arith.constant dense<0> : vector<[4]xi32>1015// CHECK: return %[[c0]], %[[c0_scalable]]1016func.func @foldSubXX_vector(%static : vector<8xi32>, %dyn : vector<[4]xi32>) -> (vector<8xi32>, vector<[4]xi32>) {1017 %static_sub = arith.subi %static, %static : vector<8xi32>1018 %dyn_sub = arith.subi %dyn, %dyn : vector<[4]xi32>1019 return %static_sub, %dyn_sub : vector<8xi32>, vector<[4]xi32>1020}1021 1022// CHECK-LABEL: @tripleAddSub01023// CHECK: %[[cres:.+]] = arith.constant 59 : index1024// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index1025// CHECK: return %[[add]]1026func.func @tripleAddSub0(%arg0: index) -> index {1027 %c17 = arith.constant 17 : index1028 %c42 = arith.constant 42 : index1029 %add1 = arith.subi %c17, %arg0 : index1030 %add2 = arith.addi %c42, %add1 : index1031 return %add2 : index1032}1033 1034// CHECK-LABEL: @tripleAddSub0Ovf1035// CHECK: %[[cres:.+]] = arith.constant 59 : index1036// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index1037// CHECK: return %[[add]]1038func.func @tripleAddSub0Ovf(%arg0: index) -> index {1039 %c17 = arith.constant 17 : index1040 %c42 = arith.constant 42 : index1041 %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index1042 %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index1043 return %add2 : index1044}1045 1046// CHECK-LABEL: @tripleAddSub11047// CHECK: %[[cres:.+]] = arith.constant 25 : index1048// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index1049// CHECK: return %[[add]]1050func.func @tripleAddSub1(%arg0: index) -> index {1051 %c17 = arith.constant 17 : index1052 %c42 = arith.constant 42 : index1053 %add1 = arith.subi %arg0, %c17 : index1054 %add2 = arith.addi %c42, %add1 : index1055 return %add2 : index1056}1057 1058// CHECK-LABEL: @tripleAddSub1Ovf1059// CHECK: %[[cres:.+]] = arith.constant 25 : index1060// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index1061// CHECK: return %[[add]]1062func.func @tripleAddSub1Ovf(%arg0: index) -> index {1063 %c17 = arith.constant 17 : index1064 %c42 = arith.constant 42 : index1065 %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index1066 %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index1067 return %add2 : index1068}1069 1070// CHECK-LABEL: @tripleSubAdd01071// CHECK: %[[cres:.+]] = arith.constant 25 : index1072// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index1073// CHECK: return %[[add]]1074func.func @tripleSubAdd0(%arg0: index) -> index {1075 %c17 = arith.constant 17 : index1076 %c42 = arith.constant 42 : index1077 %add1 = arith.addi %c17, %arg0 : index1078 %add2 = arith.subi %c42, %add1 : index1079 return %add2 : index1080}1081 1082// CHECK-LABEL: @tripleSubAdd0Ovf1083// CHECK: %[[cres:.+]] = arith.constant 25 : index1084// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index1085// CHECK: return %[[add]]1086func.func @tripleSubAdd0Ovf(%arg0: index) -> index {1087 %c17 = arith.constant 17 : index1088 %c42 = arith.constant 42 : index1089 %add1 = arith.addi %c17, %arg0 overflow<nsw, nuw> : index1090 %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index1091 return %add2 : index1092}1093 1094// CHECK-LABEL: @tripleSubAdd11095// CHECK: %[[cres:.+]] = arith.constant -25 : index1096// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index1097// CHECK: return %[[add]]1098func.func @tripleSubAdd1(%arg0: index) -> index {1099 %c17 = arith.constant 17 : index1100 %c42 = arith.constant 42 : index1101 %add1 = arith.addi %c17, %arg0 : index1102 %add2 = arith.subi %add1, %c42 : index1103 return %add2 : index1104}1105 1106// CHECK-LABEL: @subSub01107// CHECK: %[[c0:.+]] = arith.constant 0 : index1108// CHECK: %[[add:.+]] = arith.subi %[[c0]], %arg1 : index1109// CHECK: return %[[add]]1110func.func @subSub0(%arg0: index, %arg1: index) -> index {1111 %sub1 = arith.subi %arg0, %arg1 : index1112 %sub2 = arith.subi %sub1, %arg0 : index1113 return %sub2 : index1114}1115 1116// CHECK-LABEL: @subSub0Ovf1117// CHECK: %[[c0:.+]] = arith.constant 0 : index1118// CHECK: %[[add:.+]] = arith.subi %[[c0]], %arg1 overflow<nsw, nuw> : index1119// CHECK: return %[[add]]1120func.func @subSub0Ovf(%arg0: index, %arg1: index) -> index {1121 %sub1 = arith.subi %arg0, %arg1 overflow<nsw, nuw> : index1122 %sub2 = arith.subi %sub1, %arg0 overflow<nsw, nuw> : index1123 return %sub2 : index1124}1125 1126// CHECK-LABEL: @tripleSubSub01127// CHECK: %[[cres:.+]] = arith.constant 25 : index1128// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index1129// CHECK: return %[[add]]1130func.func @tripleSubSub0(%arg0: index) -> index {1131 %c17 = arith.constant 17 : index1132 %c42 = arith.constant 42 : index1133 %add1 = arith.subi %c17, %arg0 : index1134 %add2 = arith.subi %c42, %add1 : index1135 return %add2 : index1136}1137 1138// CHECK-LABEL: @tripleSubSub0Ovf1139// CHECK: %[[cres:.+]] = arith.constant 25 : index1140// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index1141// CHECK: return %[[add]]1142func.func @tripleSubSub0Ovf(%arg0: index) -> index {1143 %c17 = arith.constant 17 : index1144 %c42 = arith.constant 42 : index1145 %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index1146 %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index1147 return %add2 : index1148}1149 1150 1151// CHECK-LABEL: @tripleSubSub11152// CHECK: %[[cres:.+]] = arith.constant -25 : index1153// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index1154// CHECK: return %[[add]]1155func.func @tripleSubSub1(%arg0: index) -> index {1156 %c17 = arith.constant 17 : index1157 %c42 = arith.constant 42 : index1158 %add1 = arith.subi %c17, %arg0 : index1159 %add2 = arith.subi %add1, %c42 : index1160 return %add2 : index1161}1162 1163// CHECK-LABEL: @tripleSubSub1Ovf1164// CHECK: %[[cres:.+]] = arith.constant -25 : index1165// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index1166// CHECK: return %[[add]]1167func.func @tripleSubSub1Ovf(%arg0: index) -> index {1168 %c17 = arith.constant 17 : index1169 %c42 = arith.constant 42 : index1170 %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index1171 %add2 = arith.subi %add1, %c42 overflow<nsw, nuw> : index1172 return %add2 : index1173}1174 1175// CHECK-LABEL: @tripleSubSub21176// CHECK: %[[cres:.+]] = arith.constant 59 : index1177// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index1178// CHECK: return %[[add]]1179func.func @tripleSubSub2(%arg0: index) -> index {1180 %c17 = arith.constant 17 : index1181 %c42 = arith.constant 42 : index1182 %add1 = arith.subi %arg0, %c17 : index1183 %add2 = arith.subi %c42, %add1 : index1184 return %add2 : index1185}1186 1187// CHECK-LABEL: @tripleSubSub2Ovf1188// CHECK: %[[cres:.+]] = arith.constant 59 : index1189// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index1190// CHECK: return %[[add]]1191func.func @tripleSubSub2Ovf(%arg0: index) -> index {1192 %c17 = arith.constant 17 : index1193 %c42 = arith.constant 42 : index1194 %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index1195 %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index1196 return %add2 : index1197}1198 1199// CHECK-LABEL: @tripleSubSub31200// CHECK: %[[cres:.+]] = arith.constant 59 : index1201// CHECK: %[[add:.+]] = arith.subi %arg0, %[[cres]] : index1202// CHECK: return %[[add]]1203func.func @tripleSubSub3(%arg0: index) -> index {1204 %c17 = arith.constant 17 : index1205 %c42 = arith.constant 42 : index1206 %add1 = arith.subi %arg0, %c17 : index1207 %add2 = arith.subi %add1, %c42 : index1208 return %add2 : index1209}1210 1211// CHECK-LABEL: @tripleSubSub3Ovf1212// CHECK: %[[cres:.+]] = arith.constant 59 : index1213// CHECK: %[[add:.+]] = arith.subi %arg0, %[[cres]] overflow<nsw, nuw> : index1214// CHECK: return %[[add]]1215func.func @tripleSubSub3Ovf(%arg0: index) -> index {1216 %c17 = arith.constant 17 : index1217 %c42 = arith.constant 42 : index1218 %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index1219 %add2 = arith.subi %add1, %c42 overflow<nsw, nuw> : index1220 return %add2 : index1221}1222 1223// CHECK-LABEL: @subAdd11224// CHECK-NEXT: return %arg01225func.func @subAdd1(%arg0: index, %arg1 : index) -> index {1226 %add = arith.addi %arg0, %arg1 : index1227 %sub = arith.subi %add, %arg1 : index1228 return %sub : index1229}1230 1231// CHECK-LABEL: @subAdd21232// CHECK-NEXT: return %arg11233func.func @subAdd2(%arg0: index, %arg1 : index) -> index {1234 %add = arith.addi %arg0, %arg1 : index1235 %sub = arith.subi %add, %arg0 : index1236 return %sub : index1237}1238 1239// CHECK-LABEL: @doubleAddSub11240// CHECK-NEXT: return %arg01241func.func @doubleAddSub1(%arg0: index, %arg1 : index) -> index {1242 %sub = arith.subi %arg0, %arg1 : index1243 %add = arith.addi %sub, %arg1 : index1244 return %add : index1245}1246 1247// CHECK-LABEL: @doubleAddSub21248// CHECK-NEXT: return %arg01249func.func @doubleAddSub2(%arg0: index, %arg1 : index) -> index {1250 %sub = arith.subi %arg0, %arg1 : index1251 %add = arith.addi %arg1, %sub : index1252 return %add : index1253}1254 1255// Negative test case to ensure no further folding is performed when there's a type mismatch between the values and the result.1256// CHECK-LABEL: func.func @nested_muli() -> i32 {1257// CHECK: %[[VAL_0:.*]] = "test.constant"() <{value = 2147483647 : i64}> : () -> i321258// CHECK: %[[VAL_1:.*]] = "test.constant"() <{value = -2147483648 : i64}> : () -> i321259// CHECK: %[[VAL_2:.*]] = "test.constant"() <{value = 2147483648 : i64}> : () -> i321260// CHECK: %[[VAL_3:.*]] = arith.muli %[[VAL_0]], %[[VAL_1]] : i321261// CHECK: %[[VAL_4:.*]] = arith.muli %[[VAL_3]], %[[VAL_2]] : i321262// CHECK: return %[[VAL_4]] : i321263// CHECK: }1264func.func @nested_muli() -> (i32) {1265 %0 = "test.constant"() {value = 0x7fffffff} : () -> i321266 %1 = "test.constant"() {value = -2147483648} : () -> i321267 %2 = "test.constant"() {value = 0x80000000} : () -> i321268 %4 = arith.muli %0, %1 : i321269 %5 = arith.muli %4, %2 : i321270 return %5 : i321271}1272 1273// CHECK-LABEL: @tripleMulIMulIIndex1274// CHECK: %[[cres:.+]] = arith.constant 15 : index1275// CHECK: %[[muli:.+]] = arith.muli %arg0, %[[cres]] : index1276// CHECK: return %[[muli]]1277func.func @tripleMulIMulIIndex(%arg0: index) -> index {1278 %c3 = arith.constant 3 : index1279 %c5 = arith.constant 5 : index1280 %mul1 = arith.muli %arg0, %c3 : index1281 %mul2 = arith.muli %mul1, %c5 : index1282 return %mul2 : index1283}1284 1285// CHECK-LABEL: @tripleMulIMulII321286// CHECK: %[[cres:.+]] = arith.constant -21 : i321287// CHECK: %[[muli:.+]] = arith.muli %arg0, %[[cres]] : i321288// CHECK: return %[[muli]]1289func.func @tripleMulIMulII32(%arg0: i32) -> i32 {1290 %c_n3 = arith.constant -3 : i321291 %c7 = arith.constant 7 : i321292 %mul1 = arith.muli %arg0, %c_n3 : i321293 %mul2 = arith.muli %mul1, %c7 : i321294 return %mul2 : i321295}1296 1297// CHECK-LABEL: @tripleMulLargeInt1298// CHECK: %[[cres:.+]] = arith.constant 3618502788666131213697322783095070105623107215331596699973092056135872020482 : i2561299// CHECK: %[[addi:.+]] = arith.addi %arg0, %[[cres]] : i2561300// CHECK: return %[[addi]]1301func.func @tripleMulLargeInt(%arg0: i256) -> i256 {1302 %0 = arith.constant 3618502788666131213697322783095070105623107215331596699973092056135872020481 : i2561303 %1 = arith.constant 1 : i2561304 %2 = arith.addi %arg0, %0 : i2561305 %3 = arith.addi %2, %1 : i2561306 return %3 : i2561307}1308 1309// CHECK-LABEL: @addiMuliToSubiRhsI321310// CHECK-SAME: (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)1311// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : i321312// CHECK: return %[[SUB]]1313func.func @addiMuliToSubiRhsI32(%arg0: i32, %arg1: i32) -> i32 {1314 %c-1 = arith.constant -1 : i321315 %neg = arith.muli %arg1, %c-1 : i321316 %add = arith.addi %arg0, %neg : i321317 return %add : i321318}1319 1320// CHECK-LABEL: @addiMuliToSubiRhsIndex1321// CHECK-SAME: (%[[ARG0:.+]]: index, %[[ARG1:.+]]: index)1322// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : index1323// CHECK: return %[[SUB]]1324func.func @addiMuliToSubiRhsIndex(%arg0: index, %arg1: index) -> index {1325 %c-1 = arith.constant -1 : index1326 %neg = arith.muli %arg1, %c-1 : index1327 %add = arith.addi %arg0, %neg : index1328 return %add : index1329}1330 1331// CHECK-LABEL: @addiMuliToSubiRhsVector1332// CHECK-SAME: (%[[ARG0:.+]]: vector<3xi64>, %[[ARG1:.+]]: vector<3xi64>)1333// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : vector<3xi64>1334// CHECK: return %[[SUB]]1335func.func @addiMuliToSubiRhsVector(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi64> {1336 %c-1 = arith.constant dense<-1> : vector<3xi64>1337 %neg = arith.muli %arg1, %c-1 : vector<3xi64>1338 %add = arith.addi %arg0, %neg : vector<3xi64>1339 return %add : vector<3xi64>1340}1341 1342// CHECK-LABEL: @addiMuliToSubiLhsI321343// CHECK-SAME: (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32)1344// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : i321345// CHECK: return %[[SUB]]1346func.func @addiMuliToSubiLhsI32(%arg0: i32, %arg1: i32) -> i32 {1347 %c-1 = arith.constant -1 : i321348 %neg = arith.muli %arg1, %c-1 : i321349 %add = arith.addi %neg, %arg0 : i321350 return %add : i321351}1352 1353// CHECK-LABEL: @addiMuliToSubiLhsIndex1354// CHECK-SAME: (%[[ARG0:.+]]: index, %[[ARG1:.+]]: index)1355// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : index1356// CHECK: return %[[SUB]]1357func.func @addiMuliToSubiLhsIndex(%arg0: index, %arg1: index) -> index {1358 %c-1 = arith.constant -1 : index1359 %neg = arith.muli %arg1, %c-1 : index1360 %add = arith.addi %neg, %arg0 : index1361 return %add : index1362}1363 1364// CHECK-LABEL: @addiMuliToSubiLhsVector1365// CHECK-SAME: (%[[ARG0:.+]]: vector<3xi64>, %[[ARG1:.+]]: vector<3xi64>)1366// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : vector<3xi64>1367// CHECK: return %[[SUB]]1368func.func @addiMuliToSubiLhsVector(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi64> {1369 %c-1 = arith.constant dense<-1> : vector<3xi64>1370 %neg = arith.muli %arg1, %c-1 : vector<3xi64>1371 %add = arith.addi %neg, %arg0 : vector<3xi64>1372 return %add : vector<3xi64>1373}1374 1375// CHECK-LABEL: @adduiExtendedZeroRhs1376// CHECK-NEXT: %[[false:.+]] = arith.constant false1377// CHECK-NEXT: return %arg0, %[[false]]1378func.func @adduiExtendedZeroRhs(%arg0: i32) -> (i32, i1) {1379 %zero = arith.constant 0 : i321380 %sum, %overflow = arith.addui_extended %arg0, %zero: i32, i11381 return %sum, %overflow : i32, i11382}1383 1384// CHECK-LABEL: @adduiExtendedZeroRhsSplat1385// CHECK-NEXT: %[[false:.+]] = arith.constant dense<false> : vector<4xi1>1386// CHECK-NEXT: return %arg0, %[[false]]1387func.func @adduiExtendedZeroRhsSplat(%arg0: vector<4xi32>) -> (vector<4xi32>, vector<4xi1>) {1388 %zero = arith.constant dense<0> : vector<4xi32>1389 %sum, %overflow = arith.addui_extended %arg0, %zero: vector<4xi32>, vector<4xi1>1390 return %sum, %overflow : vector<4xi32>, vector<4xi1>1391}1392 1393// CHECK-LABEL: @adduiExtendedZeroLhs1394// CHECK-NEXT: %[[false:.+]] = arith.constant false1395// CHECK-NEXT: return %arg0, %[[false]]1396func.func @adduiExtendedZeroLhs(%arg0: i32) -> (i32, i1) {1397 %zero = arith.constant 0 : i321398 %sum, %overflow = arith.addui_extended %zero, %arg0: i32, i11399 return %sum, %overflow : i32, i11400}1401 1402// CHECK-LABEL: @adduiExtendedUnusedOverflowScalar1403// CHECK-SAME: (%[[LHS:.+]]: i32, %[[RHS:.+]]: i32) -> i321404// CHECK-NEXT: %[[RES:.+]] = arith.addi %[[LHS]], %[[RHS]] : i321405// CHECK-NEXT: return %[[RES]] : i321406func.func @adduiExtendedUnusedOverflowScalar(%arg0: i32, %arg1: i32) -> i32 {1407 %sum, %overflow = arith.addui_extended %arg0, %arg1: i32, i11408 return %sum : i321409}1410 1411// CHECK-LABEL: @adduiExtendedUnusedOverflowVector1412// CHECK-SAME: (%[[LHS:.+]]: vector<3xi32>, %[[RHS:.+]]: vector<3xi32>) -> vector<3xi32>1413// CHECK-NEXT: %[[RES:.+]] = arith.addi %[[LHS]], %[[RHS]] : vector<3xi32>1414// CHECK-NEXT: return %[[RES]] : vector<3xi32>1415func.func @adduiExtendedUnusedOverflowVector(%arg0: vector<3xi32>, %arg1: vector<3xi32>) -> vector<3xi32> {1416 %sum, %overflow = arith.addui_extended %arg0, %arg1: vector<3xi32>, vector<3xi1>1417 return %sum : vector<3xi32>1418}1419 1420// CHECK-LABEL: @adduiExtendedConstants1421// CHECK-DAG: %[[false:.+]] = arith.constant false1422// CHECK-DAG: %[[c50:.+]] = arith.constant 50 : i321423// CHECK-NEXT: return %[[c50]], %[[false]]1424func.func @adduiExtendedConstants() -> (i32, i1) {1425 %c13 = arith.constant 13 : i321426 %c37 = arith.constant 37 : i321427 %sum, %overflow = arith.addui_extended %c13, %c37: i32, i11428 return %sum, %overflow : i32, i11429}1430 1431// CHECK-LABEL: @adduiExtendedConstantsOverflow11432// CHECK-DAG: %[[true:.+]] = arith.constant true1433// CHECK-DAG: %[[c0:.+]] = arith.constant 0 : i321434// CHECK-NEXT: return %[[c0]], %[[true]]1435func.func @adduiExtendedConstantsOverflow1() -> (i32, i1) {1436 %max = arith.constant 4294967295 : i321437 %c1 = arith.constant 1 : i321438 %sum, %overflow = arith.addui_extended %max, %c1: i32, i11439 return %sum, %overflow : i32, i11440}1441 1442// CHECK-LABEL: @adduiExtendedConstantsOverflow21443// CHECK-DAG: %[[true:.+]] = arith.constant true1444// CHECK-DAG: %[[c_2:.+]] = arith.constant -2 : i321445// CHECK-NEXT: return %[[c_2]], %[[true]]1446func.func @adduiExtendedConstantsOverflow2() -> (i32, i1) {1447 %max = arith.constant 4294967295 : i321448 %sum, %overflow = arith.addui_extended %max, %max: i32, i11449 return %sum, %overflow : i32, i11450}1451 1452// CHECK-LABEL: @adduiExtendedConstantsOverflowVector1453// CHECK-DAG: %[[sum:.+]] = arith.constant dense<[1, 6, 2, 14]> : vector<4xi32>1454// CHECK-DAG: %[[overflow:.+]] = arith.constant dense<[false, false, true, false]> : vector<4xi1>1455// CHECK-NEXT: return %[[sum]], %[[overflow]]1456func.func @adduiExtendedConstantsOverflowVector() -> (vector<4xi32>, vector<4xi1>) {1457 %v1 = arith.constant dense<[1, 3, 3, 7]> : vector<4xi32>1458 %v2 = arith.constant dense<[0, 3, 4294967295, 7]> : vector<4xi32>1459 %sum, %overflow = arith.addui_extended %v1, %v2 : vector<4xi32>, vector<4xi1>1460 return %sum, %overflow : vector<4xi32>, vector<4xi1>1461}1462 1463// CHECK-LABEL: @adduiExtendedConstantsSplatVector1464// CHECK-DAG: %[[sum:.+]] = arith.constant dense<3> : vector<4xi32>1465// CHECK-DAG: %[[overflow:.+]] = arith.constant dense<false> : vector<4xi1>1466// CHECK-NEXT: return %[[sum]], %[[overflow]]1467func.func @adduiExtendedConstantsSplatVector() -> (vector<4xi32>, vector<4xi1>) {1468 %v1 = arith.constant dense<1> : vector<4xi32>1469 %v2 = arith.constant dense<2> : vector<4xi32>1470 %sum, %overflow = arith.addui_extended %v1, %v2 : vector<4xi32>, vector<4xi1>1471 return %sum, %overflow : vector<4xi32>, vector<4xi1>1472}1473 1474// CHECK-LABEL: @mulsiExtendedZeroRhs1475// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i321476// CHECK-NEXT: return %[[zero]], %[[zero]]1477func.func @mulsiExtendedZeroRhs(%arg0: i32) -> (i32, i32) {1478 %zero = arith.constant 0 : i321479 %low, %high = arith.mulsi_extended %arg0, %zero: i321480 return %low, %high : i32, i321481}1482 1483// CHECK-LABEL: @mulsiExtendedZeroRhsSplat1484// CHECK-NEXT: %[[zero:.+]] = arith.constant dense<0> : vector<3xi32>1485// CHECK-NEXT: return %[[zero]], %[[zero]]1486func.func @mulsiExtendedZeroRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {1487 %zero = arith.constant dense<0> : vector<3xi32>1488 %low, %high = arith.mulsi_extended %arg0, %zero: vector<3xi32>1489 return %low, %high : vector<3xi32>, vector<3xi32>1490}1491 1492// CHECK-LABEL: @mulsiExtendedZeroLhs1493// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i321494// CHECK-NEXT: return %[[zero]], %[[zero]]1495func.func @mulsiExtendedZeroLhs(%arg0: i32) -> (i32, i32) {1496 %zero = arith.constant 0 : i321497 %low, %high = arith.mulsi_extended %zero, %arg0: i321498 return %low, %high : i32, i321499}1500 1501// CHECK-LABEL: @mulsiExtendedOneRhs1502// CHECK-SAME: (%[[ARG:.+]]: i32) -> (i32, i32)1503// CHECK-NEXT: %[[C0:.+]] = arith.constant 0 : i321504// CHECK-NEXT: %[[CMP:.+]] = arith.cmpi slt, %[[ARG]], %[[C0]] : i321505// CHECK-NEXT: %[[EXT:.+]] = arith.extsi %[[CMP]] : i1 to i321506// CHECK-NEXT: return %[[ARG]], %[[EXT]] : i32, i321507func.func @mulsiExtendedOneRhs(%arg0: i32) -> (i32, i32) {1508 %one = arith.constant 1 : i321509 %low, %high = arith.mulsi_extended %arg0, %one: i321510 return %low, %high : i32, i321511}1512 1513// CHECK-LABEL: @mulsiExtendedOneRhsSplat1514// CHECK-SAME: (%[[ARG:.+]]: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>)1515// CHECK-NEXT: %[[C0:.+]] = arith.constant dense<0> : vector<3xi32>1516// CHECK-NEXT: %[[CMP:.+]] = arith.cmpi slt, %[[ARG]], %[[C0]] : vector<3xi32>1517// CHECK-NEXT: %[[EXT:.+]] = arith.extsi %[[CMP]] : vector<3xi1> to vector<3xi32>1518// CHECK-NEXT: return %[[ARG]], %[[EXT]] : vector<3xi32>, vector<3xi32>1519func.func @mulsiExtendedOneRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {1520 %one = arith.constant dense<1> : vector<3xi32>1521 %low, %high = arith.mulsi_extended %arg0, %one: vector<3xi32>1522 return %low, %high : vector<3xi32>, vector<3xi32>1523}1524 1525// CHECK-LABEL: @mulsiExtendedOneRhsI11526// CHECK-SAME: (%[[ARG:.+]]: i1) -> (i1, i1)1527// CHECK-NEXT: %[[T:.+]] = arith.constant true1528// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[ARG]], %[[T]] : i11529// CHECK-NEXT: return %[[LOW]], %[[HIGH]] : i1, i11530func.func @mulsiExtendedOneRhsI1(%arg0: i1) -> (i1, i1) {1531 %one = arith.constant true1532 %low, %high = arith.mulsi_extended %arg0, %one: i11533 return %low, %high : i1, i11534}1535 1536// CHECK-LABEL: @mulsiExtendedOneRhsSplatI11537// CHECK-SAME: (%[[ARG:.+]]: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>)1538// CHECK-NEXT: %[[TS:.+]] = arith.constant dense<true> : vector<3xi1>1539// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[ARG]], %[[TS]] : vector<3xi1>1540// CHECK-NEXT: return %[[LOW]], %[[HIGH]] : vector<3xi1>, vector<3xi1>1541func.func @mulsiExtendedOneRhsSplatI1(%arg0: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>) {1542 %one = arith.constant dense<true> : vector<3xi1>1543 %low, %high = arith.mulsi_extended %arg0, %one: vector<3xi1>1544 return %low, %high : vector<3xi1>, vector<3xi1>1545}1546 1547// CHECK-LABEL: @mulsiExtendedUnusedHigh1548// CHECK-SAME: (%[[ARG:.+]]: i32) -> i321549// CHECK-NEXT: %[[RES:.+]] = arith.muli %[[ARG]], %[[ARG]] : i321550// CHECK-NEXT: return %[[RES]]1551func.func @mulsiExtendedUnusedHigh(%arg0: i32) -> i32 {1552 %low, %high = arith.mulsi_extended %arg0, %arg0: i321553 return %low : i321554}1555 1556// CHECK-LABEL: @mulsiExtendedScalarConstants1557// CHECK-DAG: %[[c27:.+]] = arith.constant 27 : i81558// CHECK-DAG: %[[c_n3:.+]] = arith.constant -3 : i81559// CHECK-NEXT: return %[[c27]], %[[c_n3]]1560func.func @mulsiExtendedScalarConstants() -> (i8, i8) {1561 %c57 = arith.constant 57 : i81562 %c_n13 = arith.constant -13 : i81563 %low, %high = arith.mulsi_extended %c57, %c_n13: i81564 return %low, %high : i8, i81565}1566 1567// CHECK-LABEL: @mulsiExtendedVectorConstants1568// CHECK-DAG: %[[cstLo:.+]] = arith.constant dense<[65, 79, 34]> : vector<3xi8>1569// CHECK-DAG: %[[cstHi:.+]] = arith.constant dense<[0, 14, 0]> : vector<3xi8>1570// CHECK-NEXT: return %[[cstLo]], %[[cstHi]]1571func.func @mulsiExtendedVectorConstants() -> (vector<3xi8>, vector<3xi8>) {1572 %cstA = arith.constant dense<[5, 37, -17]> : vector<3xi8>1573 %cstB = arith.constant dense<[13, 99, -2]> : vector<3xi8>1574 %low, %high = arith.mulsi_extended %cstA, %cstB: vector<3xi8>1575 return %low, %high : vector<3xi8>, vector<3xi8>1576}1577 1578// CHECK-LABEL: @muluiExtendedZeroRhs1579// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i321580// CHECK-NEXT: return %[[zero]], %[[zero]]1581func.func @muluiExtendedZeroRhs(%arg0: i32) -> (i32, i32) {1582 %zero = arith.constant 0 : i321583 %low, %high = arith.mului_extended %arg0, %zero: i321584 return %low, %high : i32, i321585}1586 1587// CHECK-LABEL: @muluiExtendedZeroRhsSplat1588// CHECK-NEXT: %[[zero:.+]] = arith.constant dense<0> : vector<3xi32>1589// CHECK-NEXT: return %[[zero]], %[[zero]]1590func.func @muluiExtendedZeroRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {1591 %zero = arith.constant dense<0> : vector<3xi32>1592 %low, %high = arith.mului_extended %arg0, %zero: vector<3xi32>1593 return %low, %high : vector<3xi32>, vector<3xi32>1594}1595 1596// CHECK-LABEL: @muluiExtendedZeroLhs1597// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i321598// CHECK-NEXT: return %[[zero]], %[[zero]]1599func.func @muluiExtendedZeroLhs(%arg0: i32) -> (i32, i32) {1600 %zero = arith.constant 0 : i321601 %low, %high = arith.mului_extended %zero, %arg0: i321602 return %low, %high : i32, i321603}1604 1605// CHECK-LABEL: @muluiExtendedOneRhs1606// CHECK-SAME: (%[[ARG:.+]]: i32) -> (i32, i32)1607// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i321608// CHECK-NEXT: return %[[ARG]], %[[zero]]1609func.func @muluiExtendedOneRhs(%arg0: i32) -> (i32, i32) {1610 %zero = arith.constant 1 : i321611 %low, %high = arith.mului_extended %arg0, %zero: i321612 return %low, %high : i32, i321613}1614 1615// CHECK-LABEL: @muluiExtendedOneRhsSplat1616// CHECK-SAME: (%[[ARG:.+]]: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>)1617// CHECK-NEXT: %[[zero:.+]] = arith.constant dense<0> : vector<3xi32>1618// CHECK-NEXT: return %[[ARG]], %[[zero]]1619func.func @muluiExtendedOneRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {1620 %zero = arith.constant dense<1> : vector<3xi32>1621 %low, %high = arith.mului_extended %arg0, %zero: vector<3xi32>1622 return %low, %high : vector<3xi32>, vector<3xi32>1623}1624 1625// CHECK-LABEL: @muluiExtendedOneLhs1626// CHECK-SAME: (%[[ARG:.+]]: i32) -> (i32, i32)1627// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i321628// CHECK-NEXT: return %[[ARG]], %[[zero]]1629func.func @muluiExtendedOneLhs(%arg0: i32) -> (i32, i32) {1630 %zero = arith.constant 1 : i321631 %low, %high = arith.mului_extended %zero, %arg0: i321632 return %low, %high : i32, i321633}1634 1635// CHECK-LABEL: @muluiExtendedUnusedHigh1636// CHECK-SAME: (%[[ARG:.+]]: i32) -> i321637// CHECK-NEXT: %[[RES:.+]] = arith.muli %[[ARG]], %[[ARG]] : i321638// CHECK-NEXT: return %[[RES]]1639func.func @muluiExtendedUnusedHigh(%arg0: i32) -> i32 {1640 %low, %high = arith.mului_extended %arg0, %arg0: i321641 return %low : i321642}1643 1644// This shouldn't be folded.1645// CHECK-LABEL: @muluiExtendedUnusedLow1646// CHECK-SAME: (%[[ARG:.+]]: i32) -> i321647// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mului_extended %[[ARG]], %[[ARG]] : i321648// CHECK-NEXT: return %[[HIGH]]1649func.func @muluiExtendedUnusedLow(%arg0: i32) -> i32 {1650 %low, %high = arith.mului_extended %arg0, %arg0: i321651 return %high : i321652}1653 1654// CHECK-LABEL: @muluiExtendedScalarConstants1655// CHECK-DAG: %[[c157:.+]] = arith.constant -99 : i81656// CHECK-DAG: %[[c29:.+]] = arith.constant 29 : i81657// CHECK-NEXT: return %[[c157]], %[[c29]]1658func.func @muluiExtendedScalarConstants() -> (i8, i8) {1659 %c57 = arith.constant 57 : i81660 %c133 = arith.constant 133 : i81661 %low, %high = arith.mului_extended %c57, %c133: i8 // = 75811662 return %low, %high : i8, i81663}1664 1665// CHECK-LABEL: @muluiExtendedVectorConstants1666// CHECK-DAG: %[[cstLo:.+]] = arith.constant dense<[65, 79, 1]> : vector<3xi8>1667// CHECK-DAG: %[[cstHi:.+]] = arith.constant dense<[0, 14, -2]> : vector<3xi8>1668// CHECK-NEXT: return %[[cstLo]], %[[cstHi]]1669func.func @muluiExtendedVectorConstants() -> (vector<3xi8>, vector<3xi8>) {1670 %cstA = arith.constant dense<[5, 37, 255]> : vector<3xi8>1671 %cstB = arith.constant dense<[13, 99, 255]> : vector<3xi8>1672 %low, %high = arith.mului_extended %cstA, %cstB: vector<3xi8>1673 return %low, %high : vector<3xi8>, vector<3xi8>1674}1675 1676// CHECK-LABEL: @notCmpEQ1677// CHECK: %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i81678// CHECK: return %[[cres]]1679func.func @notCmpEQ(%arg0: i8, %arg1: i8) -> i1 {1680 %true = arith.constant true1681 %cmp = arith.cmpi "eq", %arg0, %arg1 : i81682 %ncmp = arith.xori %cmp, %true : i11683 return %ncmp : i11684}1685 1686// CHECK-LABEL: @notCmpEQ21687// CHECK: %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i81688// CHECK: return %[[cres]]1689func.func @notCmpEQ2(%arg0: i8, %arg1: i8) -> i1 {1690 %true = arith.constant true1691 %cmp = arith.cmpi "eq", %arg0, %arg1 : i81692 %ncmp = arith.xori %true, %cmp : i11693 return %ncmp : i11694}1695 1696// CHECK-LABEL: @notCmpNE1697// CHECK: %[[cres:.+]] = arith.cmpi eq, %arg0, %arg1 : i81698// CHECK: return %[[cres]]1699func.func @notCmpNE(%arg0: i8, %arg1: i8) -> i1 {1700 %true = arith.constant true1701 %cmp = arith.cmpi "ne", %arg0, %arg1 : i81702 %ncmp = arith.xori %cmp, %true : i11703 return %ncmp : i11704}1705 1706// CHECK-LABEL: @notCmpSLT1707// CHECK: %[[cres:.+]] = arith.cmpi sge, %arg0, %arg1 : i81708// CHECK: return %[[cres]]1709func.func @notCmpSLT(%arg0: i8, %arg1: i8) -> i1 {1710 %true = arith.constant true1711 %cmp = arith.cmpi "slt", %arg0, %arg1 : i81712 %ncmp = arith.xori %cmp, %true : i11713 return %ncmp : i11714}1715 1716// CHECK-LABEL: @notCmpSLE1717// CHECK: %[[cres:.+]] = arith.cmpi sgt, %arg0, %arg1 : i81718// CHECK: return %[[cres]]1719func.func @notCmpSLE(%arg0: i8, %arg1: i8) -> i1 {1720 %true = arith.constant true1721 %cmp = arith.cmpi "sle", %arg0, %arg1 : i81722 %ncmp = arith.xori %cmp, %true : i11723 return %ncmp : i11724}1725 1726// CHECK-LABEL: @notCmpSGT1727// CHECK: %[[cres:.+]] = arith.cmpi sle, %arg0, %arg1 : i81728// CHECK: return %[[cres]]1729func.func @notCmpSGT(%arg0: i8, %arg1: i8) -> i1 {1730 %true = arith.constant true1731 %cmp = arith.cmpi "sgt", %arg0, %arg1 : i81732 %ncmp = arith.xori %cmp, %true : i11733 return %ncmp : i11734}1735 1736// CHECK-LABEL: @notCmpSGE1737// CHECK: %[[cres:.+]] = arith.cmpi slt, %arg0, %arg1 : i81738// CHECK: return %[[cres]]1739func.func @notCmpSGE(%arg0: i8, %arg1: i8) -> i1 {1740 %true = arith.constant true1741 %cmp = arith.cmpi "sge", %arg0, %arg1 : i81742 %ncmp = arith.xori %cmp, %true : i11743 return %ncmp : i11744}1745 1746// CHECK-LABEL: @notCmpULT1747// CHECK: %[[cres:.+]] = arith.cmpi uge, %arg0, %arg1 : i81748// CHECK: return %[[cres]]1749func.func @notCmpULT(%arg0: i8, %arg1: i8) -> i1 {1750 %true = arith.constant true1751 %cmp = arith.cmpi "ult", %arg0, %arg1 : i81752 %ncmp = arith.xori %cmp, %true : i11753 return %ncmp : i11754}1755 1756// CHECK-LABEL: @notCmpULE1757// CHECK: %[[cres:.+]] = arith.cmpi ugt, %arg0, %arg1 : i81758// CHECK: return %[[cres]]1759func.func @notCmpULE(%arg0: i8, %arg1: i8) -> i1 {1760 %true = arith.constant true1761 %cmp = arith.cmpi "ule", %arg0, %arg1 : i81762 %ncmp = arith.xori %cmp, %true : i11763 return %ncmp : i11764}1765 1766// CHECK-LABEL: @notCmpUGT1767// CHECK: %[[cres:.+]] = arith.cmpi ule, %arg0, %arg1 : i81768// CHECK: return %[[cres]]1769func.func @notCmpUGT(%arg0: i8, %arg1: i8) -> i1 {1770 %true = arith.constant true1771 %cmp = arith.cmpi "ugt", %arg0, %arg1 : i81772 %ncmp = arith.xori %cmp, %true : i11773 return %ncmp : i11774}1775 1776// CHECK-LABEL: @notCmpUGE1777// CHECK: %[[cres:.+]] = arith.cmpi ult, %arg0, %arg1 : i81778// CHECK: return %[[cres]]1779func.func @notCmpUGE(%arg0: i8, %arg1: i8) -> i1 {1780 %true = arith.constant true1781 %cmp = arith.cmpi "uge", %arg0, %arg1 : i81782 %ncmp = arith.xori %cmp, %true : i11783 return %ncmp : i11784}1785 1786// -----1787 1788// CHECK-LABEL: @xorxor(1789// CHECK-NOT: xori1790// CHECK: return %arg01791func.func @xorxor(%cmp : i1) -> i1 {1792 %true = arith.constant true1793 %ncmp = arith.xori %cmp, %true : i11794 %nncmp = arith.xori %ncmp, %true : i11795 return %nncmp : i11796}1797 1798// CHECK-LABEL: @xorOfExtSI1799// CHECK: %[[comb:.+]] = arith.xori %arg0, %arg1 : i81800// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i641801// CHECK: return %[[ext]]1802func.func @xorOfExtSI(%arg0: i8, %arg1: i8) -> i64 {1803 %ext0 = arith.extsi %arg0 : i8 to i641804 %ext1 = arith.extsi %arg1 : i8 to i641805 %res = arith.xori %ext0, %ext1 : i641806 return %res : i641807}1808 1809// CHECK-LABEL: @xorOfExtUI1810// CHECK: %[[comb:.+]] = arith.xori %arg0, %arg1 : i81811// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i641812// CHECK: return %[[ext]]1813func.func @xorOfExtUI(%arg0: i8, %arg1: i8) -> i64 {1814 %ext0 = arith.extui %arg0 : i8 to i641815 %ext1 = arith.extui %arg1 : i8 to i641816 %res = arith.xori %ext0, %ext1 : i641817 return %res : i641818}1819 1820// -----1821 1822// CHECK-LABEL: @bitcastSameType(1823// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]1824func.func @bitcastSameType(%arg : f32) -> f32 {1825 // CHECK: return %[[ARG]]1826 %res = arith.bitcast %arg : f32 to f321827 return %res : f321828}1829 1830// -----1831 1832// CHECK-LABEL: @bitcastConstantFPtoI(1833func.func @bitcastConstantFPtoI() -> i32 {1834 // CHECK: %[[C0:.+]] = arith.constant 0 : i321835 // CHECK: return %[[C0]]1836 %c0 = arith.constant 0.0 : f321837 %res = arith.bitcast %c0 : f32 to i321838 return %res : i321839}1840 1841// -----1842 1843// CHECK-LABEL: @bitcastConstantItoFP(1844func.func @bitcastConstantItoFP() -> f32 {1845 // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f321846 // CHECK: return %[[C0]]1847 %c0 = arith.constant 0 : i321848 %res = arith.bitcast %c0 : i32 to f321849 return %res : f321850}1851 1852// -----1853 1854// CHECK-LABEL: @bitcastConstantFPtoFP(1855func.func @bitcastConstantFPtoFP() -> f16 {1856 // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f161857 // CHECK: return %[[C0]]1858 %c0 = arith.constant 0.0 : bf161859 %res = arith.bitcast %c0 : bf16 to f161860 return %res : f161861}1862 1863// -----1864 1865// CHECK-LABEL: @bitcastConstantVecFPtoI(1866func.func @bitcastConstantVecFPtoI() -> vector<3xf32> {1867 // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xf32>1868 // CHECK: return %[[C0]]1869 %c0 = arith.constant dense<0> : vector<3xi32>1870 %res = arith.bitcast %c0 : vector<3xi32> to vector<3xf32>1871 return %res : vector<3xf32>1872}1873 1874// -----1875 1876// CHECK-LABEL: @bitcastConstantVecItoFP(1877func.func @bitcastConstantVecItoFP() -> vector<3xi32> {1878 // CHECK: %[[C0:.+]] = arith.constant dense<0> : vector<3xi32>1879 // CHECK: return %[[C0]]1880 %c0 = arith.constant dense<0.0> : vector<3xf32>1881 %res = arith.bitcast %c0 : vector<3xf32> to vector<3xi32>1882 return %res : vector<3xi32>1883}1884 1885// -----1886 1887// CHECK-LABEL: @bitcastConstantVecFPtoFP(1888func.func @bitcastConstantVecFPtoFP() -> vector<3xbf16> {1889 // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xbf16>1890 // CHECK: return %[[C0]]1891 %c0 = arith.constant dense<0.0> : vector<3xf16>1892 %res = arith.bitcast %c0 : vector<3xf16> to vector<3xbf16>1893 return %res : vector<3xbf16>1894}1895 1896// -----1897 1898// CHECK-LABEL: @bitcastBackAndForth(1899// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]1900func.func @bitcastBackAndForth(%arg : i32) -> i32 {1901 // CHECK: return %[[ARG]]1902 %f = arith.bitcast %arg : i32 to f321903 %res = arith.bitcast %f : f32 to i321904 return %res : i321905}1906 1907// -----1908 1909// CHECK-LABEL: @bitcastOfBitcast(1910// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]]1911func.func @bitcastOfBitcast(%arg : i16) -> i16 {1912 // CHECK: return %[[ARG]]1913 %f = arith.bitcast %arg : i16 to f161914 %bf = arith.bitcast %f : f16 to bf161915 %res = arith.bitcast %bf : bf16 to i161916 return %res : i161917}1918 1919// -----1920 1921// CHECK-LABEL: @bitcastPoisonItoFP(1922func.func @bitcastPoisonItoFP() -> f32 {1923 // CHECK: %[[P:.+]] = ub.poison : f321924 // CHECK: return %[[P]] : f321925 %p = ub.poison : i321926 %res = arith.bitcast %p : i32 to f321927 return %res : f321928}1929 1930// -----1931 1932// CHECK-LABEL: @bitcastPoisonFPtoI(1933func.func @bitcastPoisonFPtoI() -> i32 {1934 // CHECK: %[[P:.+]] = ub.poison : i321935 // CHECK: return %[[P]] : i321936 %p = ub.poison : f321937 %res = arith.bitcast %p : f32 to i321938 return %res : i321939}1940 1941// -----1942 1943// CHECK-LABEL: func @bitcastChain(1944// CHECK-SAME: %[[arg:.*]]: i16)1945// CHECK: %[[cast:.*]] = arith.bitcast %[[arg]] : i16 to f161946// CHECK: return %[[cast]]1947func.func @bitcastChain(%arg: i16) -> f16 {1948 %0 = arith.bitcast %arg : i16 to bf161949 %1 = arith.bitcast %0 : bf16 to f161950 return %1 : f161951}1952 1953// -----1954 1955// CHECK-LABEL: test_maxsi1956// CHECK-DAG: %[[C0:.+]] = arith.constant 421957// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant 1271958// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]]1959// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]1960func.func @test_maxsi(%arg0 : i8) -> (i8, i8, i8, i8) {1961 %maxIntCst = arith.constant 127 : i81962 %minIntCst = arith.constant -128 : i81963 %c0 = arith.constant 42 : i81964 %0 = arith.maxsi %arg0, %arg0 : i81965 %1 = arith.maxsi %arg0, %maxIntCst : i81966 %2 = arith.maxsi %arg0, %minIntCst : i81967 %3 = arith.maxsi %arg0, %c0 : i81968 return %0, %1, %2, %3: i8, i8, i8, i81969}1970 1971// CHECK-LABEL: test_maxsi21972// CHECK-DAG: %[[C0:.+]] = arith.constant 421973// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant 1271974// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]]1975// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]1976func.func @test_maxsi2(%arg0 : i8) -> (i8, i8, i8, i8) {1977 %maxIntCst = arith.constant 127 : i81978 %minIntCst = arith.constant -128 : i81979 %c0 = arith.constant 42 : i81980 %0 = arith.maxsi %arg0, %arg0 : i81981 %1 = arith.maxsi %maxIntCst, %arg0: i81982 %2 = arith.maxsi %minIntCst, %arg0: i81983 %3 = arith.maxsi %c0, %arg0 : i81984 return %0, %1, %2, %3: i8, i8, i8, i81985}1986 1987// -----1988 1989// CHECK-LABEL: test_maxui1990// CHECK-DAG: %[[C0:.+]] = arith.constant 421991// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant -11992// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]]1993// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]1994func.func @test_maxui(%arg0 : i8) -> (i8, i8, i8, i8) {1995 %maxIntCst = arith.constant 255 : i81996 %minIntCst = arith.constant 0 : i81997 %c0 = arith.constant 42 : i81998 %0 = arith.maxui %arg0, %arg0 : i81999 %1 = arith.maxui %arg0, %maxIntCst : i82000 %2 = arith.maxui %arg0, %minIntCst : i82001 %3 = arith.maxui %arg0, %c0 : i82002 return %0, %1, %2, %3: i8, i8, i8, i82003}2004 2005// CHECK-LABEL: test_maxui2006// CHECK-DAG: %[[C0:.+]] = arith.constant 422007// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant -12008// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]]2009// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]]2010func.func @test_maxui2(%arg0 : i8) -> (i8, i8, i8, i8) {2011 %maxIntCst = arith.constant 255 : i82012 %minIntCst = arith.constant 0 : i82013 %c0 = arith.constant 42 : i82014 %0 = arith.maxui %arg0, %arg0 : i82015 %1 = arith.maxui %maxIntCst, %arg0 : i82016 %2 = arith.maxui %minIntCst, %arg0 : i82017 %3 = arith.maxui %c0, %arg0 : i82018 return %0, %1, %2, %3: i8, i8, i8, i82019}2020 2021// -----2022 2023// CHECK-LABEL: test_minsi2024// CHECK-DAG: %[[C0:.+]] = arith.constant 422025// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant -1282026// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]]2027// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]2028func.func @test_minsi(%arg0 : i8) -> (i8, i8, i8, i8) {2029 %maxIntCst = arith.constant 127 : i82030 %minIntCst = arith.constant -128 : i82031 %c0 = arith.constant 42 : i82032 %0 = arith.minsi %arg0, %arg0 : i82033 %1 = arith.minsi %arg0, %maxIntCst : i82034 %2 = arith.minsi %arg0, %minIntCst : i82035 %3 = arith.minsi %arg0, %c0 : i82036 return %0, %1, %2, %3: i8, i8, i8, i82037}2038 2039// CHECK-LABEL: test_minsi2040// CHECK-DAG: %[[C0:.+]] = arith.constant 422041// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant -1282042// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]]2043// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]2044func.func @test_minsi2(%arg0 : i8) -> (i8, i8, i8, i8) {2045 %maxIntCst = arith.constant 127 : i82046 %minIntCst = arith.constant -128 : i82047 %c0 = arith.constant 42 : i82048 %0 = arith.minsi %arg0, %arg0 : i82049 %1 = arith.minsi %maxIntCst, %arg0 : i82050 %2 = arith.minsi %minIntCst, %arg0 : i82051 %3 = arith.minsi %c0, %arg0 : i82052 return %0, %1, %2, %3: i8, i8, i8, i82053}2054 2055// -----2056 2057// CHECK-LABEL: test_minui2058// CHECK-DAG: %[[C0:.+]] = arith.constant 422059// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant 02060// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]]2061// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]2062func.func @test_minui(%arg0 : i8) -> (i8, i8, i8, i8) {2063 %maxIntCst = arith.constant 255 : i82064 %minIntCst = arith.constant 0 : i82065 %c0 = arith.constant 42 : i82066 %0 = arith.minui %arg0, %arg0 : i82067 %1 = arith.minui %arg0, %maxIntCst : i82068 %2 = arith.minui %arg0, %minIntCst : i82069 %3 = arith.minui %arg0, %c0 : i82070 return %0, %1, %2, %3: i8, i8, i8, i82071}2072 2073// CHECK-LABEL: test_minui2074// CHECK-DAG: %[[C0:.+]] = arith.constant 422075// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant 02076// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]]2077// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]]2078func.func @test_minui2(%arg0 : i8) -> (i8, i8, i8, i8) {2079 %maxIntCst = arith.constant 255 : i82080 %minIntCst = arith.constant 0 : i82081 %c0 = arith.constant 42 : i82082 %0 = arith.minui %arg0, %arg0 : i82083 %1 = arith.minui %maxIntCst, %arg0 : i82084 %2 = arith.minui %minIntCst, %arg0 : i82085 %3 = arith.minui %c0, %arg0 : i82086 return %0, %1, %2, %3: i8, i8, i8, i82087}2088 2089// -----2090 2091// CHECK-LABEL: @test_minimumf(2092func.func @test_minimumf(%arg0 : f32) -> (f32, f32, f32) {2093 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.02094 // CHECK-NEXT: %[[X:.+]] = arith.minimumf %arg0, %[[C0]]2095 // CHECK-NEXT: return %[[X]], %arg0, %arg02096 %c0 = arith.constant 0.0 : f322097 %inf = arith.constant 0x7F800000 : f322098 %0 = arith.minimumf %c0, %arg0 : f322099 %1 = arith.minimumf %arg0, %arg0 : f322100 %2 = arith.minimumf %inf, %arg0 : f322101 return %0, %1, %2 : f32, f32, f322102}2103 2104// -----2105 2106// CHECK-LABEL: @test_maximumf(2107func.func @test_maximumf(%arg0 : f32) -> (f32, f32, f32) {2108 // CHECK-DAG: %[[C0:.+]] = arith.constant2109 // CHECK-NEXT: %[[X:.+]] = arith.maximumf %arg0, %[[C0]]2110 // CHECK-NEXT: return %[[X]], %arg0, %arg02111 %c0 = arith.constant 0.0 : f322112 %-inf = arith.constant 0xFF800000 : f322113 %0 = arith.maximumf %c0, %arg0 : f322114 %1 = arith.maximumf %arg0, %arg0 : f322115 %2 = arith.maximumf %-inf, %arg0 : f322116 return %0, %1, %2 : f32, f32, f322117}2118 2119// -----2120 2121// CHECK-LABEL: @test_minnumf(2122func.func @test_minnumf(%arg0 : f32) -> (f32, f32, f32, f32) {2123 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.02124 // CHECK-DAG: %[[INF:.+]] = arith.constant2125 // CHECK-NEXT: %[[X:.+]] = arith.minnumf %arg0, %[[C0]]2126 // CHECK-NEXT: %[[Y:.+]] = arith.minnumf %arg0, %[[INF]]2127 // CHECK-NEXT: return %[[X]], %arg0, %[[Y]], %arg02128 %c0 = arith.constant 0.0 : f322129 %inf = arith.constant 0x7F800000 : f322130 %nan = arith.constant 0x7FC00000 : f322131 %0 = arith.minnumf %c0, %arg0 : f322132 %1 = arith.minnumf %arg0, %arg0 : f322133 %2 = arith.minnumf %inf, %arg0 : f322134 %3 = arith.minnumf %nan, %arg0 : f322135 return %0, %1, %2, %3 : f32, f32, f32, f322136}2137 2138// -----2139 2140// CHECK-LABEL: @test_maxnumf(2141func.func @test_maxnumf(%arg0 : f32) -> (f32, f32, f32, f32) {2142 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.02143 // CHECK-DAG: %[[NINF:.+]] = arith.constant2144 // CHECK-NEXT: %[[X:.+]] = arith.maxnumf %arg0, %[[C0]]2145 // CHECK-NEXT: %[[Y:.+]] = arith.maxnumf %arg0, %[[NINF]]2146 // CHECK-NEXT: return %[[X]], %arg0, %[[Y]], %arg02147 %c0 = arith.constant 0.0 : f322148 %-inf = arith.constant 0xFF800000 : f322149 %nan = arith.constant 0x7FC00000 : f322150 %0 = arith.maxnumf %c0, %arg0 : f322151 %1 = arith.maxnumf %arg0, %arg0 : f322152 %2 = arith.maxnumf %-inf, %arg0 : f322153 %3 = arith.maxnumf %nan, %arg0 : f322154 return %0, %1, %2, %3 : f32, f32, f32, f322155}2156 2157// -----2158 2159// CHECK-LABEL: @test_addf(2160func.func @test_addf(%arg0 : f32) -> (f32, f32, f32, f32) {2161 // CHECK-DAG: %[[C2:.+]] = arith.constant 2.02162 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.02163 // CHECK-NEXT: %[[X:.+]] = arith.addf %arg0, %[[C0]]2164 // CHECK-NEXT: return %[[X]], %arg0, %arg0, %[[C2]]2165 %c0 = arith.constant 0.0 : f322166 %c-0 = arith.constant -0.0 : f322167 %c1 = arith.constant 1.0 : f322168 %0 = arith.addf %c0, %arg0 : f322169 %1 = arith.addf %arg0, %c-0 : f322170 %2 = arith.addf %c-0, %arg0 : f322171 %3 = arith.addf %c1, %c1 : f322172 return %0, %1, %2, %3 : f32, f32, f32, f322173}2174 2175// -----2176 2177// CHECK-LABEL: @test_subf(2178func.func @test_subf(%arg0 : f16) -> (f16, f16, f16) {2179 // CHECK-DAG: %[[C1:.+]] = arith.constant -1.02180 // CHECK-DAG: %[[C0:.+]] = arith.constant -0.02181 // CHECK-NEXT: %[[X:.+]] = arith.subf %arg0, %[[C0]]2182 // CHECK-NEXT: return %arg0, %[[X]], %[[C1]]2183 %c0 = arith.constant 0.0 : f162184 %c-0 = arith.constant -0.0 : f162185 %c1 = arith.constant 1.0 : f162186 %0 = arith.subf %arg0, %c0 : f162187 %1 = arith.subf %arg0, %c-0 : f162188 %2 = arith.subf %c0, %c1 : f162189 return %0, %1, %2 : f16, f16, f162190}2191 2192// -----2193 2194// CHECK-LABEL: @test_mulf(2195func.func @test_mulf(%arg0 : f32) -> (f32, f32, f32, f32) {2196 // CHECK-DAG: %[[C2:.+]] = arith.constant 2.02197 // CHECK-DAG: %[[C4:.+]] = arith.constant 4.02198 // CHECK-NEXT: %[[X:.+]] = arith.mulf %arg0, %[[C2]]2199 // CHECK-NEXT: return %[[X]], %arg0, %arg0, %[[C4]]2200 %c1 = arith.constant 1.0 : f322201 %c2 = arith.constant 2.0 : f322202 %0 = arith.mulf %c2, %arg0 : f322203 %1 = arith.mulf %arg0, %c1 : f322204 %2 = arith.mulf %c1, %arg0 : f322205 %3 = arith.mulf %c2, %c2 : f322206 return %0, %1, %2, %3 : f32, f32, f32, f322207}2208 2209// CHECK-LABEL: @test_mulf1(2210func.func @test_mulf1(%arg0 : f32, %arg1 : f32) -> (f32) {2211 // CHECK-NEXT: %[[X:.+]] = arith.mulf %arg0, %arg1 : f322212 // CHECK-NEXT: return %[[X]]2213 %0 = arith.negf %arg0 : f322214 %1 = arith.negf %arg1 : f322215 %2 = arith.mulf %0, %1 : f322216 return %2 : f322217}2218 2219// CHECK-LABEL: @test_mulf2(2220func.func @test_mulf2(%arg0 : f32) -> (f32, f32) {2221 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.000000e+00 : f322222 // CHECK-DAG: %[[C0n:.+]] = arith.constant -0.000000e+00 : f322223 // CHECK-NEXT: return %[[C0]], %[[C0n]]2224 %c0 = arith.constant 0.0 : f322225 %c0n = arith.constant -0.0 : f322226 %0 = arith.mulf %c0, %arg0 fastmath<nnan,nsz> : f322227 %1 = arith.mulf %c0n, %arg0 fastmath<nnan,nsz> : f322228 return %0, %1 : f32, f322229}2230 2231// -----2232 2233// CHECK-LABEL: @test_divf(2234func.func @test_divf(%arg0 : f64) -> (f64, f64) {2235 // CHECK-NEXT: %[[C5:.+]] = arith.constant 5.000000e-012236 // CHECK-NEXT: return %arg0, %[[C5]]2237 %c1 = arith.constant 1.0 : f642238 %c2 = arith.constant 2.0 : f642239 %0 = arith.divf %arg0, %c1 : f642240 %1 = arith.divf %c1, %c2 : f642241 return %0, %1 : f64, f642242}2243 2244// CHECK-LABEL: @test_divf1(2245func.func @test_divf1(%arg0 : f32, %arg1 : f32) -> (f32) {2246 // CHECK-NEXT: %[[X:.+]] = arith.divf %arg0, %arg1 : f322247 // CHECK-NEXT: return %[[X]]2248 %0 = arith.negf %arg0 : f322249 %1 = arith.negf %arg1 : f322250 %2 = arith.divf %0, %1 : f322251 return %2 : f322252}2253 2254// -----2255 2256func.func @fold_divui_of_muli_0(%arg0 : index, %arg1 : index) -> index {2257 %0 = arith.muli %arg0, %arg1 overflow<nuw> : index2258 %1 = arith.divui %0, %arg0 : index2259 return %1 : index2260}2261// CHECK-LABEL: func @fold_divui_of_muli_0(2262// CHECK-SAME: %[[ARG0:.+]]: index,2263// CHECK-SAME: %[[ARG1:.+]]: index)2264// CHECK: return %[[ARG1]]2265 2266func.func @fold_divui_of_muli_1(%arg0 : index, %arg1 : index) -> index {2267 %0 = arith.muli %arg0, %arg1 overflow<nuw> : index2268 %1 = arith.divui %0, %arg1 : index2269 return %1 : index2270}2271// CHECK-LABEL: func @fold_divui_of_muli_1(2272// CHECK-SAME: %[[ARG0:.+]]: index,2273// CHECK-SAME: %[[ARG1:.+]]: index)2274// CHECK: return %[[ARG0]]2275 2276func.func @fold_divsi_of_muli_0(%arg0 : index, %arg1 : index) -> index {2277 %0 = arith.muli %arg0, %arg1 overflow<nsw> : index2278 %1 = arith.divsi %0, %arg0 : index2279 return %1 : index2280}2281// CHECK-LABEL: func @fold_divsi_of_muli_0(2282// CHECK-SAME: %[[ARG0:.+]]: index,2283// CHECK-SAME: %[[ARG1:.+]]: index)2284// CHECK: return %[[ARG1]]2285 2286func.func @fold_divsi_of_muli_1(%arg0 : index, %arg1 : index) -> index {2287 %0 = arith.muli %arg0, %arg1 overflow<nsw> : index2288 %1 = arith.divsi %0, %arg1 : index2289 return %1 : index2290}2291// CHECK-LABEL: func @fold_divsi_of_muli_1(2292// CHECK-SAME: %[[ARG0:.+]]: index,2293// CHECK-SAME: %[[ARG1:.+]]: index)2294// CHECK: return %[[ARG0]]2295 2296// Do not fold divui(mul(a, v), v) -> a with nuw attribute.2297func.func @no_fold_divui_of_muli(%arg0 : index, %arg1 : index) -> index {2298 %0 = arith.muli %arg0, %arg1 : index2299 %1 = arith.divui %0, %arg0 : index2300 return %1 : index2301}2302// CHECK-LABEL: func @no_fold_divui_of_muli2303// CHECK: %[[T0:.+]] = arith.muli2304// CHECK: %[[T1:.+]] = arith.divui %[[T0]],2305// CHECK: return %[[T1]]2306 2307// Do not fold divsi(mul(a, v), v) -> a with nuw attribute.2308func.func @no_fold_divsi_of_muli(%arg0 : index, %arg1 : index) -> index {2309 %0 = arith.muli %arg0, %arg1 : index2310 %1 = arith.divsi %0, %arg0 : index2311 return %1 : index2312}2313// CHECK-LABEL: func @no_fold_divsi_of_muli2314// CHECK: %[[T0:.+]] = arith.muli2315// CHECK: %[[T1:.+]] = arith.divsi %[[T0]],2316// CHECK: return %[[T1]]2317 2318// -----2319 2320// CHECK-LABEL: @test_cmpf(2321func.func @test_cmpf(%arg0 : f32) -> (i1, i1, i1, i1) {2322// CHECK-DAG: %[[T:.*]] = arith.constant true2323// CHECK-DAG: %[[F:.*]] = arith.constant false2324// CHECK: return %[[F]], %[[F]], %[[T]], %[[T]]2325 %nan = arith.constant 0x7fffffff : f322326 %0 = arith.cmpf olt, %nan, %arg0 : f322327 %1 = arith.cmpf olt, %arg0, %nan : f322328 %2 = arith.cmpf ugt, %nan, %arg0 : f322329 %3 = arith.cmpf ugt, %arg0, %nan : f322330 return %0, %1, %2, %3 : i1, i1, i1, i12331}2332 2333// -----2334 2335// CHECK-LABEL: @constant_FPtoUI(2336func.func @constant_FPtoUI() -> i32 {2337 // CHECK: %[[C0:.+]] = arith.constant 2 : i322338 // CHECK: return %[[C0]]2339 %c0 = arith.constant 2.0 : f322340 %res = arith.fptoui %c0 : f32 to i322341 return %res : i322342}2343 2344// CHECK-LABEL: @constant_FPtoUI_splat(2345func.func @constant_FPtoUI_splat() -> vector<4xi32> {2346 // CHECK: %[[C0:.+]] = arith.constant dense<2> : vector<4xi32>2347 // CHECK: return %[[C0]]2348 %c0 = arith.constant 2.0 : f322349 %splat = vector.broadcast %c0 : f32 to vector<4xf32>2350 %res = arith.fptoui %splat : vector<4xf32> to vector<4xi32>2351 return %res : vector<4xi32>2352}2353 2354// CHECK-LABEL: @constant_FPtoUI_vector(2355func.func @constant_FPtoUI_vector() -> vector<4xi32> {2356 // CHECK: %[[C0:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>2357 // CHECK: return %[[C0]]2358 %vector = arith.constant dense<[1.0, 3.0, 5.0, 7.0]> : vector<4xf32>2359 %res = arith.fptoui %vector : vector<4xf32> to vector<4xi32>2360 return %res : vector<4xi32>2361}2362 2363// -----2364// CHECK-LABEL: @invalid_constant_FPtoUI(2365func.func @invalid_constant_FPtoUI() -> i32 {2366 // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f322367 // CHECK: %[[C1:.+]] = arith.fptoui %[[C0]] : f32 to i322368 // CHECK: return %[[C1]]2369 %c0 = arith.constant -2.0 : f322370 %res = arith.fptoui %c0 : f32 to i322371 return %res : i322372}2373 2374// -----2375// CHECK-LABEL: @constant_FPtoSI(2376func.func @constant_FPtoSI() -> i32 {2377 // CHECK: %[[C0:.+]] = arith.constant -2 : i322378 // CHECK: return %[[C0]]2379 %c0 = arith.constant -2.0 : f322380 %res = arith.fptosi %c0 : f32 to i322381 return %res : i322382}2383 2384// CHECK-LABEL: @constant_FPtoSI_splat(2385func.func @constant_FPtoSI_splat() -> vector<4xi32> {2386 // CHECK: %[[C0:.+]] = arith.constant dense<-2> : vector<4xi32>2387 // CHECK: return %[[C0]]2388 %c0 = arith.constant -2.0 : f322389 %splat = vector.broadcast %c0 : f32 to vector<4xf32>2390 %res = arith.fptosi %splat : vector<4xf32> to vector<4xi32>2391 return %res : vector<4xi32>2392}2393 2394// CHECK-LABEL: @constant_FPtoSI_vector(2395func.func @constant_FPtoSI_vector() -> vector<4xi32> {2396 // CHECK: %[[C0:.+]] = arith.constant dense<[-1, -3, -5, -7]> : vector<4xi32>2397 // CHECK: return %[[C0]]2398 %vector = arith.constant dense<[-1.0, -3.0, -5.0, -7.0]> : vector<4xf32>2399 %res = arith.fptosi %vector : vector<4xf32> to vector<4xi32>2400 return %res : vector<4xi32>2401}2402 2403// -----2404// CHECK-LABEL: @invalid_constant_FPtoSI(2405func.func @invalid_constant_FPtoSI() -> i8 {2406 // CHECK: %[[C0:.+]] = arith.constant 2.000000e+10 : f322407 // CHECK: %[[C1:.+]] = arith.fptosi %[[C0]] : f32 to i82408 // CHECK: return %[[C1]]2409 %c0 = arith.constant 2.0e10 : f322410 %res = arith.fptosi %c0 : f32 to i82411 return %res : i82412}2413 2414// CHECK-LABEL: @constant_SItoFP(2415func.func @constant_SItoFP() -> f32 {2416 // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f322417 // CHECK: return %[[C0]]2418 %c0 = arith.constant -2 : i322419 %res = arith.sitofp %c0 : i32 to f322420 return %res : f322421}2422 2423// CHECK-LABEL: @constant_SItoFP_splat(2424func.func @constant_SItoFP_splat() -> vector<4xf32> {2425 // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32>2426 // CHECK: return %[[C0]]2427 %c0 = arith.constant 2 : i322428 %splat = vector.broadcast %c0 : i32 to vector<4xi32>2429 %res = arith.sitofp %splat : vector<4xi32> to vector<4xf32>2430 return %res : vector<4xf32>2431}2432 2433// CHECK-LABEL: @constant_SItoFP_vector(2434func.func @constant_SItoFP_vector() -> vector<4xf32> {2435 // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32>2436 // CHECK: return %[[C0]]2437 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>2438 %res = arith.sitofp %vector : vector<4xi32> to vector<4xf32>2439 return %res : vector<4xf32>2440}2441 2442// -----2443// CHECK-LABEL: @constant_UItoFP(2444func.func @constant_UItoFP() -> f32 {2445 // CHECK: %[[C0:.+]] = arith.constant 2.000000e+00 : f322446 // CHECK: return %[[C0]]2447 %c0 = arith.constant 2 : i322448 %res = arith.uitofp %c0 : i32 to f322449 return %res : f322450}2451 2452// CHECK-LABEL: @constant_UItoFP_splat(2453func.func @constant_UItoFP_splat() -> vector<4xf32> {2454 // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32>2455 // CHECK: return %[[C0]]2456 %c0 = arith.constant 2 : i322457 %splat = vector.broadcast %c0 : i32 to vector<4xi32>2458 %res = arith.uitofp %splat : vector<4xi32> to vector<4xf32>2459 return %res : vector<4xf32>2460}2461 2462// CHECK-LABEL: @constant_UItoFP_vector(2463func.func @constant_UItoFP_vector() -> vector<4xf32> {2464 // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32>2465 // CHECK: return %[[C0]]2466 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>2467 %res = arith.uitofp %vector : vector<4xi32> to vector<4xf32>2468 return %res : vector<4xf32>2469}2470 2471// -----2472 2473// Tests rewritten from https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/InstCombine/2008-11-08-FCmp.ll2474// When inst combining an FCMP with the LHS coming from a arith.uitofp instruction, we2475// can lower it to signed ICMP instructions.2476 2477// CHECK-LABEL: @test1(2478// CHECK-SAME: %[[arg0:.+]]:2479func.func @test1(%arg0: i32) -> i1 {2480 %cst = arith.constant 0.000000e+00 : f642481 %1 = arith.uitofp %arg0: i32 to f642482 %2 = arith.cmpf ole, %1, %cst : f642483 // CHECK: %[[c0:.+]] = arith.constant 0 : i322484 // CHECK: arith.cmpi ule, %[[arg0]], %[[c0]] : i322485 return %2 : i12486}2487 2488// CHECK-LABEL: @test2(2489// CHECK-SAME: %[[arg0:.+]]:2490func.func @test2(%arg0: i32) -> i1 {2491 %cst = arith.constant 0.000000e+00 : f642492 %1 = arith.uitofp %arg0: i32 to f642493 %2 = arith.cmpf olt, %1, %cst : f642494 return %2 : i12495 // CHECK: %[[c0:.+]] = arith.constant 0 : i322496 // CHECK: arith.cmpi ult, %[[arg0]], %[[c0]] : i322497}2498 2499// CHECK-LABEL: @test3(2500// CHECK-SAME: %[[arg0:.+]]:2501func.func @test3(%arg0: i32) -> i1 {2502 %cst = arith.constant 0.000000e+00 : f642503 %1 = arith.uitofp %arg0: i32 to f642504 %2 = arith.cmpf oge, %1, %cst : f642505 return %2 : i12506 // CHECK: %[[c0:.+]] = arith.constant 0 : i322507 // CHECK: arith.cmpi uge, %[[arg0]], %[[c0]] : i322508}2509 2510// CHECK-LABEL: @test4(2511// CHECK-SAME: %[[arg0:.+]]:2512func.func @test4(%arg0: i32) -> i1 {2513 %cst = arith.constant 0.000000e+00 : f642514 %1 = arith.uitofp %arg0: i32 to f642515 %2 = arith.cmpf ogt, %1, %cst : f642516 // CHECK: %[[c0:.+]] = arith.constant 0 : i322517 // CHECK: arith.cmpi ugt, %[[arg0]], %[[c0]] : i322518 return %2 : i12519}2520 2521// CHECK-LABEL: @test5(2522func.func @test5(%arg0: i32) -> i1 {2523 %cst = arith.constant -4.400000e+00 : f642524 %1 = arith.uitofp %arg0: i32 to f642525 %2 = arith.cmpf ogt, %1, %cst : f642526 return %2 : i12527 // CHECK: %[[true:.+]] = arith.constant true2528 // CHECK: return %[[true]] : i12529}2530 2531// CHECK-LABEL: @test6(2532func.func @test6(%arg0: i32) -> i1 {2533 %cst = arith.constant -4.400000e+00 : f642534 %1 = arith.uitofp %arg0: i32 to f642535 %2 = arith.cmpf olt, %1, %cst : f642536 return %2 : i12537 // CHECK: %[[false:.+]] = arith.constant false2538 // CHECK: return %[[false]] : i12539}2540 2541// Check that optimizing unsigned >= comparisons correctly distinguishes2542// positive and negative constants.2543// CHECK-LABEL: @test7(2544// CHECK-SAME: %[[arg0:.+]]:2545func.func @test7(%arg0: i32) -> i1 {2546 %cst = arith.constant 3.200000e+00 : f642547 %1 = arith.uitofp %arg0: i32 to f642548 %2 = arith.cmpf oge, %1, %cst : f642549 return %2 : i12550 // CHECK: %[[c3:.+]] = arith.constant 3 : i322551 // CHECK: arith.cmpi ugt, %[[arg0]], %[[c3]] : i322552}2553 2554// -----2555 2556// CHECK-LABEL: @foldShl(2557// CHECK: %[[res:.+]] = arith.constant 4294967296 : i642558// CHECK: return %[[res]]2559func.func @foldShl() -> i64 {2560 %c1 = arith.constant 1 : i642561 %c32 = arith.constant 32 : i642562 %r = arith.shli %c1, %c32 : i642563 return %r : i642564}2565 2566// CHECK-LABEL: @nofoldShl(2567// CHECK: %[[res:.+]] = arith.shli2568// CHECK: return %[[res]]2569func.func @nofoldShl() -> i64 {2570 %c1 = arith.constant 1 : i642571 %c132 = arith.constant 132 : i642572 %r = arith.shli %c1, %c132 : i642573 return %r : i642574}2575 2576// CHECK-LABEL: @nofoldShl2(2577// CHECK: %[[res:.+]] = arith.shli2578// CHECK: return %[[res]]2579func.func @nofoldShl2() -> i64 {2580 %c1 = arith.constant 1 : i642581 %cm32 = arith.constant -32 : i642582 %r = arith.shli %c1, %cm32 : i642583 return %r : i642584}2585 2586// CHECK-LABEL: @nofoldShl3(2587// CHECK: %[[res:.+]] = arith.shli2588// CHECK: return %[[res]]2589func.func @nofoldShl3() -> i64 {2590 %c1 = arith.constant 1 : i642591 %c64 = arith.constant 64 : i642592 // Note that this should return Poison in the future.2593 %r = arith.shli %c1, %c64 : i642594 return %r : i642595}2596 2597// CHECK-LABEL: @foldShru(2598// CHECK: %[[res:.+]] = arith.constant 2 : i642599// CHECK: return %[[res]]2600func.func @foldShru() -> i64 {2601 %c1 = arith.constant 8 : i642602 %c32 = arith.constant 2 : i642603 %r = arith.shrui %c1, %c32 : i642604 return %r : i642605}2606 2607// CHECK-LABEL: @foldShru2(2608// CHECK: %[[res:.+]] = arith.constant 9223372036854775807 : i642609// CHECK: return %[[res]]2610func.func @foldShru2() -> i64 {2611 %c1 = arith.constant -2 : i642612 %c32 = arith.constant 1 : i642613 %r = arith.shrui %c1, %c32 : i642614 return %r : i642615}2616 2617// CHECK-LABEL: @nofoldShru(2618// CHECK: %[[res:.+]] = arith.shrui2619// CHECK: return %[[res]]2620func.func @nofoldShru() -> i64 {2621 %c1 = arith.constant 8 : i642622 %c132 = arith.constant 132 : i642623 %r = arith.shrui %c1, %c132 : i642624 return %r : i642625}2626 2627// CHECK-LABEL: @nofoldShru2(2628// CHECK: %[[res:.+]] = arith.shrui2629// CHECK: return %[[res]]2630func.func @nofoldShru2() -> i64 {2631 %c1 = arith.constant 8 : i642632 %cm32 = arith.constant -32 : i642633 %r = arith.shrui %c1, %cm32 : i642634 return %r : i642635}2636 2637// CHECK-LABEL: @nofoldShru3(2638// CHECK: %[[res:.+]] = arith.shrui2639// CHECK: return %[[res]]2640func.func @nofoldShru3() -> i64 {2641 %c1 = arith.constant 8 : i642642 %c64 = arith.constant 64 : i642643 // Note that this should return Poison in the future.2644 %r = arith.shrui %c1, %c64 : i642645 return %r : i642646}2647 2648// CHECK-LABEL: @foldShrs(2649// CHECK: %[[res:.+]] = arith.constant 2 : i642650// CHECK: return %[[res]]2651func.func @foldShrs() -> i64 {2652 %c1 = arith.constant 8 : i642653 %c32 = arith.constant 2 : i642654 %r = arith.shrsi %c1, %c32 : i642655 return %r : i642656}2657 2658// CHECK-LABEL: @foldShrs2(2659// CHECK: %[[res:.+]] = arith.constant -1 : i642660// CHECK: return %[[res]]2661func.func @foldShrs2() -> i64 {2662 %c1 = arith.constant -2 : i642663 %c32 = arith.constant 1 : i642664 %r = arith.shrsi %c1, %c32 : i642665 return %r : i642666}2667 2668// CHECK-LABEL: @nofoldShrs(2669// CHECK: %[[res:.+]] = arith.shrsi2670// CHECK: return %[[res]]2671func.func @nofoldShrs() -> i64 {2672 %c1 = arith.constant 8 : i642673 %c132 = arith.constant 132 : i642674 %r = arith.shrsi %c1, %c132 : i642675 return %r : i642676}2677 2678// CHECK-LABEL: @nofoldShrs2(2679// CHECK: %[[res:.+]] = arith.shrsi2680// CHECK: return %[[res]]2681func.func @nofoldShrs2() -> i64 {2682 %c1 = arith.constant 8 : i642683 %cm32 = arith.constant -32 : i642684 %r = arith.shrsi %c1, %cm32 : i642685 return %r : i642686}2687 2688// CHECK-LABEL: @nofoldShrs3(2689// CHECK: %[[res:.+]] = arith.shrsi2690// CHECK: return %[[res]]2691func.func @nofoldShrs3() -> i64 {2692 %c1 = arith.constant 8 : i642693 %c64 = arith.constant 64 : i642694 // Note that this should return Poison in the future.2695 %r = arith.shrsi %c1, %c64 : i642696 return %r : i642697}2698 2699// -----2700 2701// CHECK-LABEL: @test_negf(2702// CHECK: %[[res:.+]] = arith.constant -2.02703// CHECK: return %[[res]]2704func.func @test_negf() -> (f32) {2705 %c = arith.constant 2.0 : f322706 %0 = arith.negf %c : f322707 return %0: f322708}2709 2710// CHECK-LABEL: @test_negf1(2711// CHECK-SAME: %[[arg0:.+]]:2712// CHECK: return %[[arg0]]2713func.func @test_negf1(%f : f32) -> (f32) {2714 %0 = arith.negf %f : f322715 %1 = arith.negf %0 : f322716 return %1: f322717}2718 2719// -----2720 2721// CHECK-LABEL: @test_remui(2722// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32>2723// CHECK: return %[[res]]2724func.func @test_remui() -> (vector<4xi32>) {2725 %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32>2726 %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>2727 %0 = arith.remui %v1, %v2 : vector<4xi32>2728 return %0 : vector<4xi32>2729}2730 2731// // -----2732 2733// CHECK-LABEL: @test_remui_1(2734// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32>2735// CHECK: return %[[res]]2736func.func @test_remui_1(%arg : vector<4xi32>) -> (vector<4xi32>) {2737 %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32>2738 %0 = arith.remui %arg, %v : vector<4xi32>2739 return %0 : vector<4xi32>2740}2741 2742// -----2743 2744// CHECK-LABEL: @test_remsi(2745// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32>2746// CHECK: return %[[res]]2747func.func @test_remsi() -> (vector<4xi32>) {2748 %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32>2749 %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32>2750 %0 = arith.remsi %v1, %v2 : vector<4xi32>2751 return %0 : vector<4xi32>2752}2753 2754// // -----2755 2756// CHECK-LABEL: @test_remsi_1(2757// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32>2758// CHECK: return %[[res]]2759func.func @test_remsi_1(%arg : vector<4xi32>) -> (vector<4xi32>) {2760 %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32>2761 %0 = arith.remsi %arg, %v : vector<4xi32>2762 return %0 : vector<4xi32>2763}2764 2765// -----2766 2767// CHECK-LABEL: @test_remf(2768// CHECK: %[[res:.+]] = arith.constant 1.000000e+00 : f322769// CHECK: return %[[res]]2770func.func @test_remf() -> (f32) {2771 %v1 = arith.constant 3.0 : f322772 %v2 = arith.constant 2.0 : f322773 %0 = arith.remf %v1, %v2 : f322774 return %0 : f322775}2776 2777// CHECK-LABEL: @test_remf2(2778// CHECK: %[[respos:.+]] = arith.constant 1.000000e+00 : f322779// CHECK: %[[resneg:.+]] = arith.constant -1.000000e+00 : f322780// CHECK: return %[[respos]], %[[resneg]]2781func.func @test_remf2() -> (f32, f32) {2782 %v1 = arith.constant 3.0 : f322783 %v2 = arith.constant -2.0 : f322784 %v3 = arith.constant -3.0 : f322785 %0 = arith.remf %v1, %v2 : f322786 %1 = arith.remf %v3, %v2 : f322787 return %0, %1 : f32, f322788}2789 2790// CHECK-LABEL: @test_remf_vec(2791// CHECK: %[[res:.+]] = arith.constant dense<[1.000000e+00, 0.000000e+00, -1.000000e+00, 0.000000e+00]> : vector<4xf32>2792// CHECK: return %[[res]]2793func.func @test_remf_vec() -> (vector<4xf32>) {2794 %v1 = arith.constant dense<[1.0, 2.0, -3.0, 4.0]> : vector<4xf32>2795 %v2 = arith.constant dense<[2.0, 2.0, 2.0, 2.0]> : vector<4xf32>2796 %0 = arith.remf %v1, %v2 : vector<4xf32>2797 return %0 : vector<4xf32>2798}2799 2800// -----2801 2802// CHECK-LABEL: @test_andi_not_fold_rhs(2803// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]2804// CHECK: %[[C:.*]] = arith.constant 0 : index2805// CHECK: return %[[C]]2806 2807func.func @test_andi_not_fold_rhs(%arg0 : index) -> index {2808 %0 = arith.constant -1 : index2809 %1 = arith.xori %arg0, %0 : index2810 %2 = arith.andi %arg0, %1 : index2811 return %2 : index2812}2813 2814 2815// CHECK-LABEL: @test_andi_not_fold_lhs(2816// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]2817// CHECK: %[[C:.*]] = arith.constant 0 : index2818// CHECK: return %[[C]]2819 2820func.func @test_andi_not_fold_lhs(%arg0 : index) -> index {2821 %0 = arith.constant -1 : index2822 %1 = arith.xori %arg0, %0 : index2823 %2 = arith.andi %1, %arg0 : index2824 return %2 : index2825}2826 2827// -----2828 2829// CHECK-LABEL: @test_andi_not_fold_rhs_vec(2830// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]2831// CHECK: %[[C:.*]] = arith.constant dense<0> : vector<2xi32>2832// CHECK: return %[[C]]2833 2834func.func @test_andi_not_fold_rhs_vec(%arg0 : vector<2xi32>) -> vector<2xi32> {2835 %0 = arith.constant dense<[-1, -1]> : vector<2xi32>2836 %1 = arith.xori %arg0, %0 : vector<2xi32>2837 %2 = arith.andi %arg0, %1 : vector<2xi32>2838 return %2 : vector<2xi32>2839}2840 2841 2842// CHECK-LABEL: @test_andi_not_fold_lhs_vec(2843// CHECK-SAME: %[[ARG0:[[:alnum:]]+]]2844// CHECK: %[[C:.*]] = arith.constant dense<0> : vector<2xi32>2845// CHECK: return %[[C]]2846 2847func.func @test_andi_not_fold_lhs_vec(%arg0 : vector<2xi32>) -> vector<2xi32> {2848 %0 = arith.constant dense<[-1, -1]> : vector<2xi32>2849 %1 = arith.xori %arg0, %0 : vector<2xi32>2850 %2 = arith.andi %1, %arg0 : vector<2xi32>2851 return %2 : vector<2xi32>2852}2853 2854// -----2855/// xor(xor(x, a), a) -> x2856 2857// CHECK-LABEL: @xorxor0(2858// CHECK-NOT: xori2859// CHECK: return %arg02860func.func @xorxor0(%a : i32, %b : i32) -> i32 {2861 %c = arith.xori %a, %b : i322862 %res = arith.xori %c, %b : i322863 return %res : i322864}2865 2866// -----2867/// xor(xor(a, x), a) -> x2868 2869// CHECK-LABEL: @xorxor1(2870// CHECK-NOT: xori2871// CHECK: return %arg02872func.func @xorxor1(%a : i32, %b : i32) -> i32 {2873 %c = arith.xori %b, %a : i322874 %res = arith.xori %c, %b : i322875 return %res : i322876}2877 2878// -----2879/// xor(a, xor(x, a)) -> x2880 2881// CHECK-LABEL: @xorxor2(2882// CHECK-NOT: xori2883// CHECK: return %arg02884func.func @xorxor2(%a : i32, %b : i32) -> i32 {2885 %c = arith.xori %a, %b : i322886 %res = arith.xori %b, %c : i322887 return %res : i322888}2889 2890// -----2891/// xor(a, xor(a, x)) -> x2892 2893// CHECK-LABEL: @xorxor3(2894// CHECK-NOT: xori2895// CHECK: return %arg02896func.func @xorxor3(%a : i32, %b : i32) -> i32 {2897 %c = arith.xori %b, %a : i322898 %res = arith.xori %b, %c : i322899 return %res : i322900}2901 2902// -----2903 2904/// and(a, and(a, b)) -> and(a, b)2905 2906// CHECK-LABEL: @andand02907// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)2908// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i322909// CHECK: return %[[RES]]2910func.func @andand0(%a : i32, %b : i32) -> i32 {2911 %c = arith.andi %a, %b : i322912 %res = arith.andi %a, %c : i322913 return %res : i322914}2915 2916// CHECK-LABEL: @andand12917// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)2918// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i322919// CHECK: return %[[RES]]2920func.func @andand1(%a : i32, %b : i32) -> i32 {2921 %c = arith.andi %a, %b : i322922 %res = arith.andi %c, %a : i322923 return %res : i322924}2925 2926// CHECK-LABEL: @andand22927// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)2928// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i322929// CHECK: return %[[RES]]2930func.func @andand2(%a : i32, %b : i32) -> i32 {2931 %c = arith.andi %a, %b : i322932 %res = arith.andi %b, %c : i322933 return %res : i322934}2935 2936// CHECK-LABEL: @andand32937// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)2938// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i322939// CHECK: return %[[RES]]2940func.func @andand3(%a : i32, %b : i32) -> i32 {2941 %c = arith.andi %a, %b : i322942 %res = arith.andi %c, %b : i322943 return %res : i322944}2945 2946// -----2947 2948// CHECK-LABEL: @truncIShrSIToTrunciShrUI2949// CHECK-SAME: (%[[A:.+]]: i64)2950// CHECK-NEXT: %[[C32:.+]] = arith.constant 32 : i642951// CHECK-NEXT: %[[SHR:.+]] = arith.shrui %[[A]], %[[C32]] : i642952// CHECK-NEXT: %[[TRU:.+]] = arith.trunci %[[SHR]] : i64 to i322953// CHECK-NEXT: return %[[TRU]] : i322954func.func @truncIShrSIToTrunciShrUI(%a: i64) -> i32 {2955 %c32 = arith.constant 32: i642956 %sh = arith.shrsi %a, %c32 : i642957 %hi = arith.trunci %sh: i64 to i322958 return %hi : i322959}2960 2961// CHECK-LABEL: @truncIShrSIExactToTrunciShrUIExact2962// CHECK-SAME: (%[[A:.+]]: i64)2963// CHECK-NEXT: %[[C32:.+]] = arith.constant 32 : i642964// CHECK-NEXT: %[[SHR:.+]] = arith.shrui %[[A]], %[[C32]] exact : i642965// CHECK-NEXT: %[[TRU:.+]] = arith.trunci %[[SHR]] : i64 to i322966// CHECK-NEXT: return %[[TRU]] : i322967func.func @truncIShrSIExactToTrunciShrUIExact(%a: i64) -> i32 {2968 %c32 = arith.constant 32: i642969 %sh = arith.shrsi %a, %c32 exact : i642970 %hi = arith.trunci %sh: i64 to i322971 return %hi : i322972}2973 2974// CHECK-LABEL: @truncIShrSIToTrunciShrUIBadShiftAmt12975// CHECK: arith.shrsi2976func.func @truncIShrSIToTrunciShrUIBadShiftAmt1(%a: i64) -> i32 {2977 %c33 = arith.constant 33: i642978 %sh = arith.shrsi %a, %c33 : i642979 %hi = arith.trunci %sh: i64 to i322980 return %hi : i322981}2982 2983// CHECK-LABEL: @truncIShrSIToTrunciShrUIBadShiftAmt22984// CHECK: arith.shrsi2985func.func @truncIShrSIToTrunciShrUIBadShiftAmt2(%a: i64) -> i32 {2986 %c31 = arith.constant 31: i642987 %sh = arith.shrsi %a, %c31 : i642988 %hi = arith.trunci %sh: i64 to i322989 return %hi : i322990}2991 2992// CHECK-LABEL: @foldShli02993// CHECK-SAME: (%[[ARG:.*]]: i64)2994// CHECK: return %[[ARG]] : i642995func.func @foldShli0(%x : i64) -> i64 {2996 %c0 = arith.constant 0 : i642997 %r = arith.shli %x, %c0 : i642998 return %r : i642999}3000 3001// CHECK-LABEL: @foldShrui03002// CHECK-SAME: (%[[ARG:.*]]: i64)3003// CHECK: return %[[ARG]] : i643004func.func @foldShrui0(%x : i64) -> i64 {3005 %c0 = arith.constant 0 : i643006 %r = arith.shrui %x, %c0 : i643007 return %r : i643008}3009 3010// CHECK-LABEL: @foldShrsi03011// CHECK-SAME: (%[[ARG:.*]]: i64)3012// CHECK: return %[[ARG]] : i643013func.func @foldShrsi0(%x : i64) -> i64 {3014 %c0 = arith.constant 0 : i643015 %r = arith.shrsi %x, %c0 : i643016 return %r : i643017}3018 3019// CHECK-LABEL: @foldOrXor13020// CHECK-SAME: (%[[ARG:.*]]: i1)3021// CHECK: %[[ONE:.*]] = arith.constant true3022// CHECK: return %[[ONE]]3023func.func @foldOrXor1(%arg0: i1) -> i1 {3024 %0 = arith.constant true3025 %1 = arith.xori %arg0, %0 : i13026 %2 = arith.ori %arg0, %1 : i13027 return %2 : i13028}3029 3030// CHECK-LABEL: @foldOrXor23031// CHECK-SAME: (%[[ARG:.*]]: i1)3032// CHECK: %[[ONE:.*]] = arith.constant true3033// CHECK: return %[[ONE]]3034func.func @foldOrXor2(%arg0: i1) -> i1 {3035 %0 = arith.constant true3036 %1 = arith.xori %0, %arg0 : i13037 %2 = arith.ori %arg0, %1 : i13038 return %2 : i13039}3040 3041// CHECK-LABEL: @foldOrXor33042// CHECK-SAME: (%[[ARG:.*]]: i1)3043// CHECK: %[[ONE:.*]] = arith.constant true3044// CHECK: return %[[ONE]]3045func.func @foldOrXor3(%arg0: i1) -> i1 {3046 %0 = arith.constant true3047 %1 = arith.xori %arg0, %0 : i13048 %2 = arith.ori %1, %arg0 : i13049 return %2 : i13050}3051 3052// CHECK-LABEL: @foldOrXor43053// CHECK-SAME: (%[[ARG:.*]]: i1)3054// CHECK: %[[ONE:.*]] = arith.constant true3055// CHECK: return %[[ONE]]3056func.func @foldOrXor4(%arg0: i1) -> i1 {3057 %0 = arith.constant true3058 %1 = arith.xori %0, %arg0 : i13059 %2 = arith.ori %1, %arg0 : i13060 return %2 : i13061}3062 3063// CHECK-LABEL: @foldOrXor53064// CHECK-SAME: (%[[ARG:.*]]: i32)3065// CHECK: %[[ONE:.*]] = arith.constant -13066// CHECK: return %[[ONE]]3067func.func @foldOrXor5(%arg0: i32) -> i32 {3068 %0 = arith.constant -1 : i323069 %1 = arith.xori %arg0, %0 : i323070 %2 = arith.ori %arg0, %1 : i323071 return %2 : i323072}3073 3074// CHECK-LABEL: @foldOrXor63075// CHECK-SAME: (%[[ARG:.*]]: index)3076// CHECK: %[[ONE:.*]] = arith.constant -13077// CHECK: return %[[ONE]]3078func.func @foldOrXor6(%arg0: index) -> index {3079 %0 = arith.constant -1 : index3080 %1 = arith.xori %arg0, %0 : index3081 %2 = arith.ori %arg0, %1 : index3082 return %2 : index3083}3084 3085// CHECK-LABEL: @selectOfPoison3086// CHECK-SAME: %[[ARG:[[:alnum:]]+]]: i323087// CHECK: %[[UB:.*]] = ub.poison : i323088// CHECK: return %[[ARG]], %[[ARG]], %[[UB]], %[[ARG]]3089func.func @selectOfPoison(%cond : i1, %arg: i32) -> (i32, i32, i32, i32) {3090 %poison = ub.poison : i323091 %select1 = arith.select %cond, %poison, %arg : i323092 %select2 = arith.select %cond, %arg, %poison : i323093 3094 // Check that constant folding is applied prior to poison handling.3095 %true = arith.constant true3096 %false = arith.constant false3097 %select3 = arith.select %true, %poison, %arg : i323098 %select4 = arith.select %false, %poison, %arg : i323099 return %select1, %select2, %select3, %select4 : i32, i32, i32, i323100}3101 3102// CHECK-LABEL: @addi_poison13103// CHECK: %[[P:.*]] = ub.poison : i323104// CHECK: return %[[P]]3105func.func @addi_poison1(%arg: i32) -> i32 {3106 %0 = ub.poison : i323107 %1 = arith.addi %0, %arg : i323108 return %1 : i323109}3110 3111// CHECK-LABEL: @addi_poison23112// CHECK: %[[P:.*]] = ub.poison : i323113// CHECK: return %[[P]]3114func.func @addi_poison2(%arg: i32) -> i32 {3115 %0 = ub.poison : i323116 %1 = arith.addi %arg, %0 : i323117 return %1 : i323118}3119 3120// CHECK-LABEL: @addf_poison13121// CHECK: %[[P:.*]] = ub.poison : f323122// CHECK: return %[[P]]3123func.func @addf_poison1(%arg: f32) -> f32 {3124 %0 = ub.poison : f323125 %1 = arith.addf %0, %arg : f323126 return %1 : f323127}3128 3129// CHECK-LABEL: @addf_poison23130// CHECK: %[[P:.*]] = ub.poison : f323131// CHECK: return %[[P]]3132func.func @addf_poison2(%arg: f32) -> f32 {3133 %0 = ub.poison : f323134 %1 = arith.addf %arg, %0 : f323135 return %1 : f323136}3137 3138 3139// CHECK-LABEL: @negf_poison3140// CHECK: %[[P:.*]] = ub.poison : f323141// CHECK: return %[[P]]3142func.func @negf_poison() -> f32 {3143 %0 = ub.poison : f323144 %1 = arith.negf %0 : f323145 return %1 : f323146}3147 3148// CHECK-LABEL: @extsi_poison3149// CHECK: %[[P:.*]] = ub.poison : i643150// CHECK: return %[[P]]3151func.func @extsi_poison() -> i64 {3152 %0 = ub.poison : i323153 %1 = arith.extsi %0 : i32 to i643154 return %1 : i643155}3156 3157// Just checks that this doesn't crash.3158// CHECK-LABEL: @unsignedExtendConstantResource3159func.func @unsignedExtendConstantResource() -> tensor<i16> {3160 %c2 = arith.constant dense_resource<blob1> : tensor<i8>3161 %ext = arith.extui %c2 : tensor<i8> to tensor<i16>3162 return %ext : tensor<i16>3163}3164 3165// CHECK-LABEL: @extsi_i03166// CHECK: %[[ZERO:.*]] = arith.constant 0 : i163167// CHECK: return %[[ZERO]] : i163168func.func @extsi_i0() -> i16 {3169 %c0 = arith.constant 0 : i03170 %extsi = arith.extsi %c0 : i0 to i163171 return %extsi : i163172}3173 3174// CHECK-LABEL: @extui_i03175// CHECK: %[[ZERO:.*]] = arith.constant 0 : i163176// CHECK: return %[[ZERO]] : i163177func.func @extui_i0() -> i16 {3178 %c0 = arith.constant 0 : i03179 %extui = arith.extui %c0 : i0 to i163180 return %extui : i163181}3182 3183// CHECK-LABEL: @trunc_i03184// CHECK: %[[ZERO:.*]] = arith.constant 0 : i03185// CHECK: return %[[ZERO]] : i03186func.func @trunc_i0() -> i0 {3187 %cFF = arith.constant 0xFF : i83188 %trunc = arith.trunci %cFF : i8 to i03189 return %trunc : i03190}3191 3192// CHECK-LABEL: @shli_i03193// CHECK: %[[ZERO:.*]] = arith.constant 0 : i03194// CHECK: return %[[ZERO]] : i03195func.func @shli_i0() -> i0 {3196 %c0 = arith.constant 0 : i03197 %shli = arith.shli %c0, %c0 : i03198 return %shli : i03199}3200 3201// CHECK-LABEL: @shrsi_i03202// CHECK: %[[ZERO:.*]] = arith.constant 0 : i03203// CHECK: return %[[ZERO]] : i03204func.func @shrsi_i0() -> i0 {3205 %c0 = arith.constant 0 : i03206 %shrsi = arith.shrsi %c0, %c0 : i03207 return %shrsi : i03208}3209 3210// CHECK-LABEL: @shrui_i03211// CHECK: %[[ZERO:.*]] = arith.constant 0 : i03212// CHECK: return %[[ZERO]] : i03213func.func @shrui_i0() -> i0 {3214 %c0 = arith.constant 0 : i03215 %shrui = arith.shrui %c0, %c0 : i03216 return %shrui : i03217}3218 3219// CHECK-LABEL: @maxsi_i03220// CHECK: %[[ZERO:.*]] = arith.constant 0 : i03221// CHECK: return %[[ZERO]] : i03222func.func @maxsi_i0() -> i0 {3223 %c0 = arith.constant 0 : i03224 %maxsi = arith.maxsi %c0, %c0 : i03225 return %maxsi : i03226}3227 3228// CHECK-LABEL: @minsi_i03229// CHECK: %[[ZERO:.*]] = arith.constant 0 : i03230// CHECK: return %[[ZERO]] : i03231func.func @minsi_i0() -> i0 {3232 %c0 = arith.constant 0 : i03233 %minsi = arith.minsi %c0, %c0 : i03234 return %minsi : i03235}3236 3237// CHECK-LABEL: @mulsi_extended_i03238// CHECK: %[[ZERO:.*]] = arith.constant 0 : i03239// CHECK: return %[[ZERO]], %[[ZERO]] : i03240func.func @mulsi_extended_i0() -> (i0, i0) {3241 %c0 = arith.constant 0 : i03242 %mulsi_extended:2 = arith.mulsi_extended %c0, %c0 : i03243 return %mulsi_extended#0, %mulsi_extended#1 : i0, i03244}3245 3246// CHECK-LABEL: @sequences_fastmath_contract3247// CHECK-SAME: ([[ARG0:%.+]]: bf16)3248// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]3249// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]3250// CHECK: [[SIN:%.+]] = math.sin [[ABSF]]3251// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]3252// CHECK: return [[TRUNCF]] : bf163253func.func @sequences_fastmath_contract(%arg0: bf16) -> bf16 {3254 %0 = arith.extf %arg0 fastmath<contract> : bf16 to f323255 %1 = math.absf %0 : f323256 %2 = arith.truncf %1 fastmath<contract> : f32 to bf163257 %3 = arith.extf %2 fastmath<contract> : bf16 to f323258 %4 = math.sin %3 : f323259 %5 = arith.truncf %4 fastmath<contract> : f32 to bf163260 return %5 : bf163261}3262 3263// CHECK-LABEL: @sequences_no_fastmath3264// CHECK-SAME: ([[ARG0:%.+]]: bf16)3265// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]3266// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]3267// CHECK: [[TRUNCF1:%.+]] = arith.truncf [[ABSF]]3268// CHECK: [[EXTF1:%.+]] = arith.extf [[TRUNCF1]]3269// CHECK: [[SIN:%.+]] = math.sin [[EXTF1]]3270// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]3271// CHECK: return [[TRUNCF]] : bf163272func.func @sequences_no_fastmath(%arg0: bf16) -> bf16 {3273 %0 = arith.extf %arg0 : bf16 to f323274 %1 = math.absf %0 : f323275 %2 = arith.truncf %1 : f32 to bf163276 %3 = arith.extf %2 : bf16 to f323277 %4 = math.sin %3 : f323278 %5 = arith.truncf %4 : f32 to bf163279 return %5 : bf163280}3281 3282// CHECK-LABEL: @eliminate_cast_to_f163283// CHECK: return [[arg0:%.+]] : f323284func.func @eliminate_cast_to_f16(%arg0: f32) -> f32 {3285 %0 = arith.truncf %arg0 fastmath<contract> : f32 to f163286 %1 = arith.extf %0 fastmath<contract> : f16 to f323287 return %1 : f323288}3289 3290// CHECK-LABEL: @eliminate_cast_to_bf163291// CHECK: return [[arg0:%.+]] : f323292func.func @eliminate_cast_to_bf16(%arg0: f32) -> f32 {3293 %0 = arith.truncf %arg0 fastmath<contract> : f32 to bf163294 %1 = arith.extf %0 fastmath<contract> : bf16 to f323295 return %1 : f323296}3297 3298// CHECK-LABEL: @bf16_sin_vector3299// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>)3300// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]3301// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]3302// CHECK: [[SIN:%.+]] = math.sin [[ABSF]]3303// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]3304// CHECK: return [[TRUNCF]] : vector<32x32x32xbf16>3305func.func @bf16_sin_vector(%arg0: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> {3306 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3307 %1 = math.absf %0 : vector<32x32x32xf32>3308 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3309 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3310 %4 = math.sin %3 : vector<32x32x32xf32>3311 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3312 return %5 : vector<32x32x32xbf16>3313}3314 3315// CHECK-LABEL: @f16_sin_vector3316// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xf16>)3317// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]3318// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]3319// CHECK: [[SIN:%.+]] = math.sin [[ABSF]]3320// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]]3321// CHECK: return [[TRUNCF]] : vector<32x32x32xf16>3322func.func @f16_sin_vector(%arg0: vector<32x32x32xf16>) -> vector<32x32x32xf16> {3323 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xf16> to vector<32x32x32xf32>3324 %1 = math.absf %0 : vector<32x32x32xf32>3325 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xf16>3326 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xf16> to vector<32x32x32xf32>3327 %4 = math.sin %3 : vector<32x32x32xf32>3328 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xf16>3329 return %5 : vector<32x32x32xf16>3330}3331 3332// CHECK-LABEL: @bf16_branch_vector3333// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>)3334// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]]3335// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]]3336// CHECK-DAG: [[SIN:%.+]] = math.sin [[ABSF]]3337// CHECK-DAG: [[COS:%.+]] = math.cos [[ABSF]]3338// CHECK: [[ADDF:%.+]] = arith.addf [[SIN]], [[COS]]3339// CHECK: [[TRUNCF:%.+]] = arith.truncf [[ADDF]]3340// CHECK: return [[TRUNCF]] : vector<32x32x32xbf16>3341func.func @bf16_branch_vector(%arg0: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> {3342 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3343 %1 = math.absf %0 : vector<32x32x32xf32>3344 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3345 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3346 %4 = math.sin %3 : vector<32x32x32xf32>3347 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3348 %6 = arith.extf %5 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3349 %7 = math.cos %3 : vector<32x32x32xf32>3350 %8 = arith.truncf %7 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3351 %9 = arith.extf %8 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3352 %10 = arith.addf %6, %9 : vector<32x32x32xf32>3353 %11 = arith.truncf %10 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3354 return %11 : vector<32x32x32xbf16>3355}3356 3357// CHECK-LABEL: @bf16_fma3358// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>, [[ARG1:%.+]]: vector<32x32x32xbf16>, [[ARG2:%.+]]: vector<32x32x32xbf16>)3359// CHECK: [[EXTF0:%.+]] = arith.extf [[ARG0]]3360// CHECK: [[ABSF:%.+]] = math.absf [[EXTF0]]3361// CHECK-DAG: [[SIN:%.+]] = math.sin [[ABSF]]3362// CHECK: [[TRUNCF0:%.+]] = arith.truncf [[SIN]]3363// CHECK-DAG: [[FMA:%.+]] = math.fma [[TRUNCF0]], [[ARG1]], [[ARG2]]3364// CHECK: [[EXTF1:%.+]] = arith.extf [[FMA]]3365// CHECK: [[ADDF:%.+]] = arith.addf [[EXTF1]], [[SIN]]3366// CHECK: [[TRUNCF1:%.+]] = arith.truncf [[ADDF]]3367// CHECK: return [[TRUNCF1]] : vector<32x32x32xbf16>3368func.func @bf16_fma(%arg0: vector<32x32x32xbf16>, %arg1: vector<32x32x32xbf16>, %arg2: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> {3369 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3370 %1 = math.absf %0 : vector<32x32x32xf32>3371 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3372 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3373 %4 = math.sin %3 : vector<32x32x32xf32>3374 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3375 %6 = arith.extf %5 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3376 %7 = math.fma %5, %arg1, %arg2 : vector<32x32x32xbf16>3377 %8 = arith.extf %7 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32>3378 %9 = arith.addf %8, %6 : vector<32x32x32xf32>3379 %10 = arith.truncf %9 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16>3380 return %10 : vector<32x32x32xbf16>3381}3382 3383{-#3384 dialect_resources: {3385 builtin: {3386 // Note: This is just copied blob, the actual value isn't used or checked.3387 blob1: "0x08000000010000000000000002000000000000000300000000000000"3388 }3389 }3390#-}3391 3392// CHECK-LABEL: func @unreachable()3393// CHECK-NEXT: return3394// CHECK-NOT: arith3395func.func @unreachable() {3396 return3397^unreachable:3398 %c1_i64 = arith.constant 1 : i643399 // This self referencing operation is legal in an unreachable block.3400 // Many patterns are unsafe with respect to this kind of situation,3401 // check that we don't infinite loop here.3402 %add = arith.addi %add, %c1_i64 : i643403 cf.br ^unreachable3404}3405 3406