1// RUN: mlir-opt %s -canonicalize --split-input-file | FileCheck %s 2 3// CHECK-LABEL: @select_same_val 4// CHECK: return %arg1 5func.func @select_same_val(%arg0: i1, %arg1: i64) -> i64 { 6 %0 = arith.select %arg0, %arg1, %arg1 : i64 7 return %0 : i64 8} 9 10// CHECK-LABEL: @select_cmp_eq_select 11// CHECK: return %arg1 12func.func @select_cmp_eq_select(%arg0: i64, %arg1: i64) -> i64 { 13 %0 = arith.cmpi eq, %arg0, %arg1 : i64 14 %1 = arith.select %0, %arg0, %arg1 : i64 15 return %1 : i64 16} 17 18// CHECK-LABEL: @select_cmp_ne_select 19// CHECK: return %arg0 20func.func @select_cmp_ne_select(%arg0: i64, %arg1: i64) -> i64 { 21 %0 = arith.cmpi ne, %arg0, %arg1 : i64 22 %1 = arith.select %0, %arg0, %arg1 : i64 23 return %1 : i64 24} 25 26// CHECK-LABEL: @select_extui 27// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i64 28// CHECK: return %[[res]] 29func.func @select_extui(%arg0: i1) -> i64 { 30 %c0_i64 = arith.constant 0 : i64 31 %c1_i64 = arith.constant 1 : i64 32 %res = arith.select %arg0, %c1_i64, %c0_i64 : i64 33 return %res : i64 34} 35 36// CHECK-LABEL: @select_extui2 37// CHECK-DAG: %true = arith.constant true 38// CHECK-DAG: %[[xor:.+]] = arith.xori %arg0, %true : i1 39// CHECK-DAG: %[[res:.+]] = arith.extui %[[xor]] : i1 to i64 40// CHECK: return %[[res]] 41func.func @select_extui2(%arg0: i1) -> i64 { 42 %c0_i64 = arith.constant 0 : i64 43 %c1_i64 = arith.constant 1 : i64 44 %res = arith.select %arg0, %c0_i64, %c1_i64 : i64 45 return %res : i64 46} 47 48// CHECK-LABEL: @select_extui_i1 49// CHECK-NEXT: return %arg0 50func.func @select_extui_i1(%arg0: i1) -> i1 { 51 %c0_i1 = arith.constant false 52 %c1_i1 = arith.constant true 53 %res = arith.select %arg0, %c1_i1, %c0_i1 : i1 54 return %res : i1 55} 56 57// CHECK-LABEL: @selToNot 58// CHECK: %[[trueval:.+]] = arith.constant true 59// CHECK: %[[res:.+]] = arith.xori %arg0, %[[trueval]] : i1 60// CHECK: return %[[res]] 61func.func @selToNot(%arg0: i1) -> i1 { 62 %true = arith.constant true 63 %false = arith.constant false 64 %res = arith.select %arg0, %false, %true : i1 65 return %res : i1 66} 67 68// CHECK-LABEL: @selToArith 69// CHECK-NEXT: %[[trueval:.+]] = arith.constant true 70// CHECK-NEXT: %[[notcmp:.+]] = arith.xori %arg0, %[[trueval]] : i1 71// CHECK-NEXT: %[[condtrue:.+]] = arith.andi %arg0, %arg1 : i1 72// CHECK-NEXT: %[[condfalse:.+]] = arith.andi %[[notcmp]], %arg2 : i1 73// CHECK-NEXT: %[[res:.+]] = arith.ori %[[condtrue]], %[[condfalse]] : i1 74// CHECK: return %[[res]] 75func.func @selToArith(%arg0: i1, %arg1 : i1, %arg2 : i1) -> i1 { 76 %res = arith.select %arg0, %arg1, %arg2 : i1 77 return %res : i1 78} 79 80// Test case: Folding of comparisons with equal operands. 81// CHECK-LABEL: @cmpi_equal_operands 82// CHECK-DAG: %[[T:.*]] = arith.constant true 83// CHECK-DAG: %[[F:.*]] = arith.constant false 84// CHECK: return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]], 85// CHECK-SAME: %[[F]], %[[F]], %[[F]], %[[F]], %[[F]] 86func.func @cmpi_equal_operands(%arg0: i64) 87 -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) { 88 %0 = arith.cmpi eq, %arg0, %arg0 : i64 89 %1 = arith.cmpi sle, %arg0, %arg0 : i64 90 %2 = arith.cmpi sge, %arg0, %arg0 : i64 91 %3 = arith.cmpi ule, %arg0, %arg0 : i64 92 %4 = arith.cmpi uge, %arg0, %arg0 : i64 93 %5 = arith.cmpi ne, %arg0, %arg0 : i64 94 %6 = arith.cmpi slt, %arg0, %arg0 : i64 95 %7 = arith.cmpi sgt, %arg0, %arg0 : i64 96 %8 = arith.cmpi ult, %arg0, %arg0 : i64 97 %9 = arith.cmpi ugt, %arg0, %arg0 : i64 98 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9 99 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1 100} 101 102// Test case: Folding of comparisons with equal vector operands. 103// CHECK-LABEL: @cmpi_equal_vector_operands 104// CHECK-DAG: %[[T:.*]] = arith.constant dense<true> 105// CHECK-DAG: %[[F:.*]] = arith.constant dense<false> 106// CHECK: return %[[T]], %[[T]], %[[T]], %[[T]], %[[T]], 107// CHECK-SAME: %[[F]], %[[F]], %[[F]], %[[F]], %[[F]] 108func.func @cmpi_equal_vector_operands(%arg0: vector<1x8xi64>) 109 -> (vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, 110 vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, 111 vector<1x8xi1>, vector<1x8xi1>) { 112 %0 = arith.cmpi eq, %arg0, %arg0 : vector<1x8xi64> 113 %1 = arith.cmpi sle, %arg0, %arg0 : vector<1x8xi64> 114 %2 = arith.cmpi sge, %arg0, %arg0 : vector<1x8xi64> 115 %3 = arith.cmpi ule, %arg0, %arg0 : vector<1x8xi64> 116 %4 = arith.cmpi uge, %arg0, %arg0 : vector<1x8xi64> 117 %5 = arith.cmpi ne, %arg0, %arg0 : vector<1x8xi64> 118 %6 = arith.cmpi slt, %arg0, %arg0 : vector<1x8xi64> 119 %7 = arith.cmpi sgt, %arg0, %arg0 : vector<1x8xi64> 120 %8 = arith.cmpi ult, %arg0, %arg0 : vector<1x8xi64> 121 %9 = arith.cmpi ugt, %arg0, %arg0 : vector<1x8xi64> 122 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9 123 : vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, 124 vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, vector<1x8xi1>, 125 vector<1x8xi1>, vector<1x8xi1> 126} 127 128// ----- 129 130// CHECK-LABEL: @cmpOfExtSI 131// CHECK-NEXT: return %arg0 132func.func @cmpOfExtSI(%arg0: i1) -> i1 { 133 %ext = arith.extsi %arg0 : i1 to i64 134 %c0 = arith.constant 0 : i64 135 %res = arith.cmpi ne, %ext, %c0 : i64 136 return %res : i1 137} 138 139// CHECK-LABEL: @cmpOfExtUI 140// CHECK-NEXT: return %arg0 141func.func @cmpOfExtUI(%arg0: i1) -> i1 { 142 %ext = arith.extui %arg0 : i1 to i64 143 %c0 = arith.constant 0 : i64 144 %res = arith.cmpi ne, %ext, %c0 : i64 145 return %res : i1 146} 147 148// ----- 149 150// CHECK-LABEL: @extSIOfExtUI 151// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i64 152// CHECK: return %[[res]] 153func.func @extSIOfExtUI(%arg0: i1) -> i64 { 154 %ext1 = arith.extui %arg0 : i1 to i8 155 %ext2 = arith.extsi %ext1 : i8 to i64 156 return %ext2 : i64 157} 158 159// CHECK-LABEL: @extUIOfExtUI 160// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i64 161// CHECK: return %[[res]] 162func.func @extUIOfExtUI(%arg0: i1) -> i64 { 163 %ext1 = arith.extui %arg0 : i1 to i8 164 %ext2 = arith.extui %ext1 : i8 to i64 165 return %ext2 : i64 166} 167 168// CHECK-LABEL: @extSIOfExtSI 169// CHECK: %[[res:.+]] = arith.extsi %arg0 : i1 to i64 170// CHECK: return %[[res]] 171func.func @extSIOfExtSI(%arg0: i1) -> i64 { 172 %ext1 = arith.extsi %arg0 : i1 to i8 173 %ext2 = arith.extsi %ext1 : i8 to i64 174 return %ext2 : i64 175} 176 177// ----- 178 179// CHECK-LABEL: @cmpIExtSINE 180// CHECK: %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 181// CHECK: return %[[comb]] 182func.func @cmpIExtSINE(%arg0: i8, %arg1: i8) -> i1 { 183 %ext0 = arith.extsi %arg0 : i8 to i64 184 %ext1 = arith.extsi %arg1 : i8 to i64 185 %res = arith.cmpi ne, %ext0, %ext1 : i64 186 return %res : i1 187} 188 189// CHECK-LABEL: @cmpIExtSIEQ 190// CHECK: %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8 191// CHECK: return %[[comb]] 192func.func @cmpIExtSIEQ(%arg0: i8, %arg1: i8) -> i1 { 193 %ext0 = arith.extsi %arg0 : i8 to i64 194 %ext1 = arith.extsi %arg1 : i8 to i64 195 %res = arith.cmpi eq, %ext0, %ext1 : i64 196 return %res : i1 197} 198 199// CHECK-LABEL: @cmpIExtUINE 200// CHECK: %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 201// CHECK: return %[[comb]] 202func.func @cmpIExtUINE(%arg0: i8, %arg1: i8) -> i1 { 203 %ext0 = arith.extui %arg0 : i8 to i64 204 %ext1 = arith.extui %arg1 : i8 to i64 205 %res = arith.cmpi ne, %ext0, %ext1 : i64 206 return %res : i1 207} 208 209// CHECK-LABEL: @cmpIExtUIEQ 210// CHECK: %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8 211// CHECK: return %[[comb]] 212func.func @cmpIExtUIEQ(%arg0: i8, %arg1: i8) -> i1 { 213 %ext0 = arith.extui %arg0 : i8 to i64 214 %ext1 = arith.extui %arg1 : i8 to i64 215 %res = arith.cmpi eq, %ext0, %ext1 : i64 216 return %res : i1 217} 218 219// ----- 220 221// CHECK-LABEL: @andOfExtSI 222// CHECK: %[[comb:.+]] = arith.andi %arg0, %arg1 : i8 223// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64 224// CHECK: return %[[ext]] 225func.func @andOfExtSI(%arg0: i8, %arg1: i8) -> i64 { 226 %ext0 = arith.extsi %arg0 : i8 to i64 227 %ext1 = arith.extsi %arg1 : i8 to i64 228 %res = arith.andi %ext0, %ext1 : i64 229 return %res : i64 230} 231 232// CHECK-LABEL: @andOfExtUI 233// CHECK: %[[comb:.+]] = arith.andi %arg0, %arg1 : i8 234// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64 235// CHECK: return %[[ext]] 236func.func @andOfExtUI(%arg0: i8, %arg1: i8) -> i64 { 237 %ext0 = arith.extui %arg0 : i8 to i64 238 %ext1 = arith.extui %arg1 : i8 to i64 239 %res = arith.andi %ext0, %ext1 : i64 240 return %res : i64 241} 242 243// CHECK-LABEL: @orOfExtSI 244// CHECK: %[[comb:.+]] = arith.ori %arg0, %arg1 : i8 245// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64 246// CHECK: return %[[ext]] 247func.func @orOfExtSI(%arg0: i8, %arg1: i8) -> i64 { 248 %ext0 = arith.extsi %arg0 : i8 to i64 249 %ext1 = arith.extsi %arg1 : i8 to i64 250 %res = arith.ori %ext0, %ext1 : i64 251 return %res : i64 252} 253 254// CHECK-LABEL: @orOfExtUI 255// CHECK: %[[comb:.+]] = arith.ori %arg0, %arg1 : i8 256// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64 257// CHECK: return %[[ext]] 258func.func @orOfExtUI(%arg0: i8, %arg1: i8) -> i64 { 259 %ext0 = arith.extui %arg0 : i8 to i64 260 %ext1 = arith.extui %arg1 : i8 to i64 261 %res = arith.ori %ext0, %ext1 : i64 262 return %res : i64 263} 264 265// ----- 266 267// CHECK-LABEL: @indexCastOfSignExtend 268// CHECK: %[[res:.+]] = arith.index_cast %arg0 : i8 to index 269// CHECK: return %[[res]] 270func.func @indexCastOfSignExtend(%arg0: i8) -> index { 271 %ext = arith.extsi %arg0 : i8 to i16 272 %idx = arith.index_cast %ext : i16 to index 273 return %idx : index 274} 275 276// CHECK-LABEL: @signExtendConstant 277// CHECK: %[[cres:.+]] = arith.constant -2 : i16 278// CHECK: return %[[cres]] 279func.func @signExtendConstant() -> i16 { 280 %c-2 = arith.constant -2 : i8 281 %ext = arith.extsi %c-2 : i8 to i16 282 return %ext : i16 283} 284 285// CHECK-LABEL: @signExtendConstantSplat 286// CHECK: %[[cres:.+]] = arith.constant dense<-2> : vector<4xi16> 287// CHECK: return %[[cres]] 288func.func @signExtendConstantSplat() -> vector<4xi16> { 289 %c-2 = arith.constant -2 : i8 290 %splat = vector.splat %c-2 : vector<4xi8> 291 %ext = arith.extsi %splat : vector<4xi8> to vector<4xi16> 292 return %ext : vector<4xi16> 293} 294 295// CHECK-LABEL: @signExtendConstantVector 296// CHECK: %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16> 297// CHECK: return %[[cres]] 298func.func @signExtendConstantVector() -> vector<4xi16> { 299 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8> 300 %ext = arith.extsi %vector : vector<4xi8> to vector<4xi16> 301 return %ext : vector<4xi16> 302} 303 304// CHECK-LABEL: @unsignedExtendConstant 305// CHECK: %[[cres:.+]] = arith.constant 2 : i16 306// CHECK: return %[[cres]] 307func.func @unsignedExtendConstant() -> i16 { 308 %c2 = arith.constant 2 : i8 309 %ext = arith.extui %c2 : i8 to i16 310 return %ext : i16 311} 312 313// CHECK-LABEL: @unsignedExtendConstantSplat 314// CHECK: %[[cres:.+]] = arith.constant dense<2> : vector<4xi16> 315// CHECK: return %[[cres]] 316func.func @unsignedExtendConstantSplat() -> vector<4xi16> { 317 %c2 = arith.constant 2 : i8 318 %splat = vector.splat %c2 : vector<4xi8> 319 %ext = arith.extui %splat : vector<4xi8> to vector<4xi16> 320 return %ext : vector<4xi16> 321} 322 323// CHECK-LABEL: @unsignedExtendConstantVector 324// CHECK: %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16> 325// CHECK: return %[[cres]] 326func.func @unsignedExtendConstantVector() -> vector<4xi16> { 327 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8> 328 %ext = arith.extui %vector : vector<4xi8> to vector<4xi16> 329 return %ext : vector<4xi16> 330} 331 332// CHECK-LABEL: @truncConstant 333// CHECK: %[[cres:.+]] = arith.constant -2 : i16 334// CHECK: return %[[cres]] 335func.func @truncConstant(%arg0: i8) -> i16 { 336 %c-2 = arith.constant -2 : i32 337 %tr = arith.trunci %c-2 : i32 to i16 338 return %tr : i16 339} 340 341// CHECK-LABEL: @truncConstantSplat 342// CHECK: %[[cres:.+]] = arith.constant dense<-2> : vector<4xi8> 343// CHECK: return %[[cres]] 344func.func @truncConstantSplat() -> vector<4xi8> { 345 %c-2 = arith.constant -2 : i16 346 %splat = vector.splat %c-2 : vector<4xi16> 347 %trunc = arith.trunci %splat : vector<4xi16> to vector<4xi8> 348 return %trunc : vector<4xi8> 349} 350 351// CHECK-LABEL: @truncConstantVector 352// CHECK: %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8> 353// CHECK: return %[[cres]] 354func.func @truncConstantVector() -> vector<4xi8> { 355 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16> 356 %trunc = arith.trunci %vector : vector<4xi16> to vector<4xi8> 357 return %trunc : vector<4xi8> 358} 359 360// CHECK-LABEL: @truncTrunc 361// CHECK: %[[cres:.+]] = arith.trunci %arg0 : i64 to i8 362// CHECK: return %[[cres]] 363func.func @truncTrunc(%arg0: i64) -> i8 { 364 %tr1 = arith.trunci %arg0 : i64 to i32 365 %tr2 = arith.trunci %tr1 : i32 to i8 366 return %tr2 : i8 367} 368 369// CHECK-LABEL: @truncFPConstant 370// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16 371// CHECK: return %[[cres]] 372func.func @truncFPConstant() -> bf16 { 373 %cst = arith.constant 1.000000e+00 : f32 374 %0 = arith.truncf %cst : f32 to bf16 375 return %0 : bf16 376} 377 378// Test that cases with rounding are NOT propagated 379// CHECK-LABEL: @truncFPConstantRounding 380// CHECK: arith.constant 1.444000e+25 : f32 381// CHECK: truncf 382func.func @truncFPConstantRounding() -> bf16 { 383 %cst = arith.constant 1.444000e+25 : f32 384 %0 = arith.truncf %cst : f32 to bf16 385 return %0 : bf16 386} 387 388// CHECK-LABEL: @tripleAddAdd 389// CHECK: %[[cres:.+]] = arith.constant 59 : index 390// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 391// CHECK: return %[[add]] 392func.func @tripleAddAdd(%arg0: index) -> index { 393 %c17 = arith.constant 17 : index 394 %c42 = arith.constant 42 : index 395 %add1 = arith.addi %c17, %arg0 : index 396 %add2 = arith.addi %c42, %add1 : index 397 return %add2 : index 398} 399 400// CHECK-LABEL: @tripleAddSub0 401// CHECK: %[[cres:.+]] = arith.constant 59 : index 402// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 403// CHECK: return %[[add]] 404func.func @tripleAddSub0(%arg0: index) -> index { 405 %c17 = arith.constant 17 : index 406 %c42 = arith.constant 42 : index 407 %add1 = arith.subi %c17, %arg0 : index 408 %add2 = arith.addi %c42, %add1 : index 409 return %add2 : index 410} 411 412// CHECK-LABEL: @tripleAddSub1 413// CHECK: %[[cres:.+]] = arith.constant 25 : index 414// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 415// CHECK: return %[[add]] 416func.func @tripleAddSub1(%arg0: index) -> index { 417 %c17 = arith.constant 17 : index 418 %c42 = arith.constant 42 : index 419 %add1 = arith.subi %arg0, %c17 : index 420 %add2 = arith.addi %c42, %add1 : index 421 return %add2 : index 422} 423 424// CHECK-LABEL: @tripleSubAdd0 425// CHECK: %[[cres:.+]] = arith.constant 25 : index 426// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 427// CHECK: return %[[add]] 428func.func @tripleSubAdd0(%arg0: index) -> index { 429 %c17 = arith.constant 17 : index 430 %c42 = arith.constant 42 : index 431 %add1 = arith.addi %c17, %arg0 : index 432 %add2 = arith.subi %c42, %add1 : index 433 return %add2 : index 434} 435 436// CHECK-LABEL: @tripleSubAdd1 437// CHECK: %[[cres:.+]] = arith.constant -25 : index 438// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 439// CHECK: return %[[add]] 440func.func @tripleSubAdd1(%arg0: index) -> index { 441 %c17 = arith.constant 17 : index 442 %c42 = arith.constant 42 : index 443 %add1 = arith.addi %c17, %arg0 : index 444 %add2 = arith.subi %add1, %c42 : index 445 return %add2 : index 446} 447 448// CHECK-LABEL: @tripleSubSub0 449// CHECK: %[[cres:.+]] = arith.constant 25 : index 450// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 451// CHECK: return %[[add]] 452func.func @tripleSubSub0(%arg0: index) -> index { 453 %c17 = arith.constant 17 : index 454 %c42 = arith.constant 42 : index 455 %add1 = arith.subi %c17, %arg0 : index 456 %add2 = arith.subi %c42, %add1 : index 457 return %add2 : index 458} 459 460// CHECK-LABEL: @tripleSubSub1 461// CHECK: %[[cres:.+]] = arith.constant -25 : index 462// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 463// CHECK: return %[[add]] 464func.func @tripleSubSub1(%arg0: index) -> index { 465 %c17 = arith.constant 17 : index 466 %c42 = arith.constant 42 : index 467 %add1 = arith.subi %c17, %arg0 : index 468 %add2 = arith.subi %add1, %c42 : index 469 return %add2 : index 470} 471 472// CHECK-LABEL: @tripleSubSub2 473// CHECK: %[[cres:.+]] = arith.constant 59 : index 474// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 475// CHECK: return %[[add]] 476func.func @tripleSubSub2(%arg0: index) -> index { 477 %c17 = arith.constant 17 : index 478 %c42 = arith.constant 42 : index 479 %add1 = arith.subi %arg0, %c17 : index 480 %add2 = arith.subi %c42, %add1 : index 481 return %add2 : index 482} 483 484// CHECK-LABEL: @tripleSubSub3 485// CHECK: %[[cres:.+]] = arith.constant 59 : index 486// CHECK: %[[add:.+]] = arith.subi %arg0, %[[cres]] : index 487// CHECK: return %[[add]] 488func.func @tripleSubSub3(%arg0: index) -> index { 489 %c17 = arith.constant 17 : index 490 %c42 = arith.constant 42 : index 491 %add1 = arith.subi %arg0, %c17 : index 492 %add2 = arith.subi %add1, %c42 : index 493 return %add2 : index 494} 495 496// CHECK-LABEL: @doubleAddSub1 497// CHECK-NEXT: return %arg0 498func.func @doubleAddSub1(%arg0: index, %arg1 : index) -> index { 499 %sub = arith.subi %arg0, %arg1 : index 500 %add = arith.addi %sub, %arg1 : index 501 return %add : index 502} 503 504// CHECK-LABEL: @doubleAddSub2 505// CHECK-NEXT: return %arg0 506func.func @doubleAddSub2(%arg0: index, %arg1 : index) -> index { 507 %sub = arith.subi %arg0, %arg1 : index 508 %add = arith.addi %arg1, %sub : index 509 return %add : index 510} 511 512// CHECK-LABEL: @notCmpEQ 513// CHECK: %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 514// CHECK: return %[[cres]] 515func.func @notCmpEQ(%arg0: i8, %arg1: i8) -> i1 { 516 %true = arith.constant true 517 %cmp = arith.cmpi "eq", %arg0, %arg1 : i8 518 %ncmp = arith.xori %cmp, %true : i1 519 return %ncmp : i1 520} 521 522// CHECK-LABEL: @notCmpEQ2 523// CHECK: %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 524// CHECK: return %[[cres]] 525func.func @notCmpEQ2(%arg0: i8, %arg1: i8) -> i1 { 526 %true = arith.constant true 527 %cmp = arith.cmpi "eq", %arg0, %arg1 : i8 528 %ncmp = arith.xori %true, %cmp : i1 529 return %ncmp : i1 530} 531 532// CHECK-LABEL: @notCmpNE 533// CHECK: %[[cres:.+]] = arith.cmpi eq, %arg0, %arg1 : i8 534// CHECK: return %[[cres]] 535func.func @notCmpNE(%arg0: i8, %arg1: i8) -> i1 { 536 %true = arith.constant true 537 %cmp = arith.cmpi "ne", %arg0, %arg1 : i8 538 %ncmp = arith.xori %cmp, %true : i1 539 return %ncmp : i1 540} 541 542// CHECK-LABEL: @notCmpSLT 543// CHECK: %[[cres:.+]] = arith.cmpi sge, %arg0, %arg1 : i8 544// CHECK: return %[[cres]] 545func.func @notCmpSLT(%arg0: i8, %arg1: i8) -> i1 { 546 %true = arith.constant true 547 %cmp = arith.cmpi "slt", %arg0, %arg1 : i8 548 %ncmp = arith.xori %cmp, %true : i1 549 return %ncmp : i1 550} 551 552// CHECK-LABEL: @notCmpSLE 553// CHECK: %[[cres:.+]] = arith.cmpi sgt, %arg0, %arg1 : i8 554// CHECK: return %[[cres]] 555func.func @notCmpSLE(%arg0: i8, %arg1: i8) -> i1 { 556 %true = arith.constant true 557 %cmp = arith.cmpi "sle", %arg0, %arg1 : i8 558 %ncmp = arith.xori %cmp, %true : i1 559 return %ncmp : i1 560} 561 562// CHECK-LABEL: @notCmpSGT 563// CHECK: %[[cres:.+]] = arith.cmpi sle, %arg0, %arg1 : i8 564// CHECK: return %[[cres]] 565func.func @notCmpSGT(%arg0: i8, %arg1: i8) -> i1 { 566 %true = arith.constant true 567 %cmp = arith.cmpi "sgt", %arg0, %arg1 : i8 568 %ncmp = arith.xori %cmp, %true : i1 569 return %ncmp : i1 570} 571 572// CHECK-LABEL: @notCmpSGE 573// CHECK: %[[cres:.+]] = arith.cmpi slt, %arg0, %arg1 : i8 574// CHECK: return %[[cres]] 575func.func @notCmpSGE(%arg0: i8, %arg1: i8) -> i1 { 576 %true = arith.constant true 577 %cmp = arith.cmpi "sge", %arg0, %arg1 : i8 578 %ncmp = arith.xori %cmp, %true : i1 579 return %ncmp : i1 580} 581 582// CHECK-LABEL: @notCmpULT 583// CHECK: %[[cres:.+]] = arith.cmpi uge, %arg0, %arg1 : i8 584// CHECK: return %[[cres]] 585func.func @notCmpULT(%arg0: i8, %arg1: i8) -> i1 { 586 %true = arith.constant true 587 %cmp = arith.cmpi "ult", %arg0, %arg1 : i8 588 %ncmp = arith.xori %cmp, %true : i1 589 return %ncmp : i1 590} 591 592// CHECK-LABEL: @notCmpULE 593// CHECK: %[[cres:.+]] = arith.cmpi ugt, %arg0, %arg1 : i8 594// CHECK: return %[[cres]] 595func.func @notCmpULE(%arg0: i8, %arg1: i8) -> i1 { 596 %true = arith.constant true 597 %cmp = arith.cmpi "ule", %arg0, %arg1 : i8 598 %ncmp = arith.xori %cmp, %true : i1 599 return %ncmp : i1 600} 601 602// CHECK-LABEL: @notCmpUGT 603// CHECK: %[[cres:.+]] = arith.cmpi ule, %arg0, %arg1 : i8 604// CHECK: return %[[cres]] 605func.func @notCmpUGT(%arg0: i8, %arg1: i8) -> i1 { 606 %true = arith.constant true 607 %cmp = arith.cmpi "ugt", %arg0, %arg1 : i8 608 %ncmp = arith.xori %cmp, %true : i1 609 return %ncmp : i1 610} 611 612// CHECK-LABEL: @notCmpUGE 613// CHECK: %[[cres:.+]] = arith.cmpi ult, %arg0, %arg1 : i8 614// CHECK: return %[[cres]] 615func.func @notCmpUGE(%arg0: i8, %arg1: i8) -> i1 { 616 %true = arith.constant true 617 %cmp = arith.cmpi "uge", %arg0, %arg1 : i8 618 %ncmp = arith.xori %cmp, %true : i1 619 return %ncmp : i1 620} 621 622// ----- 623 624// CHECK-LABEL: @xorxor( 625// CHECK-NOT: xori 626// CHECK: return %arg0 627func.func @xorxor(%cmp : i1) -> i1 { 628 %true = arith.constant true 629 %ncmp = arith.xori %cmp, %true : i1 630 %nncmp = arith.xori %ncmp, %true : i1 631 return %nncmp : i1 632} 633 634// ----- 635 636// CHECK-LABEL: @bitcastSameType( 637// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]] 638func.func @bitcastSameType(%arg : f32) -> f32 { 639 // CHECK: return %[[ARG]] 640 %res = arith.bitcast %arg : f32 to f32 641 return %res : f32 642} 643 644// ----- 645 646// CHECK-LABEL: @bitcastConstantFPtoI( 647func.func @bitcastConstantFPtoI() -> i32 { 648 // CHECK: %[[C0:.+]] = arith.constant 0 : i32 649 // CHECK: return %[[C0]] 650 %c0 = arith.constant 0.0 : f32 651 %res = arith.bitcast %c0 : f32 to i32 652 return %res : i32 653} 654 655// ----- 656 657// CHECK-LABEL: @bitcastConstantItoFP( 658func.func @bitcastConstantItoFP() -> f32 { 659 // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f32 660 // CHECK: return %[[C0]] 661 %c0 = arith.constant 0 : i32 662 %res = arith.bitcast %c0 : i32 to f32 663 return %res : f32 664} 665 666// ----- 667 668// CHECK-LABEL: @bitcastConstantFPtoFP( 669func.func @bitcastConstantFPtoFP() -> f16 { 670 // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f16 671 // CHECK: return %[[C0]] 672 %c0 = arith.constant 0.0 : bf16 673 %res = arith.bitcast %c0 : bf16 to f16 674 return %res : f16 675} 676 677// ----- 678 679// CHECK-LABEL: @bitcastConstantVecFPtoI( 680func.func @bitcastConstantVecFPtoI() -> vector<3xf32> { 681 // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xf32> 682 // CHECK: return %[[C0]] 683 %c0 = arith.constant dense<0> : vector<3xi32> 684 %res = arith.bitcast %c0 : vector<3xi32> to vector<3xf32> 685 return %res : vector<3xf32> 686} 687 688// ----- 689 690// CHECK-LABEL: @bitcastConstantVecItoFP( 691func.func @bitcastConstantVecItoFP() -> vector<3xi32> { 692 // CHECK: %[[C0:.+]] = arith.constant dense<0> : vector<3xi32> 693 // CHECK: return %[[C0]] 694 %c0 = arith.constant dense<0.0> : vector<3xf32> 695 %res = arith.bitcast %c0 : vector<3xf32> to vector<3xi32> 696 return %res : vector<3xi32> 697} 698 699// ----- 700 701// CHECK-LABEL: @bitcastConstantVecFPtoFP( 702func.func @bitcastConstantVecFPtoFP() -> vector<3xbf16> { 703 // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xbf16> 704 // CHECK: return %[[C0]] 705 %c0 = arith.constant dense<0.0> : vector<3xf16> 706 %res = arith.bitcast %c0 : vector<3xf16> to vector<3xbf16> 707 return %res : vector<3xbf16> 708} 709 710// ----- 711 712// CHECK-LABEL: @bitcastBackAndForth( 713// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]] 714func.func @bitcastBackAndForth(%arg : i32) -> i32 { 715 // CHECK: return %[[ARG]] 716 %f = arith.bitcast %arg : i32 to f32 717 %res = arith.bitcast %f : f32 to i32 718 return %res : i32 719} 720 721// ----- 722 723// CHECK-LABEL: @bitcastOfBitcast( 724// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]] 725func.func @bitcastOfBitcast(%arg : i16) -> i16 { 726 // CHECK: return %[[ARG]] 727 %f = arith.bitcast %arg : i16 to f16 728 %bf = arith.bitcast %f : f16 to bf16 729 %res = arith.bitcast %bf : bf16 to i16 730 return %res : i16 731} 732 733// ----- 734 735// CHECK-LABEL: test_maxsi 736// CHECK: %[[C0:.+]] = arith.constant 42 737// CHECK: %[[MAX_INT_CST:.+]] = arith.constant 127 738// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]] 739// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 740func.func @test_maxsi(%arg0 : i8) -> (i8, i8, i8, i8) { 741 %maxIntCst = arith.constant 127 : i8 742 %minIntCst = arith.constant -128 : i8 743 %c0 = arith.constant 42 : i8 744 %0 = arith.maxsi %arg0, %arg0 : i8 745 %1 = arith.maxsi %arg0, %maxIntCst : i8 746 %2 = arith.maxsi %arg0, %minIntCst : i8 747 %3 = arith.maxsi %arg0, %c0 : i8 748 return %0, %1, %2, %3: i8, i8, i8, i8 749} 750 751// CHECK-LABEL: test_maxsi2 752// CHECK: %[[C0:.+]] = arith.constant 42 753// CHECK: %[[MAX_INT_CST:.+]] = arith.constant 127 754// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]] 755// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 756func.func @test_maxsi2(%arg0 : i8) -> (i8, i8, i8, i8) { 757 %maxIntCst = arith.constant 127 : i8 758 %minIntCst = arith.constant -128 : i8 759 %c0 = arith.constant 42 : i8 760 %0 = arith.maxsi %arg0, %arg0 : i8 761 %1 = arith.maxsi %maxIntCst, %arg0: i8 762 %2 = arith.maxsi %minIntCst, %arg0: i8 763 %3 = arith.maxsi %c0, %arg0 : i8 764 return %0, %1, %2, %3: i8, i8, i8, i8 765} 766 767// ----- 768 769// CHECK-LABEL: test_maxui 770// CHECK: %[[C0:.+]] = arith.constant 42 771// CHECK: %[[MAX_INT_CST:.+]] = arith.constant -1 772// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]] 773// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 774func.func @test_maxui(%arg0 : i8) -> (i8, i8, i8, i8) { 775 %maxIntCst = arith.constant 255 : i8 776 %minIntCst = arith.constant 0 : i8 777 %c0 = arith.constant 42 : i8 778 %0 = arith.maxui %arg0, %arg0 : i8 779 %1 = arith.maxui %arg0, %maxIntCst : i8 780 %2 = arith.maxui %arg0, %minIntCst : i8 781 %3 = arith.maxui %arg0, %c0 : i8 782 return %0, %1, %2, %3: i8, i8, i8, i8 783} 784 785// CHECK-LABEL: test_maxui 786// CHECK: %[[C0:.+]] = arith.constant 42 787// CHECK: %[[MAX_INT_CST:.+]] = arith.constant -1 788// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]] 789// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 790func.func @test_maxui2(%arg0 : i8) -> (i8, i8, i8, i8) { 791 %maxIntCst = arith.constant 255 : i8 792 %minIntCst = arith.constant 0 : i8 793 %c0 = arith.constant 42 : i8 794 %0 = arith.maxui %arg0, %arg0 : i8 795 %1 = arith.maxui %maxIntCst, %arg0 : i8 796 %2 = arith.maxui %minIntCst, %arg0 : i8 797 %3 = arith.maxui %c0, %arg0 : i8 798 return %0, %1, %2, %3: i8, i8, i8, i8 799} 800 801// ----- 802 803// CHECK-LABEL: test_minsi 804// CHECK: %[[C0:.+]] = arith.constant 42 805// CHECK: %[[MIN_INT_CST:.+]] = arith.constant -128 806// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]] 807// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 808func.func @test_minsi(%arg0 : i8) -> (i8, i8, i8, i8) { 809 %maxIntCst = arith.constant 127 : i8 810 %minIntCst = arith.constant -128 : i8 811 %c0 = arith.constant 42 : i8 812 %0 = arith.minsi %arg0, %arg0 : i8 813 %1 = arith.minsi %arg0, %maxIntCst : i8 814 %2 = arith.minsi %arg0, %minIntCst : i8 815 %3 = arith.minsi %arg0, %c0 : i8 816 return %0, %1, %2, %3: i8, i8, i8, i8 817} 818 819// CHECK-LABEL: test_minsi 820// CHECK: %[[C0:.+]] = arith.constant 42 821// CHECK: %[[MIN_INT_CST:.+]] = arith.constant -128 822// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]] 823// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 824func.func @test_minsi2(%arg0 : i8) -> (i8, i8, i8, i8) { 825 %maxIntCst = arith.constant 127 : i8 826 %minIntCst = arith.constant -128 : i8 827 %c0 = arith.constant 42 : i8 828 %0 = arith.minsi %arg0, %arg0 : i8 829 %1 = arith.minsi %maxIntCst, %arg0 : i8 830 %2 = arith.minsi %minIntCst, %arg0 : i8 831 %3 = arith.minsi %c0, %arg0 : i8 832 return %0, %1, %2, %3: i8, i8, i8, i8 833} 834 835// ----- 836 837// CHECK-LABEL: test_minui 838// CHECK: %[[C0:.+]] = arith.constant 42 839// CHECK: %[[MIN_INT_CST:.+]] = arith.constant 0 840// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]] 841// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 842func.func @test_minui(%arg0 : i8) -> (i8, i8, i8, i8) { 843 %maxIntCst = arith.constant 255 : i8 844 %minIntCst = arith.constant 0 : i8 845 %c0 = arith.constant 42 : i8 846 %0 = arith.minui %arg0, %arg0 : i8 847 %1 = arith.minui %arg0, %maxIntCst : i8 848 %2 = arith.minui %arg0, %minIntCst : i8 849 %3 = arith.minui %arg0, %c0 : i8 850 return %0, %1, %2, %3: i8, i8, i8, i8 851} 852 853// CHECK-LABEL: test_minui 854// CHECK: %[[C0:.+]] = arith.constant 42 855// CHECK: %[[MIN_INT_CST:.+]] = arith.constant 0 856// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]] 857// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 858func.func @test_minui2(%arg0 : i8) -> (i8, i8, i8, i8) { 859 %maxIntCst = arith.constant 255 : i8 860 %minIntCst = arith.constant 0 : i8 861 %c0 = arith.constant 42 : i8 862 %0 = arith.minui %arg0, %arg0 : i8 863 %1 = arith.minui %maxIntCst, %arg0 : i8 864 %2 = arith.minui %minIntCst, %arg0 : i8 865 %3 = arith.minui %c0, %arg0 : i8 866 return %0, %1, %2, %3: i8, i8, i8, i8 867} 868 869// ----- 870 871// CHECK-LABEL: @test_minf( 872func.func @test_minf(%arg0 : f32) -> (f32, f32, f32) { 873 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.0 874 // CHECK-NEXT: %[[X:.+]] = arith.minf %arg0, %[[C0]] 875 // CHECK-NEXT: return %[[X]], %arg0, %arg0 876 %c0 = arith.constant 0.0 : f32 877 %inf = arith.constant 0x7F800000 : f32 878 %0 = arith.minf %c0, %arg0 : f32 879 %1 = arith.minf %arg0, %arg0 : f32 880 %2 = arith.minf %inf, %arg0 : f32 881 return %0, %1, %2 : f32, f32, f32 882} 883 884// ----- 885 886// CHECK-LABEL: @test_maxf( 887func.func @test_maxf(%arg0 : f32) -> (f32, f32, f32) { 888 // CHECK-DAG: %[[C0:.+]] = arith.constant 889 // CHECK-NEXT: %[[X:.+]] = arith.maxf %arg0, %[[C0]] 890 // CHECK-NEXT: return %[[X]], %arg0, %arg0 891 %c0 = arith.constant 0.0 : f32 892 %-inf = arith.constant 0xFF800000 : f32 893 %0 = arith.maxf %c0, %arg0 : f32 894 %1 = arith.maxf %arg0, %arg0 : f32 895 %2 = arith.maxf %-inf, %arg0 : f32 896 return %0, %1, %2 : f32, f32, f32 897} 898 899// ----- 900 901// CHECK-LABEL: @test_addf( 902func.func @test_addf(%arg0 : f32) -> (f32, f32, f32, f32) { 903 // CHECK-DAG: %[[C2:.+]] = arith.constant 2.0 904 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.0 905 // CHECK-NEXT: %[[X:.+]] = arith.addf %arg0, %[[C0]] 906 // CHECK-NEXT: return %[[X]], %arg0, %arg0, %[[C2]] 907 %c0 = arith.constant 0.0 : f32 908 %c-0 = arith.constant -0.0 : f32 909 %c1 = arith.constant 1.0 : f32 910 %0 = arith.addf %c0, %arg0 : f32 911 %1 = arith.addf %arg0, %c-0 : f32 912 %2 = arith.addf %c-0, %arg0 : f32 913 %3 = arith.addf %c1, %c1 : f32 914 return %0, %1, %2, %3 : f32, f32, f32, f32 915} 916 917// ----- 918 919// CHECK-LABEL: @test_subf( 920func.func @test_subf(%arg0 : f16) -> (f16, f16, f16) { 921 // CHECK-DAG: %[[C1:.+]] = arith.constant -1.0 922 // CHECK-DAG: %[[C0:.+]] = arith.constant -0.0 923 // CHECK-NEXT: %[[X:.+]] = arith.subf %arg0, %[[C0]] 924 // CHECK-NEXT: return %arg0, %[[X]], %[[C1]] 925 %c0 = arith.constant 0.0 : f16 926 %c-0 = arith.constant -0.0 : f16 927 %c1 = arith.constant 1.0 : f16 928 %0 = arith.subf %arg0, %c0 : f16 929 %1 = arith.subf %arg0, %c-0 : f16 930 %2 = arith.subf %c0, %c1 : f16 931 return %0, %1, %2 : f16, f16, f16 932} 933 934// ----- 935 936// CHECK-LABEL: @test_mulf( 937func.func @test_mulf(%arg0 : f32) -> (f32, f32, f32, f32) { 938 // CHECK-DAG: %[[C2:.+]] = arith.constant 2.0 939 // CHECK-DAG: %[[C4:.+]] = arith.constant 4.0 940 // CHECK-NEXT: %[[X:.+]] = arith.mulf %arg0, %[[C2]] 941 // CHECK-NEXT: return %[[X]], %arg0, %arg0, %[[C4]] 942 %c1 = arith.constant 1.0 : f32 943 %c2 = arith.constant 2.0 : f32 944 %0 = arith.mulf %c2, %arg0 : f32 945 %1 = arith.mulf %arg0, %c1 : f32 946 %2 = arith.mulf %c1, %arg0 : f32 947 %3 = arith.mulf %c2, %c2 : f32 948 return %0, %1, %2, %3 : f32, f32, f32, f32 949} 950 951// ----- 952 953// CHECK-LABEL: @test_divf( 954func.func @test_divf(%arg0 : f64) -> (f64, f64) { 955 // CHECK-NEXT: %[[C5:.+]] = arith.constant 5.000000e-01 956 // CHECK-NEXT: return %arg0, %[[C5]] 957 %c1 = arith.constant 1.0 : f64 958 %c2 = arith.constant 2.0 : f64 959 %0 = arith.divf %arg0, %c1 : f64 960 %1 = arith.divf %c1, %c2 : f64 961 return %0, %1 : f64, f64 962} 963 964// ----- 965 966// CHECK-LABEL: @test_cmpf( 967func.func @test_cmpf(%arg0 : f32) -> (i1, i1, i1, i1) { 968// CHECK-DAG: %[[T:.*]] = arith.constant true 969// CHECK-DAG: %[[F:.*]] = arith.constant false 970// CHECK: return %[[F]], %[[F]], %[[T]], %[[T]] 971 %nan = arith.constant 0x7fffffff : f32 972 %0 = arith.cmpf olt, %nan, %arg0 : f32 973 %1 = arith.cmpf olt, %arg0, %nan : f32 974 %2 = arith.cmpf ugt, %nan, %arg0 : f32 975 %3 = arith.cmpf ugt, %arg0, %nan : f32 976 return %0, %1, %2, %3 : i1, i1, i1, i1 977} 978 979// ----- 980 981// CHECK-LABEL: @constant_FPtoUI( 982func.func @constant_FPtoUI() -> i32 { 983 // CHECK: %[[C0:.+]] = arith.constant 2 : i32 984 // CHECK: return %[[C0]] 985 %c0 = arith.constant 2.0 : f32 986 %res = arith.fptoui %c0 : f32 to i32 987 return %res : i32 988} 989 990// CHECK-LABEL: @constant_FPtoUI_splat( 991func.func @constant_FPtoUI_splat() -> vector<4xi32> { 992 // CHECK: %[[C0:.+]] = arith.constant dense<2> : vector<4xi32> 993 // CHECK: return %[[C0]] 994 %c0 = arith.constant 2.0 : f32 995 %splat = vector.splat %c0 : vector<4xf32> 996 %res = arith.fptoui %splat : vector<4xf32> to vector<4xi32> 997 return %res : vector<4xi32> 998} 999 1000// CHECK-LABEL: @constant_FPtoUI_vector( 1001func.func @constant_FPtoUI_vector() -> vector<4xi32> { 1002 // CHECK: %[[C0:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 1003 // CHECK: return %[[C0]] 1004 %vector = arith.constant dense<[1.0, 3.0, 5.0, 7.0]> : vector<4xf32> 1005 %res = arith.fptoui %vector : vector<4xf32> to vector<4xi32> 1006 return %res : vector<4xi32> 1007} 1008 1009// ----- 1010// CHECK-LABEL: @invalid_constant_FPtoUI( 1011func.func @invalid_constant_FPtoUI() -> i32 { 1012 // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32 1013 // CHECK: %[[C1:.+]] = arith.fptoui %[[C0]] : f32 to i32 1014 // CHECK: return %[[C1]] 1015 %c0 = arith.constant -2.0 : f32 1016 %res = arith.fptoui %c0 : f32 to i32 1017 return %res : i32 1018} 1019 1020// ----- 1021// CHECK-LABEL: @constant_FPtoSI( 1022func.func @constant_FPtoSI() -> i32 { 1023 // CHECK: %[[C0:.+]] = arith.constant -2 : i32 1024 // CHECK: return %[[C0]] 1025 %c0 = arith.constant -2.0 : f32 1026 %res = arith.fptosi %c0 : f32 to i32 1027 return %res : i32 1028} 1029 1030// CHECK-LABEL: @constant_FPtoSI_splat( 1031func.func @constant_FPtoSI_splat() -> vector<4xi32> { 1032 // CHECK: %[[C0:.+]] = arith.constant dense<-2> : vector<4xi32> 1033 // CHECK: return %[[C0]] 1034 %c0 = arith.constant -2.0 : f32 1035 %splat = vector.splat %c0 : vector<4xf32> 1036 %res = arith.fptosi %splat : vector<4xf32> to vector<4xi32> 1037 return %res : vector<4xi32> 1038} 1039 1040// CHECK-LABEL: @constant_FPtoSI_vector( 1041func.func @constant_FPtoSI_vector() -> vector<4xi32> { 1042 // CHECK: %[[C0:.+]] = arith.constant dense<[-1, -3, -5, -7]> : vector<4xi32> 1043 // CHECK: return %[[C0]] 1044 %vector = arith.constant dense<[-1.0, -3.0, -5.0, -7.0]> : vector<4xf32> 1045 %res = arith.fptosi %vector : vector<4xf32> to vector<4xi32> 1046 return %res : vector<4xi32> 1047} 1048 1049// ----- 1050// CHECK-LABEL: @invalid_constant_FPtoSI( 1051func.func @invalid_constant_FPtoSI() -> i8 { 1052 // CHECK: %[[C0:.+]] = arith.constant 2.000000e+10 : f32 1053 // CHECK: %[[C1:.+]] = arith.fptosi %[[C0]] : f32 to i8 1054 // CHECK: return %[[C1]] 1055 %c0 = arith.constant 2.0e10 : f32 1056 %res = arith.fptosi %c0 : f32 to i8 1057 return %res : i8 1058} 1059 1060// CHECK-LABEL: @constant_SItoFP( 1061func.func @constant_SItoFP() -> f32 { 1062 // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32 1063 // CHECK: return %[[C0]] 1064 %c0 = arith.constant -2 : i32 1065 %res = arith.sitofp %c0 : i32 to f32 1066 return %res : f32 1067} 1068 1069// CHECK-LABEL: @constant_SItoFP_splat( 1070func.func @constant_SItoFP_splat() -> vector<4xf32> { 1071 // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32> 1072 // CHECK: return %[[C0]] 1073 %c0 = arith.constant 2 : i32 1074 %splat = vector.splat %c0 : vector<4xi32> 1075 %res = arith.sitofp %splat : vector<4xi32> to vector<4xf32> 1076 return %res : vector<4xf32> 1077} 1078 1079// CHECK-LABEL: @constant_SItoFP_vector( 1080func.func @constant_SItoFP_vector() -> vector<4xf32> { 1081 // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32> 1082 // CHECK: return %[[C0]] 1083 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 1084 %res = arith.sitofp %vector : vector<4xi32> to vector<4xf32> 1085 return %res : vector<4xf32> 1086} 1087 1088// ----- 1089// CHECK-LABEL: @constant_UItoFP( 1090func.func @constant_UItoFP() -> f32 { 1091 // CHECK: %[[C0:.+]] = arith.constant 2.000000e+00 : f32 1092 // CHECK: return %[[C0]] 1093 %c0 = arith.constant 2 : i32 1094 %res = arith.uitofp %c0 : i32 to f32 1095 return %res : f32 1096} 1097 1098// CHECK-LABEL: @constant_UItoFP_splat( 1099func.func @constant_UItoFP_splat() -> vector<4xf32> { 1100 // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32> 1101 // CHECK: return %[[C0]] 1102 %c0 = arith.constant 2 : i32 1103 %splat = vector.splat %c0 : vector<4xi32> 1104 %res = arith.uitofp %splat : vector<4xi32> to vector<4xf32> 1105 return %res : vector<4xf32> 1106} 1107 1108// CHECK-LABEL: @constant_UItoFP_vector( 1109func.func @constant_UItoFP_vector() -> vector<4xf32> { 1110 // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32> 1111 // CHECK: return %[[C0]] 1112 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 1113 %res = arith.uitofp %vector : vector<4xi32> to vector<4xf32> 1114 return %res : vector<4xf32> 1115} 1116 1117// ----- 1118 1119// Tests rewritten from https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/InstCombine/2008-11-08-FCmp.ll 1120// When inst combining an FCMP with the LHS coming from a arith.uitofp instruction, we 1121// can lower it to signed ICMP instructions. 1122 1123// CHECK-LABEL: @test1( 1124// CHECK-SAME: %[[arg0:.+]]: 1125func.func @test1(%arg0: i32) -> i1 { 1126 %cst = arith.constant 0.000000e+00 : f64 1127 %1 = arith.uitofp %arg0: i32 to f64 1128 %2 = arith.cmpf ole, %1, %cst : f64 1129 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 1130 // CHECK: arith.cmpi ule, %[[arg0]], %[[c0]] : i32 1131 return %2 : i1 1132} 1133 1134// CHECK-LABEL: @test2( 1135// CHECK-SAME: %[[arg0:.+]]: 1136func.func @test2(%arg0: i32) -> i1 { 1137 %cst = arith.constant 0.000000e+00 : f64 1138 %1 = arith.uitofp %arg0: i32 to f64 1139 %2 = arith.cmpf olt, %1, %cst : f64 1140 return %2 : i1 1141 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 1142 // CHECK: arith.cmpi ult, %[[arg0]], %[[c0]] : i32 1143} 1144 1145// CHECK-LABEL: @test3( 1146// CHECK-SAME: %[[arg0:.+]]: 1147func.func @test3(%arg0: i32) -> i1 { 1148 %cst = arith.constant 0.000000e+00 : f64 1149 %1 = arith.uitofp %arg0: i32 to f64 1150 %2 = arith.cmpf oge, %1, %cst : f64 1151 return %2 : i1 1152 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 1153 // CHECK: arith.cmpi uge, %[[arg0]], %[[c0]] : i32 1154} 1155 1156// CHECK-LABEL: @test4( 1157// CHECK-SAME: %[[arg0:.+]]: 1158func.func @test4(%arg0: i32) -> i1 { 1159 %cst = arith.constant 0.000000e+00 : f64 1160 %1 = arith.uitofp %arg0: i32 to f64 1161 %2 = arith.cmpf ogt, %1, %cst : f64 1162 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 1163 // CHECK: arith.cmpi ugt, %[[arg0]], %[[c0]] : i32 1164 return %2 : i1 1165} 1166 1167// CHECK-LABEL: @test5( 1168func.func @test5(%arg0: i32) -> i1 { 1169 %cst = arith.constant -4.400000e+00 : f64 1170 %1 = arith.uitofp %arg0: i32 to f64 1171 %2 = arith.cmpf ogt, %1, %cst : f64 1172 return %2 : i1 1173 // CHECK: %[[true:.+]] = arith.constant true 1174 // CHECK: return %[[true]] : i1 1175} 1176 1177// CHECK-LABEL: @test6( 1178func.func @test6(%arg0: i32) -> i1 { 1179 %cst = arith.constant -4.400000e+00 : f64 1180 %1 = arith.uitofp %arg0: i32 to f64 1181 %2 = arith.cmpf olt, %1, %cst : f64 1182 return %2 : i1 1183 // CHECK: %[[false:.+]] = arith.constant false 1184 // CHECK: return %[[false]] : i1 1185} 1186 1187// Check that optimizing unsigned >= comparisons correctly distinguishes 1188// positive and negative constants. 1189// CHECK-LABEL: @test7( 1190// CHECK-SAME: %[[arg0:.+]]: 1191func.func @test7(%arg0: i32) -> i1 { 1192 %cst = arith.constant 3.200000e+00 : f64 1193 %1 = arith.uitofp %arg0: i32 to f64 1194 %2 = arith.cmpf oge, %1, %cst : f64 1195 return %2 : i1 1196 // CHECK: %[[c3:.+]] = arith.constant 3 : i32 1197 // CHECK: arith.cmpi ugt, %[[arg0]], %[[c3]] : i32 1198} 1199 1200// ----- 1201 1202// CHECK-LABEL: @foldShl( 1203// CHECK: %[[res:.+]] = arith.constant 4294967296 : i64 1204// CHECK: return %[[res]] 1205func.func @foldShl() -> i64 { 1206 %c1 = arith.constant 1 : i64 1207 %c32 = arith.constant 32 : i64 1208 %r = arith.shli %c1, %c32 : i64 1209 return %r : i64 1210} 1211 1212// CHECK-LABEL: @nofoldShl( 1213// CHECK: %[[res:.+]] = arith.shli 1214// CHECK: return %[[res]] 1215func.func @nofoldShl() -> i64 { 1216 %c1 = arith.constant 1 : i64 1217 %c132 = arith.constant 132 : i64 1218 %r = arith.shli %c1, %c132 : i64 1219 return %r : i64 1220} 1221 1222// CHECK-LABEL: @nofoldShl2( 1223// CHECK: %[[res:.+]] = arith.shli 1224// CHECK: return %[[res]] 1225func.func @nofoldShl2() -> i64 { 1226 %c1 = arith.constant 1 : i64 1227 %cm32 = arith.constant -32 : i64 1228 %r = arith.shli %c1, %cm32 : i64 1229 return %r : i64 1230} 1231 1232// CHECK-LABEL: @foldShru( 1233// CHECK: %[[res:.+]] = arith.constant 2 : i64 1234// CHECK: return %[[res]] 1235func.func @foldShru() -> i64 { 1236 %c1 = arith.constant 8 : i64 1237 %c32 = arith.constant 2 : i64 1238 %r = arith.shrui %c1, %c32 : i64 1239 return %r : i64 1240} 1241 1242// CHECK-LABEL: @foldShru2( 1243// CHECK: %[[res:.+]] = arith.constant 9223372036854775807 : i64 1244// CHECK: return %[[res]] 1245func.func @foldShru2() -> i64 { 1246 %c1 = arith.constant -2 : i64 1247 %c32 = arith.constant 1 : i64 1248 %r = arith.shrui %c1, %c32 : i64 1249 return %r : i64 1250} 1251 1252// CHECK-LABEL: @nofoldShru( 1253// CHECK: %[[res:.+]] = arith.shrui 1254// CHECK: return %[[res]] 1255func.func @nofoldShru() -> i64 { 1256 %c1 = arith.constant 8 : i64 1257 %c132 = arith.constant 132 : i64 1258 %r = arith.shrui %c1, %c132 : i64 1259 return %r : i64 1260} 1261 1262// CHECK-LABEL: @nofoldShru2( 1263// CHECK: %[[res:.+]] = arith.shrui 1264// CHECK: return %[[res]] 1265func.func @nofoldShru2() -> i64 { 1266 %c1 = arith.constant 8 : i64 1267 %cm32 = arith.constant -32 : i64 1268 %r = arith.shrui %c1, %cm32 : i64 1269 return %r : i64 1270} 1271 1272// CHECK-LABEL: @foldShrs( 1273// CHECK: %[[res:.+]] = arith.constant 2 : i64 1274// CHECK: return %[[res]] 1275func.func @foldShrs() -> i64 { 1276 %c1 = arith.constant 8 : i64 1277 %c32 = arith.constant 2 : i64 1278 %r = arith.shrsi %c1, %c32 : i64 1279 return %r : i64 1280} 1281 1282// CHECK-LABEL: @foldShrs2( 1283// CHECK: %[[res:.+]] = arith.constant -1 : i64 1284// CHECK: return %[[res]] 1285func.func @foldShrs2() -> i64 { 1286 %c1 = arith.constant -2 : i64 1287 %c32 = arith.constant 1 : i64 1288 %r = arith.shrsi %c1, %c32 : i64 1289 return %r : i64 1290} 1291 1292// CHECK-LABEL: @nofoldShrs( 1293// CHECK: %[[res:.+]] = arith.shrsi 1294// CHECK: return %[[res]] 1295func.func @nofoldShrs() -> i64 { 1296 %c1 = arith.constant 8 : i64 1297 %c132 = arith.constant 132 : i64 1298 %r = arith.shrsi %c1, %c132 : i64 1299 return %r : i64 1300} 1301 1302// CHECK-LABEL: @nofoldShrs2( 1303// CHECK: %[[res:.+]] = arith.shrsi 1304// CHECK: return %[[res]] 1305func.func @nofoldShrs2() -> i64 { 1306 %c1 = arith.constant 8 : i64 1307 %cm32 = arith.constant -32 : i64 1308 %r = arith.shrsi %c1, %cm32 : i64 1309 return %r : i64 1310} 1311 1312// ----- 1313 1314// CHECK-LABEL: @test_negf( 1315// CHECK: %[[res:.+]] = arith.constant -2.0 1316// CHECK: return %[[res]] 1317func.func @test_negf() -> (f32) { 1318 %c = arith.constant 2.0 : f32 1319 %0 = arith.negf %c : f32 1320 return %0: f32 1321} 1322 1323// ----- 1324 1325// CHECK-LABEL: @test_remui( 1326// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32> 1327// CHECK: return %[[res]] 1328func.func @test_remui() -> (vector<4xi32>) { 1329 %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32> 1330 %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 1331 %0 = arith.remui %v1, %v2 : vector<4xi32> 1332 return %0 : vector<4xi32> 1333} 1334 1335// // ----- 1336 1337// CHECK-LABEL: @test_remui_1( 1338// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32> 1339// CHECK: return %[[res]] 1340func.func @test_remui_1(%arg : vector<4xi32>) -> (vector<4xi32>) { 1341 %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32> 1342 %0 = arith.remui %arg, %v : vector<4xi32> 1343 return %0 : vector<4xi32> 1344} 1345 1346// ----- 1347 1348// CHECK-LABEL: @test_remsi( 1349// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32> 1350// CHECK: return %[[res]] 1351func.func @test_remsi() -> (vector<4xi32>) { 1352 %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32> 1353 %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 1354 %0 = arith.remsi %v1, %v2 : vector<4xi32> 1355 return %0 : vector<4xi32> 1356} 1357 1358// // ----- 1359 1360// CHECK-LABEL: @test_remsi_1( 1361// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32> 1362// CHECK: return %[[res]] 1363func.func @test_remsi_1(%arg : vector<4xi32>) -> (vector<4xi32>) { 1364 %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32> 1365 %0 = arith.remsi %arg, %v : vector<4xi32> 1366 return %0 : vector<4xi32> 1367} 1368