1// RUN: mlir-opt %s -canonicalize="test-convergence" --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: @select_no_fold_ui1 58// CHECK: %[[CONST_0:.+]] = "test.constant"() <{value = 0 : i32}> : () -> ui1 59// CHECK: %[[CONST_1:.+]] = "test.constant"() <{value = 1 : i32}> : () -> ui1 60// CHECK-NEXT: %[[RES:.+]] = arith.select %arg0, %[[CONST_1]], %[[CONST_0]] : ui1 61// CHECK-NEXT: return %[[RES]] 62func.func @select_no_fold_ui1(%arg0: i1) -> ui1 { 63 %c0_i1 = "test.constant"() {value = 0 : i32} : () -> ui1 64 %c1_i1 = "test.constant"() {value = 1 : i32} : () -> ui1 65 %res = arith.select %arg0, %c1_i1, %c0_i1 : ui1 66 return %res : ui1 67} 68 69// CHECK-LABEL: @select_cst_false_scalar 70// 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 false 74 %res = arith.select %false, %arg0, %arg1 : i32 75 return %res : i32 76} 77 78// CHECK-LABEL: @select_cst_true_scalar 79// 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 true 83 %res = arith.select %true, %arg0, %arg1 : i32 84 return %res : i32 85} 86 87// CHECK-LABEL: @select_cst_true_splat 88// 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_i32 99// 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_f32 110// 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: @selToNot 121// CHECK: %[[trueval:.+]] = arith.constant true 122// CHECK: %[[res:.+]] = arith.xori %arg0, %[[trueval]] : i1 123// CHECK: return %[[res]] 124func.func @selToNot(%arg0: i1) -> i1 { 125 %true = arith.constant true 126 %false = arith.constant false 127 %res = arith.select %arg0, %false, %true : i1 128 return %res : i1 129} 130 131// CHECK-LABEL: @redundantSelectTrue 132// CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg1, %arg3 133// CHECK-NEXT: return %[[res]] 134func.func @redundantSelectTrue(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32) -> i32 { 135 %0 = arith.select %arg0, %arg1, %arg2 : i32 136 %res = arith.select %arg0, %0, %arg3 : i32 137 return %res : i32 138} 139 140// CHECK-LABEL: @redundantSelectFalse 141// CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg3, %arg2 142// CHECK-NEXT: return %[[res]] 143func.func @redundantSelectFalse(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : i32) -> i32 { 144 %0 = arith.select %arg0, %arg1, %arg2 : i32 145 %res = arith.select %arg0, %arg3, %0 : i32 146 return %res : i32 147} 148 149// CHECK-LABEL: @selNotCond 150// CHECK-NEXT: %[[res1:.+]] = arith.select %arg0, %arg2, %arg1 151// CHECK-NEXT: %[[res2:.+]] = arith.select %arg0, %arg4, %arg3 152// 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 : i1 155 %cond1 = arith.xori %arg0, %one : i1 156 %cond2 = arith.xori %one, %arg0 : i1 157 158 %res1 = arith.select %cond1, %arg1, %arg2 : i32 159 %res2 = arith.select %cond2, %arg3, %arg4 : i32 160 return %res1, %res2 : i32, i32 161} 162 163// CHECK-LABEL: @cmpiI1eq 164// CHECK-SAME: (%[[ARG:.*]]: i1) 165// CHECK: return %[[ARG]] 166func.func @cmpiI1eq(%arg0: i1) -> i1 { 167 %one = arith.constant 1 : i1 168 %res = arith.cmpi eq, %arg0, %one : i1 169 return %res : i1 170} 171 172// CHECK-LABEL: @cmpiI1eqVec 173// 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: @cmpiI1ne 182// CHECK-SAME: (%[[ARG:.*]]: i1) 183// CHECK: return %[[ARG]] 184func.func @cmpiI1ne(%arg0: i1) -> i1 { 185 %zero = arith.constant 0 : i1 186 %res = arith.cmpi ne, %arg0, %zero : i1 187 return %res : i1 188} 189 190// CHECK-LABEL: @cmpiI1neVec 191// 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: @cmpiI1eqLhs 200// CHECK-SAME: (%[[ARG:.*]]: i1) 201// CHECK: return %[[ARG]] 202func.func @cmpiI1eqLhs(%arg0: i1) -> i1 { 203 %one = arith.constant 1 : i1 204 %res = arith.cmpi eq, %one, %arg0 : i1 205 return %res : i1 206} 207 208// CHECK-LABEL: @cmpiI1eqVecLhs 209// 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: @cmpiI1neLhs 218// CHECK-SAME: (%[[ARG:.*]]: i1) 219// CHECK: return %[[ARG]] 220func.func @cmpiI1neLhs(%arg0: i1) -> i1 { 221 %zero = arith.constant 0 : i1 222 %res = arith.cmpi ne, %zero, %arg0 : i1 223 return %res : i1 224} 225 226// CHECK-LABEL: @cmpiI1neVecLhs 227// 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_operands 237// CHECK-DAG: %[[T:.*]] = arith.constant true 238// CHECK-DAG: %[[F:.*]] = arith.constant false 239// 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 : i64 244 %1 = arith.cmpi sle, %arg0, %arg0 : i64 245 %2 = arith.cmpi sge, %arg0, %arg0 : i64 246 %3 = arith.cmpi ule, %arg0, %arg0 : i64 247 %4 = arith.cmpi uge, %arg0, %arg0 : i64 248 %5 = arith.cmpi ne, %arg0, %arg0 : i64 249 %6 = arith.cmpi slt, %arg0, %arg0 : i64 250 %7 = arith.cmpi sgt, %arg0, %arg0 : i64 251 %8 = arith.cmpi ult, %arg0, %arg0 : i64 252 %9 = arith.cmpi ugt, %arg0, %arg0 : i64 253 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9 254 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1 255} 256 257// Test case: Folding of comparisons with equal vector operands. 258// CHECK-LABEL: @cmpi_equal_vector_operands 259// 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, %9 278 : 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 : i64 289// CHECK: %[[R0:.*]] = arith.cmpi eq, %[[ARG]], %[[C]] : i64 290// CHECK: %[[R1:.*]] = arith.cmpi sge, %[[ARG]], %[[C]] : i64 291// CHECK: %[[R2:.*]] = arith.cmpi sle, %[[ARG]], %[[C]] : i64 292// CHECK: %[[R3:.*]] = arith.cmpi uge, %[[ARG]], %[[C]] : i64 293// CHECK: %[[R4:.*]] = arith.cmpi ule, %[[ARG]], %[[C]] : i64 294// CHECK: %[[R5:.*]] = arith.cmpi ne, %[[ARG]], %[[C]] : i64 295// CHECK: %[[R6:.*]] = arith.cmpi sgt, %[[ARG]], %[[C]] : i64 296// CHECK: %[[R7:.*]] = arith.cmpi slt, %[[ARG]], %[[C]] : i64 297// CHECK: %[[R8:.*]] = arith.cmpi ugt, %[[ARG]], %[[C]] : i64 298// CHECK: %[[R9:.*]] = arith.cmpi ult, %[[ARG]], %[[C]] : i64 299// 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 : i64 304 %0 = arith.cmpi eq, %c1, %arg0 : i64 305 %1 = arith.cmpi sle, %c1, %arg0 : i64 306 %2 = arith.cmpi sge, %c1, %arg0 : i64 307 %3 = arith.cmpi ule, %c1, %arg0 : i64 308 %4 = arith.cmpi uge, %c1, %arg0 : i64 309 %5 = arith.cmpi ne, %c1, %arg0 : i64 310 %6 = arith.cmpi slt, %c1, %arg0 : i64 311 %7 = arith.cmpi sgt, %c1, %arg0 : i64 312 %8 = arith.cmpi ult, %c1, %arg0 : i64 313 %9 = arith.cmpi ugt, %c1, %arg0 : i64 314 return %0, %1, %2, %3, %4, %5, %6, %7, %8, %9 315 : i1, i1, i1, i1, i1, i1, i1, i1, i1, i1 316} 317 318// ----- 319 320// CHECK-LABEL: @cmpOfExtSI( 321// CHECK-NEXT: return %arg0 322func.func @cmpOfExtSI(%arg0: i1) -> i1 { 323 %ext = arith.extsi %arg0 : i1 to i64 324 %c0 = arith.constant 0 : i64 325 %res = arith.cmpi ne, %ext, %c0 : i64 326 return %res : i1 327} 328 329// CHECK-LABEL: @cmpOfExtUI( 330// CHECK-NEXT: return %arg0 331func.func @cmpOfExtUI(%arg0: i1) -> i1 { 332 %ext = arith.extui %arg0 : i1 to i64 333 %c0 = arith.constant 0 : i64 334 %res = arith.cmpi ne, %ext, %c0 : i64 335 return %res : i1 336} 337 338// ----- 339 340// CHECK-LABEL: @cmpOfExtSIVector( 341// CHECK-NEXT: return %arg0 342func.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 %arg0 351func.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: @extSIOfExtUI 361// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i64 362// CHECK: return %[[res]] 363func.func @extSIOfExtUI(%arg0: i1) -> i64 { 364 %ext1 = arith.extui %arg0 : i1 to i8 365 %ext2 = arith.extsi %ext1 : i8 to i64 366 return %ext2 : i64 367} 368 369// CHECK-LABEL: @extUIOfExtUI 370// CHECK: %[[res:.+]] = arith.extui %arg0 : i1 to i64 371// CHECK: return %[[res]] 372func.func @extUIOfExtUI(%arg0: i1) -> i64 { 373 %ext1 = arith.extui %arg0 : i1 to i8 374 %ext2 = arith.extui %ext1 : i8 to i64 375 return %ext2 : i64 376} 377 378// CHECK-LABEL: @extSIOfExtSI 379// CHECK: %[[res:.+]] = arith.extsi %arg0 : i1 to i64 380// CHECK: return %[[res]] 381func.func @extSIOfExtSI(%arg0: i1) -> i64 { 382 %ext1 = arith.extsi %arg0 : i1 to i8 383 %ext2 = arith.extsi %ext1 : i8 to i64 384 return %ext2 : i64 385} 386 387// ----- 388 389// CHECK-LABEL: @cmpIExtSINE 390// CHECK: %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 391// CHECK: return %[[comb]] 392func.func @cmpIExtSINE(%arg0: i8, %arg1: i8) -> i1 { 393 %ext0 = arith.extsi %arg0 : i8 to i64 394 %ext1 = arith.extsi %arg1 : i8 to i64 395 %res = arith.cmpi ne, %ext0, %ext1 : i64 396 return %res : i1 397} 398 399// CHECK-LABEL: @cmpIExtSIEQ 400// CHECK: %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8 401// CHECK: return %[[comb]] 402func.func @cmpIExtSIEQ(%arg0: i8, %arg1: i8) -> i1 { 403 %ext0 = arith.extsi %arg0 : i8 to i64 404 %ext1 = arith.extsi %arg1 : i8 to i64 405 %res = arith.cmpi eq, %ext0, %ext1 : i64 406 return %res : i1 407} 408 409// CHECK-LABEL: @cmpIExtUINE 410// CHECK: %[[comb:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 411// CHECK: return %[[comb]] 412func.func @cmpIExtUINE(%arg0: i8, %arg1: i8) -> i1 { 413 %ext0 = arith.extui %arg0 : i8 to i64 414 %ext1 = arith.extui %arg1 : i8 to i64 415 %res = arith.cmpi ne, %ext0, %ext1 : i64 416 return %res : i1 417} 418 419// CHECK-LABEL: @cmpIExtUIEQ 420// CHECK: %[[comb:.+]] = arith.cmpi eq, %arg0, %arg1 : i8 421// CHECK: return %[[comb]] 422func.func @cmpIExtUIEQ(%arg0: i8, %arg1: i8) -> i1 { 423 %ext0 = arith.extui %arg0 : i8 to i64 424 %ext1 = arith.extui %arg1 : i8 to i64 425 %res = arith.cmpi eq, %ext0, %ext1 : i64 426 return %res : i1 427} 428 429// CHECK-LABEL: @cmpIFoldEQ 430// 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: @cmpIFoldNE 440// 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: @cmpIFoldSGE 450// 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: @cmpIFoldULT 460// 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: @andOfExtSI 472// CHECK: %[[comb:.+]] = arith.andi %arg0, %arg1 : i8 473// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64 474// CHECK: return %[[ext]] 475func.func @andOfExtSI(%arg0: i8, %arg1: i8) -> i64 { 476 %ext0 = arith.extsi %arg0 : i8 to i64 477 %ext1 = arith.extsi %arg1 : i8 to i64 478 %res = arith.andi %ext0, %ext1 : i64 479 return %res : i64 480} 481 482// CHECK-LABEL: @andOfExtUI 483// CHECK: %[[comb:.+]] = arith.andi %arg0, %arg1 : i8 484// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64 485// CHECK: return %[[ext]] 486func.func @andOfExtUI(%arg0: i8, %arg1: i8) -> i64 { 487 %ext0 = arith.extui %arg0 : i8 to i64 488 %ext1 = arith.extui %arg1 : i8 to i64 489 %res = arith.andi %ext0, %ext1 : i64 490 return %res : i64 491} 492 493// CHECK-LABEL: @orOfExtSI 494// CHECK: %[[comb:.+]] = arith.ori %arg0, %arg1 : i8 495// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64 496// CHECK: return %[[ext]] 497func.func @orOfExtSI(%arg0: i8, %arg1: i8) -> i64 { 498 %ext0 = arith.extsi %arg0 : i8 to i64 499 %ext1 = arith.extsi %arg1 : i8 to i64 500 %res = arith.ori %ext0, %ext1 : i64 501 return %res : i64 502} 503 504// CHECK-LABEL: @orOfExtUI 505// CHECK: %[[comb:.+]] = arith.ori %arg0, %arg1 : i8 506// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64 507// CHECK: return %[[ext]] 508func.func @orOfExtUI(%arg0: i8, %arg1: i8) -> i64 { 509 %ext0 = arith.extui %arg0 : i8 to i64 510 %ext1 = arith.extui %arg1 : i8 to i64 511 %res = arith.ori %ext0, %ext1 : i64 512 return %res : i64 513} 514 515// ----- 516 517// CHECK-LABEL: @indexCastOfSignExtend 518// CHECK: %[[res:.+]] = arith.index_cast %arg0 : i8 to index 519// CHECK: return %[[res]] 520func.func @indexCastOfSignExtend(%arg0: i8) -> index { 521 %ext = arith.extsi %arg0 : i8 to i16 522 %idx = arith.index_cast %ext : i16 to index 523 return %idx : index 524} 525 526// CHECK-LABEL: @indexCastUIOfUnsignedExtend 527// CHECK: %[[res:.+]] = arith.index_castui %arg0 : i8 to index 528// CHECK: return %[[res]] 529func.func @indexCastUIOfUnsignedExtend(%arg0: i8) -> index { 530 %ext = arith.extui %arg0 : i8 to i16 531 %idx = arith.index_castui %ext : i16 to index 532 return %idx : index 533} 534 535// CHECK-LABEL: @indexCastFold 536// CHECK: %[[res:.*]] = arith.constant -2 : index 537// CHECK: return %[[res]] 538func.func @indexCastFold() -> index { 539 %c-2 = arith.constant -2 : i8 540 %idx = arith.index_cast %c-2 : i8 to index 541 return %idx : index 542} 543 544// CHECK-LABEL: @indexCastFoldIndexToInt 545// CHECK: %[[res:.*]] = arith.constant 1 : i32 546// CHECK: return %[[res]] 547func.func @indexCastFoldIndexToInt() -> i32 { 548 %c1 = arith.constant 1 : index 549 %int = arith.index_cast %c1 : index to i32 550 return %int : i32 551} 552 553// CHECK-LABEL: @indexCastFoldSplatVector 554// 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: @indexCastFoldVector 563// 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: @indexCastFoldSplatVectorIndexToInt 572// 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: @indexCastFoldVectorIndexToInt 581// 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: @indexCastUIFold 590// CHECK: %[[res:.*]] = arith.constant 254 : index 591// CHECK: return %[[res]] 592func.func @indexCastUIFold() -> index { 593 %c-2 = arith.constant -2 : i8 594 %idx = arith.index_castui %c-2 : i8 to index 595 return %idx : index 596} 597 598// CHECK-LABEL: @indexCastUIFoldSplatVector 599// 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: @indexCastUIFoldVector 608// 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: @indexCastUIFoldIndexToInt 617// CHECK: %[[res:.*]] = arith.constant 1 : i32 618// CHECK: return %[[res]] 619func.func @indexCastUIFoldIndexToInt() -> i32 { 620 %c1 = arith.constant 1 : index 621 %int = arith.index_castui %c1 : index to i32 622 return %int : i32 623} 624 625// CHECK-LABEL: @indexCastUIFoldSplatVectorIndexToInt 626// 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: @indexCastUIFoldVectorIndexToInt 635// 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: @signExtendConstant 644// CHECK: %[[cres:.+]] = arith.constant -2 : i16 645// CHECK: return %[[cres]] 646func.func @signExtendConstant() -> i16 { 647 %c-2 = arith.constant -2 : i8 648 %ext = arith.extsi %c-2 : i8 to i16 649 return %ext : i16 650} 651 652// CHECK-LABEL: @signExtendConstantSplat 653// CHECK: %[[cres:.+]] = arith.constant dense<-2> : vector<4xi16> 654// CHECK: return %[[cres]] 655func.func @signExtendConstantSplat() -> vector<4xi16> { 656 %c-2 = arith.constant -2 : i8 657 %splat = vector.splat %c-2 : vector<4xi8> 658 %ext = arith.extsi %splat : vector<4xi8> to vector<4xi16> 659 return %ext : vector<4xi16> 660} 661 662// CHECK-LABEL: @signExtendConstantVector 663// 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: @unsignedExtendConstant 672// CHECK: %[[cres:.+]] = arith.constant 2 : i16 673// CHECK: return %[[cres]] 674func.func @unsignedExtendConstant() -> i16 { 675 %c2 = arith.constant 2 : i8 676 %ext = arith.extui %c2 : i8 to i16 677 return %ext : i16 678} 679 680// CHECK-LABEL: @unsignedExtendConstantSplat 681// CHECK: %[[cres:.+]] = arith.constant dense<2> : vector<4xi16> 682// CHECK: return %[[cres]] 683func.func @unsignedExtendConstantSplat() -> vector<4xi16> { 684 %c2 = arith.constant 2 : i8 685 %splat = vector.splat %c2 : vector<4xi8> 686 %ext = arith.extui %splat : vector<4xi8> to vector<4xi16> 687 return %ext : vector<4xi16> 688} 689 690// CHECK-LABEL: @unsignedExtendConstantVector 691// 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: @extFPConstant 700// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : f64 701// CHECK: return %[[cres]] 702func.func @extFPConstant() -> f64 { 703 %cst = arith.constant 1.000000e+00 : f32 704 %0 = arith.extf %cst : f32 to f64 705 return %0 : f64 706} 707 708// CHECK-LABEL: @extFPVectorConstant 709// 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// TODO: We should also add a test for not folding arith.extf on information loss. 718// This may happen when extending f8E5M2FNUZ to f16. 719 720// CHECK-LABEL: @truncConstant 721// CHECK: %[[cres:.+]] = arith.constant -2 : i16 722// CHECK: return %[[cres]] 723func.func @truncConstant(%arg0: i8) -> i16 { 724 %c-2 = arith.constant -2 : i32 725 %tr = arith.trunci %c-2 : i32 to i16 726 return %tr : i16 727} 728 729// CHECK-LABEL: @truncExtui 730// CHECK-NOT: trunci 731// CHECK: return %arg0 732func.func @truncExtui(%arg0: i32) -> i32 { 733 %extui = arith.extui %arg0 : i32 to i64 734 %trunci = arith.trunci %extui : i64 to i32 735 return %trunci : i32 736} 737 738// CHECK-LABEL: @truncExtui2 739// CHECK: %[[ARG0:.+]]: i32 740// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : i32 to i16 741// CHECK: return %[[CST:.*]] 742func.func @truncExtui2(%arg0: i32) -> i16 { 743 %extui = arith.extui %arg0 : i32 to i64 744 %trunci = arith.trunci %extui : i64 to i16 745 return %trunci : i16 746} 747 748// CHECK-LABEL: @truncExtui3 749// CHECK: %[[ARG0:.+]]: i8 750// CHECK: %[[CST:.*]] = arith.extui %[[ARG0:.+]] : i8 to i16 751// CHECK: return %[[CST:.*]] : i16 752func.func @truncExtui3(%arg0: i8) -> i16 { 753 %extui = arith.extui %arg0 : i8 to i32 754 %trunci = arith.trunci %extui : i32 to i16 755 return %trunci : i16 756} 757 758// CHECK-LABEL: @truncExtuiVector 759// CHECK: %[[ARG0:.+]]: vector<2xi32> 760// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : vector<2xi32> to vector<2xi16> 761// CHECK: return %[[CST:.*]] 762func.func @truncExtuiVector(%arg0: vector<2xi32>) -> vector<2xi16> { 763 %extsi = arith.extui %arg0 : vector<2xi32> to vector<2xi64> 764 %trunci = arith.trunci %extsi : vector<2xi64> to vector<2xi16> 765 return %trunci : vector<2xi16> 766} 767 768// CHECK-LABEL: @truncExtsi 769// CHECK-NOT: trunci 770// CHECK: return %arg0 771func.func @truncExtsi(%arg0: i32) -> i32 { 772 %extsi = arith.extsi %arg0 : i32 to i64 773 %trunci = arith.trunci %extsi : i64 to i32 774 return %trunci : i32 775} 776 777// CHECK-LABEL: @truncExtsi2 778// CHECK: %[[ARG0:.+]]: i32 779// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : i32 to i16 780// CHECK: return %[[CST:.*]] 781func.func @truncExtsi2(%arg0: i32) -> i16 { 782 %extsi = arith.extsi %arg0 : i32 to i64 783 %trunci = arith.trunci %extsi : i64 to i16 784 return %trunci : i16 785} 786 787// CHECK-LABEL: @truncExtsi3 788// CHECK: %[[ARG0:.+]]: i8 789// CHECK: %[[CST:.*]] = arith.extsi %[[ARG0:.+]] : i8 to i16 790// CHECK: return %[[CST:.*]] : i16 791func.func @truncExtsi3(%arg0: i8) -> i16 { 792 %extsi = arith.extsi %arg0 : i8 to i32 793 %trunci = arith.trunci %extsi : i32 to i16 794 return %trunci : i16 795} 796 797// CHECK-LABEL: @truncExtsiVector 798// CHECK: %[[ARG0:.+]]: vector<2xi32> 799// CHECK: %[[CST:.*]] = arith.trunci %[[ARG0:.+]] : vector<2xi32> to vector<2xi16> 800// CHECK: return %[[CST:.*]] 801func.func @truncExtsiVector(%arg0: vector<2xi32>) -> vector<2xi16> { 802 %extsi = arith.extsi %arg0 : vector<2xi32> to vector<2xi64> 803 %trunci = arith.trunci %extsi : vector<2xi64> to vector<2xi16> 804 return %trunci : vector<2xi16> 805} 806 807// CHECK-LABEL: @truncConstantSplat 808// CHECK: %[[cres:.+]] = arith.constant dense<-2> : vector<4xi8> 809// CHECK: return %[[cres]] 810func.func @truncConstantSplat() -> vector<4xi8> { 811 %c-2 = arith.constant -2 : i16 812 %splat = vector.splat %c-2 : vector<4xi16> 813 %trunc = arith.trunci %splat : vector<4xi16> to vector<4xi8> 814 return %trunc : vector<4xi8> 815} 816 817// CHECK-LABEL: @truncConstantVector 818// CHECK: %[[cres:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi8> 819// CHECK: return %[[cres]] 820func.func @truncConstantVector() -> vector<4xi8> { 821 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi16> 822 %trunc = arith.trunci %vector : vector<4xi16> to vector<4xi8> 823 return %trunc : vector<4xi8> 824} 825 826// CHECK-LABEL: @truncTrunc 827// CHECK: %[[cres:.+]] = arith.trunci %arg0 : i64 to i8 828// CHECK: return %[[cres]] 829func.func @truncTrunc(%arg0: i64) -> i8 { 830 %tr1 = arith.trunci %arg0 : i64 to i32 831 %tr2 = arith.trunci %tr1 : i32 to i8 832 return %tr2 : i8 833} 834 835// CHECK-LABEL: @truncFPConstant 836// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16 837// CHECK: return %[[cres]] 838func.func @truncFPConstant() -> bf16 { 839 %cst = arith.constant 1.000000e+00 : f32 840 %0 = arith.truncf %cst : f32 to bf16 841 return %0 : bf16 842} 843 844// CHECK-LABEL: @truncFPToNearestEvenConstant 845// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16 846// CHECK: return %[[cres]] 847func.func @truncFPToNearestEvenConstant() -> bf16 { 848 %cst = arith.constant 1.000000e+00 : f32 849 %0 = arith.truncf %cst to_nearest_even : f32 to bf16 850 return %0 : bf16 851} 852 853// CHECK-LABEL: @truncFPDownwardConstant 854// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16 855// CHECK: return %[[cres]] 856func.func @truncFPDownwardConstant() -> bf16 { 857 %cst = arith.constant 1.000000e+00 : f32 858 %0 = arith.truncf %cst downward : f32 to bf16 859 return %0 : bf16 860} 861 862// CHECK-LABEL: @truncFPUpwardConstant 863// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16 864// CHECK: return %[[cres]] 865func.func @truncFPUpwardConstant() -> bf16 { 866 %cst = arith.constant 1.000000e+00 : f32 867 %0 = arith.truncf %cst upward : f32 to bf16 868 return %0 : bf16 869} 870 871// CHECK-LABEL: @truncFPTowardZeroConstant 872// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16 873// CHECK: return %[[cres]] 874func.func @truncFPTowardZeroConstant() -> bf16 { 875 %cst = arith.constant 1.000000e+00 : f32 876 %0 = arith.truncf %cst toward_zero : f32 to bf16 877 return %0 : bf16 878} 879 880// CHECK-LABEL: @truncFPToNearestAwayConstant 881// CHECK: %[[cres:.+]] = arith.constant 1.000000e+00 : bf16 882// CHECK: return %[[cres]] 883func.func @truncFPToNearestAwayConstant() -> bf16 { 884 %cst = arith.constant 1.000000e+00 : f32 885 %0 = arith.truncf %cst to_nearest_away : f32 to bf16 886 return %0 : bf16 887} 888 889// CHECK-LABEL: @truncFPVectorConstant 890// CHECK: %[[cres:.+]] = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xbf16> 891// CHECK: return %[[cres]] 892func.func @truncFPVectorConstant() -> vector<2xbf16> { 893 %cst = arith.constant dense<[0.000000e+00, 1.000000e+00]> : vector<2xf32> 894 %0 = arith.truncf %cst : vector<2xf32> to vector<2xbf16> 895 return %0 : vector<2xbf16> 896} 897 898// Test that cases with rounding are NOT propagated 899// CHECK-LABEL: @truncFPConstantRounding 900// CHECK: arith.constant 1.444000e+25 : f32 901// CHECK: truncf 902func.func @truncFPConstantRounding() -> bf16 { 903 %cst = arith.constant 1.444000e+25 : f32 904 %0 = arith.truncf %cst : f32 to bf16 905 return %0 : bf16 906} 907 908// CHECK-LABEL: @tripleAddAdd 909// CHECK: %[[cres:.+]] = arith.constant 59 : index 910// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 911// CHECK: return %[[add]] 912func.func @tripleAddAdd(%arg0: index) -> index { 913 %c17 = arith.constant 17 : index 914 %c42 = arith.constant 42 : index 915 %add1 = arith.addi %c17, %arg0 : index 916 %add2 = arith.addi %c42, %add1 : index 917 return %add2 : index 918} 919 920// CHECK-LABEL: @tripleAddAddOvf1 921// CHECK: %[[cres:.+]] = arith.constant 59 : index 922// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index 923// CHECK: return %[[add]] 924func.func @tripleAddAddOvf1(%arg0: index) -> index { 925 %c17 = arith.constant 17 : index 926 %c42 = arith.constant 42 : index 927 %add1 = arith.addi %c17, %arg0 overflow<nsw, nuw> : index 928 %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index 929 return %add2 : index 930} 931 932// CHECK-LABEL: @tripleAddAddOvf2 933// CHECK: %[[cres:.+]] = arith.constant 59 : index 934// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 935// CHECK: return %[[add]] 936func.func @tripleAddAddOvf2(%arg0: index) -> index { 937 %c17 = arith.constant 17 : index 938 %c42 = arith.constant 42 : index 939 %add1 = arith.addi %c17, %arg0 overflow<nsw> : index 940 %add2 = arith.addi %c42, %add1 overflow<nuw> : index 941 return %add2 : index 942} 943 944 945// CHECK-LABEL: @foldSubXX_tensor 946// CHECK: %[[c0:.+]] = arith.constant dense<0> : tensor<10xi32> 947// CHECK: %[[sub:.+]] = arith.subi 948// CHECK: return %[[c0]], %[[sub]] 949func.func @foldSubXX_tensor(%static : tensor<10xi32>, %dyn : tensor<?x?xi32>) -> (tensor<10xi32>, tensor<?x?xi32>) { 950 %static_sub = arith.subi %static, %static : tensor<10xi32> 951 %dyn_sub = arith.subi %dyn, %dyn : tensor<?x?xi32> 952 return %static_sub, %dyn_sub : tensor<10xi32>, tensor<?x?xi32> 953} 954 955// CHECK-LABEL: @foldSubXX_vector 956// CHECK-DAG: %[[c0:.+]] = arith.constant dense<0> : vector<8xi32> 957// CHECK-DAG: %[[c0_scalable:.+]] = arith.constant dense<0> : vector<[4]xi32> 958// CHECK: return %[[c0]], %[[c0_scalable]] 959func.func @foldSubXX_vector(%static : vector<8xi32>, %dyn : vector<[4]xi32>) -> (vector<8xi32>, vector<[4]xi32>) { 960 %static_sub = arith.subi %static, %static : vector<8xi32> 961 %dyn_sub = arith.subi %dyn, %dyn : vector<[4]xi32> 962 return %static_sub, %dyn_sub : vector<8xi32>, vector<[4]xi32> 963} 964 965// CHECK-LABEL: @tripleAddSub0 966// CHECK: %[[cres:.+]] = arith.constant 59 : index 967// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 968// CHECK: return %[[add]] 969func.func @tripleAddSub0(%arg0: index) -> index { 970 %c17 = arith.constant 17 : index 971 %c42 = arith.constant 42 : index 972 %add1 = arith.subi %c17, %arg0 : index 973 %add2 = arith.addi %c42, %add1 : index 974 return %add2 : index 975} 976 977// CHECK-LABEL: @tripleAddSub0Ovf 978// CHECK: %[[cres:.+]] = arith.constant 59 : index 979// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index 980// CHECK: return %[[add]] 981func.func @tripleAddSub0Ovf(%arg0: index) -> index { 982 %c17 = arith.constant 17 : index 983 %c42 = arith.constant 42 : index 984 %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index 985 %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index 986 return %add2 : index 987} 988 989// CHECK-LABEL: @tripleAddSub1 990// CHECK: %[[cres:.+]] = arith.constant 25 : index 991// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 992// CHECK: return %[[add]] 993func.func @tripleAddSub1(%arg0: index) -> index { 994 %c17 = arith.constant 17 : index 995 %c42 = arith.constant 42 : index 996 %add1 = arith.subi %arg0, %c17 : index 997 %add2 = arith.addi %c42, %add1 : index 998 return %add2 : index 999} 1000 1001// CHECK-LABEL: @tripleAddSub1Ovf 1002// CHECK: %[[cres:.+]] = arith.constant 25 : index 1003// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index 1004// CHECK: return %[[add]] 1005func.func @tripleAddSub1Ovf(%arg0: index) -> index { 1006 %c17 = arith.constant 17 : index 1007 %c42 = arith.constant 42 : index 1008 %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index 1009 %add2 = arith.addi %c42, %add1 overflow<nsw, nuw> : index 1010 return %add2 : index 1011} 1012 1013// CHECK-LABEL: @tripleSubAdd0 1014// CHECK: %[[cres:.+]] = arith.constant 25 : index 1015// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 1016// CHECK: return %[[add]] 1017func.func @tripleSubAdd0(%arg0: index) -> index { 1018 %c17 = arith.constant 17 : index 1019 %c42 = arith.constant 42 : index 1020 %add1 = arith.addi %c17, %arg0 : index 1021 %add2 = arith.subi %c42, %add1 : index 1022 return %add2 : index 1023} 1024 1025// CHECK-LABEL: @tripleSubAdd0Ovf 1026// CHECK: %[[cres:.+]] = arith.constant 25 : index 1027// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index 1028// CHECK: return %[[add]] 1029func.func @tripleSubAdd0Ovf(%arg0: index) -> index { 1030 %c17 = arith.constant 17 : index 1031 %c42 = arith.constant 42 : index 1032 %add1 = arith.addi %c17, %arg0 overflow<nsw, nuw> : index 1033 %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index 1034 return %add2 : index 1035} 1036 1037// CHECK-LABEL: @tripleSubAdd1 1038// CHECK: %[[cres:.+]] = arith.constant -25 : index 1039// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 1040// CHECK: return %[[add]] 1041func.func @tripleSubAdd1(%arg0: index) -> index { 1042 %c17 = arith.constant 17 : index 1043 %c42 = arith.constant 42 : index 1044 %add1 = arith.addi %c17, %arg0 : index 1045 %add2 = arith.subi %add1, %c42 : index 1046 return %add2 : index 1047} 1048 1049// CHECK-LABEL: @subSub0 1050// CHECK: %[[c0:.+]] = arith.constant 0 : index 1051// CHECK: %[[add:.+]] = arith.subi %[[c0]], %arg1 : index 1052// CHECK: return %[[add]] 1053func.func @subSub0(%arg0: index, %arg1: index) -> index { 1054 %sub1 = arith.subi %arg0, %arg1 : index 1055 %sub2 = arith.subi %sub1, %arg0 : index 1056 return %sub2 : index 1057} 1058 1059// CHECK-LABEL: @subSub0Ovf 1060// CHECK: %[[c0:.+]] = arith.constant 0 : index 1061// CHECK: %[[add:.+]] = arith.subi %[[c0]], %arg1 overflow<nsw, nuw> : index 1062// CHECK: return %[[add]] 1063func.func @subSub0Ovf(%arg0: index, %arg1: index) -> index { 1064 %sub1 = arith.subi %arg0, %arg1 overflow<nsw, nuw> : index 1065 %sub2 = arith.subi %sub1, %arg0 overflow<nsw, nuw> : index 1066 return %sub2 : index 1067} 1068 1069// CHECK-LABEL: @tripleSubSub0 1070// CHECK: %[[cres:.+]] = arith.constant 25 : index 1071// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] : index 1072// CHECK: return %[[add]] 1073func.func @tripleSubSub0(%arg0: index) -> index { 1074 %c17 = arith.constant 17 : index 1075 %c42 = arith.constant 42 : index 1076 %add1 = arith.subi %c17, %arg0 : index 1077 %add2 = arith.subi %c42, %add1 : index 1078 return %add2 : index 1079} 1080 1081// CHECK-LABEL: @tripleSubSub0Ovf 1082// CHECK: %[[cres:.+]] = arith.constant 25 : index 1083// CHECK: %[[add:.+]] = arith.addi %arg0, %[[cres]] overflow<nsw, nuw> : index 1084// CHECK: return %[[add]] 1085func.func @tripleSubSub0Ovf(%arg0: index) -> index { 1086 %c17 = arith.constant 17 : index 1087 %c42 = arith.constant 42 : index 1088 %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index 1089 %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index 1090 return %add2 : index 1091} 1092 1093 1094// CHECK-LABEL: @tripleSubSub1 1095// CHECK: %[[cres:.+]] = arith.constant -25 : index 1096// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 1097// CHECK: return %[[add]] 1098func.func @tripleSubSub1(%arg0: index) -> index { 1099 %c17 = arith.constant 17 : index 1100 %c42 = arith.constant 42 : index 1101 %add1 = arith.subi %c17, %arg0 : index 1102 %add2 = arith.subi %add1, %c42 : index 1103 return %add2 : index 1104} 1105 1106// CHECK-LABEL: @tripleSubSub1Ovf 1107// CHECK: %[[cres:.+]] = arith.constant -25 : index 1108// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index 1109// CHECK: return %[[add]] 1110func.func @tripleSubSub1Ovf(%arg0: index) -> index { 1111 %c17 = arith.constant 17 : index 1112 %c42 = arith.constant 42 : index 1113 %add1 = arith.subi %c17, %arg0 overflow<nsw, nuw> : index 1114 %add2 = arith.subi %add1, %c42 overflow<nsw, nuw> : index 1115 return %add2 : index 1116} 1117 1118// CHECK-LABEL: @tripleSubSub2 1119// CHECK: %[[cres:.+]] = arith.constant 59 : index 1120// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 : index 1121// CHECK: return %[[add]] 1122func.func @tripleSubSub2(%arg0: index) -> index { 1123 %c17 = arith.constant 17 : index 1124 %c42 = arith.constant 42 : index 1125 %add1 = arith.subi %arg0, %c17 : index 1126 %add2 = arith.subi %c42, %add1 : index 1127 return %add2 : index 1128} 1129 1130// CHECK-LABEL: @tripleSubSub2Ovf 1131// CHECK: %[[cres:.+]] = arith.constant 59 : index 1132// CHECK: %[[add:.+]] = arith.subi %[[cres]], %arg0 overflow<nsw, nuw> : index 1133// CHECK: return %[[add]] 1134func.func @tripleSubSub2Ovf(%arg0: index) -> index { 1135 %c17 = arith.constant 17 : index 1136 %c42 = arith.constant 42 : index 1137 %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index 1138 %add2 = arith.subi %c42, %add1 overflow<nsw, nuw> : index 1139 return %add2 : index 1140} 1141 1142// CHECK-LABEL: @tripleSubSub3 1143// CHECK: %[[cres:.+]] = arith.constant 59 : index 1144// CHECK: %[[add:.+]] = arith.subi %arg0, %[[cres]] : index 1145// CHECK: return %[[add]] 1146func.func @tripleSubSub3(%arg0: index) -> index { 1147 %c17 = arith.constant 17 : index 1148 %c42 = arith.constant 42 : index 1149 %add1 = arith.subi %arg0, %c17 : index 1150 %add2 = arith.subi %add1, %c42 : index 1151 return %add2 : index 1152} 1153 1154// CHECK-LABEL: @tripleSubSub3Ovf 1155// CHECK: %[[cres:.+]] = arith.constant 59 : index 1156// CHECK: %[[add:.+]] = arith.subi %arg0, %[[cres]] overflow<nsw, nuw> : index 1157// CHECK: return %[[add]] 1158func.func @tripleSubSub3Ovf(%arg0: index) -> index { 1159 %c17 = arith.constant 17 : index 1160 %c42 = arith.constant 42 : index 1161 %add1 = arith.subi %arg0, %c17 overflow<nsw, nuw> : index 1162 %add2 = arith.subi %add1, %c42 overflow<nsw, nuw> : index 1163 return %add2 : index 1164} 1165 1166// CHECK-LABEL: @subAdd1 1167// CHECK-NEXT: return %arg0 1168func.func @subAdd1(%arg0: index, %arg1 : index) -> index { 1169 %add = arith.addi %arg0, %arg1 : index 1170 %sub = arith.subi %add, %arg1 : index 1171 return %sub : index 1172} 1173 1174// CHECK-LABEL: @subAdd2 1175// CHECK-NEXT: return %arg1 1176func.func @subAdd2(%arg0: index, %arg1 : index) -> index { 1177 %add = arith.addi %arg0, %arg1 : index 1178 %sub = arith.subi %add, %arg0 : index 1179 return %sub : index 1180} 1181 1182// CHECK-LABEL: @doubleAddSub1 1183// CHECK-NEXT: return %arg0 1184func.func @doubleAddSub1(%arg0: index, %arg1 : index) -> index { 1185 %sub = arith.subi %arg0, %arg1 : index 1186 %add = arith.addi %sub, %arg1 : index 1187 return %add : index 1188} 1189 1190// CHECK-LABEL: @doubleAddSub2 1191// CHECK-NEXT: return %arg0 1192func.func @doubleAddSub2(%arg0: index, %arg1 : index) -> index { 1193 %sub = arith.subi %arg0, %arg1 : index 1194 %add = arith.addi %arg1, %sub : index 1195 return %add : index 1196} 1197 1198// CHECK-LABEL: @tripleMulIMulIIndex 1199// CHECK: %[[cres:.+]] = arith.constant 15 : index 1200// CHECK: %[[muli:.+]] = arith.muli %arg0, %[[cres]] : index 1201// CHECK: return %[[muli]] 1202func.func @tripleMulIMulIIndex(%arg0: index) -> index { 1203 %c3 = arith.constant 3 : index 1204 %c5 = arith.constant 5 : index 1205 %mul1 = arith.muli %arg0, %c3 : index 1206 %mul2 = arith.muli %mul1, %c5 : index 1207 return %mul2 : index 1208} 1209 1210// CHECK-LABEL: @tripleMulIMulII32 1211// CHECK: %[[cres:.+]] = arith.constant -21 : i32 1212// CHECK: %[[muli:.+]] = arith.muli %arg0, %[[cres]] : i32 1213// CHECK: return %[[muli]] 1214func.func @tripleMulIMulII32(%arg0: i32) -> i32 { 1215 %c_n3 = arith.constant -3 : i32 1216 %c7 = arith.constant 7 : i32 1217 %mul1 = arith.muli %arg0, %c_n3 : i32 1218 %mul2 = arith.muli %mul1, %c7 : i32 1219 return %mul2 : i32 1220} 1221 1222// CHECK-LABEL: @tripleMulLargeInt 1223// CHECK: %[[cres:.+]] = arith.constant 3618502788666131213697322783095070105623107215331596699973092056135872020482 : i256 1224// CHECK: %[[addi:.+]] = arith.addi %arg0, %[[cres]] : i256 1225// CHECK: return %[[addi]] 1226func.func @tripleMulLargeInt(%arg0: i256) -> i256 { 1227 %0 = arith.constant 3618502788666131213697322783095070105623107215331596699973092056135872020481 : i256 1228 %1 = arith.constant 1 : i256 1229 %2 = arith.addi %arg0, %0 : i256 1230 %3 = arith.addi %2, %1 : i256 1231 return %3 : i256 1232} 1233 1234// CHECK-LABEL: @addiMuliToSubiRhsI32 1235// CHECK-SAME: (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32) 1236// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : i32 1237// CHECK: return %[[SUB]] 1238func.func @addiMuliToSubiRhsI32(%arg0: i32, %arg1: i32) -> i32 { 1239 %c-1 = arith.constant -1 : i32 1240 %neg = arith.muli %arg1, %c-1 : i32 1241 %add = arith.addi %arg0, %neg : i32 1242 return %add : i32 1243} 1244 1245// CHECK-LABEL: @addiMuliToSubiRhsIndex 1246// CHECK-SAME: (%[[ARG0:.+]]: index, %[[ARG1:.+]]: index) 1247// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : index 1248// CHECK: return %[[SUB]] 1249func.func @addiMuliToSubiRhsIndex(%arg0: index, %arg1: index) -> index { 1250 %c-1 = arith.constant -1 : index 1251 %neg = arith.muli %arg1, %c-1 : index 1252 %add = arith.addi %arg0, %neg : index 1253 return %add : index 1254} 1255 1256// CHECK-LABEL: @addiMuliToSubiRhsVector 1257// CHECK-SAME: (%[[ARG0:.+]]: vector<3xi64>, %[[ARG1:.+]]: vector<3xi64>) 1258// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : vector<3xi64> 1259// CHECK: return %[[SUB]] 1260func.func @addiMuliToSubiRhsVector(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi64> { 1261 %c-1 = arith.constant dense<-1> : vector<3xi64> 1262 %neg = arith.muli %arg1, %c-1 : vector<3xi64> 1263 %add = arith.addi %arg0, %neg : vector<3xi64> 1264 return %add : vector<3xi64> 1265} 1266 1267// CHECK-LABEL: @addiMuliToSubiLhsI32 1268// CHECK-SAME: (%[[ARG0:.+]]: i32, %[[ARG1:.+]]: i32) 1269// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : i32 1270// CHECK: return %[[SUB]] 1271func.func @addiMuliToSubiLhsI32(%arg0: i32, %arg1: i32) -> i32 { 1272 %c-1 = arith.constant -1 : i32 1273 %neg = arith.muli %arg1, %c-1 : i32 1274 %add = arith.addi %neg, %arg0 : i32 1275 return %add : i32 1276} 1277 1278// CHECK-LABEL: @addiMuliToSubiLhsIndex 1279// CHECK-SAME: (%[[ARG0:.+]]: index, %[[ARG1:.+]]: index) 1280// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : index 1281// CHECK: return %[[SUB]] 1282func.func @addiMuliToSubiLhsIndex(%arg0: index, %arg1: index) -> index { 1283 %c-1 = arith.constant -1 : index 1284 %neg = arith.muli %arg1, %c-1 : index 1285 %add = arith.addi %neg, %arg0 : index 1286 return %add : index 1287} 1288 1289// CHECK-LABEL: @addiMuliToSubiLhsVector 1290// CHECK-SAME: (%[[ARG0:.+]]: vector<3xi64>, %[[ARG1:.+]]: vector<3xi64>) 1291// CHECK: %[[SUB:.+]] = arith.subi %[[ARG0]], %[[ARG1]] : vector<3xi64> 1292// CHECK: return %[[SUB]] 1293func.func @addiMuliToSubiLhsVector(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi64> { 1294 %c-1 = arith.constant dense<-1> : vector<3xi64> 1295 %neg = arith.muli %arg1, %c-1 : vector<3xi64> 1296 %add = arith.addi %neg, %arg0 : vector<3xi64> 1297 return %add : vector<3xi64> 1298} 1299 1300// CHECK-LABEL: @adduiExtendedZeroRhs 1301// CHECK-NEXT: %[[false:.+]] = arith.constant false 1302// CHECK-NEXT: return %arg0, %[[false]] 1303func.func @adduiExtendedZeroRhs(%arg0: i32) -> (i32, i1) { 1304 %zero = arith.constant 0 : i32 1305 %sum, %overflow = arith.addui_extended %arg0, %zero: i32, i1 1306 return %sum, %overflow : i32, i1 1307} 1308 1309// CHECK-LABEL: @adduiExtendedZeroRhsSplat 1310// CHECK-NEXT: %[[false:.+]] = arith.constant dense<false> : vector<4xi1> 1311// CHECK-NEXT: return %arg0, %[[false]] 1312func.func @adduiExtendedZeroRhsSplat(%arg0: vector<4xi32>) -> (vector<4xi32>, vector<4xi1>) { 1313 %zero = arith.constant dense<0> : vector<4xi32> 1314 %sum, %overflow = arith.addui_extended %arg0, %zero: vector<4xi32>, vector<4xi1> 1315 return %sum, %overflow : vector<4xi32>, vector<4xi1> 1316} 1317 1318// CHECK-LABEL: @adduiExtendedZeroLhs 1319// CHECK-NEXT: %[[false:.+]] = arith.constant false 1320// CHECK-NEXT: return %arg0, %[[false]] 1321func.func @adduiExtendedZeroLhs(%arg0: i32) -> (i32, i1) { 1322 %zero = arith.constant 0 : i32 1323 %sum, %overflow = arith.addui_extended %zero, %arg0: i32, i1 1324 return %sum, %overflow : i32, i1 1325} 1326 1327// CHECK-LABEL: @adduiExtendedUnusedOverflowScalar 1328// CHECK-SAME: (%[[LHS:.+]]: i32, %[[RHS:.+]]: i32) -> i32 1329// CHECK-NEXT: %[[RES:.+]] = arith.addi %[[LHS]], %[[RHS]] : i32 1330// CHECK-NEXT: return %[[RES]] : i32 1331func.func @adduiExtendedUnusedOverflowScalar(%arg0: i32, %arg1: i32) -> i32 { 1332 %sum, %overflow = arith.addui_extended %arg0, %arg1: i32, i1 1333 return %sum : i32 1334} 1335 1336// CHECK-LABEL: @adduiExtendedUnusedOverflowVector 1337// CHECK-SAME: (%[[LHS:.+]]: vector<3xi32>, %[[RHS:.+]]: vector<3xi32>) -> vector<3xi32> 1338// CHECK-NEXT: %[[RES:.+]] = arith.addi %[[LHS]], %[[RHS]] : vector<3xi32> 1339// CHECK-NEXT: return %[[RES]] : vector<3xi32> 1340func.func @adduiExtendedUnusedOverflowVector(%arg0: vector<3xi32>, %arg1: vector<3xi32>) -> vector<3xi32> { 1341 %sum, %overflow = arith.addui_extended %arg0, %arg1: vector<3xi32>, vector<3xi1> 1342 return %sum : vector<3xi32> 1343} 1344 1345// CHECK-LABEL: @adduiExtendedConstants 1346// CHECK-DAG: %[[false:.+]] = arith.constant false 1347// CHECK-DAG: %[[c50:.+]] = arith.constant 50 : i32 1348// CHECK-NEXT: return %[[c50]], %[[false]] 1349func.func @adduiExtendedConstants() -> (i32, i1) { 1350 %c13 = arith.constant 13 : i32 1351 %c37 = arith.constant 37 : i32 1352 %sum, %overflow = arith.addui_extended %c13, %c37: i32, i1 1353 return %sum, %overflow : i32, i1 1354} 1355 1356// CHECK-LABEL: @adduiExtendedConstantsOverflow1 1357// CHECK-DAG: %[[true:.+]] = arith.constant true 1358// CHECK-DAG: %[[c0:.+]] = arith.constant 0 : i32 1359// CHECK-NEXT: return %[[c0]], %[[true]] 1360func.func @adduiExtendedConstantsOverflow1() -> (i32, i1) { 1361 %max = arith.constant 4294967295 : i32 1362 %c1 = arith.constant 1 : i32 1363 %sum, %overflow = arith.addui_extended %max, %c1: i32, i1 1364 return %sum, %overflow : i32, i1 1365} 1366 1367// CHECK-LABEL: @adduiExtendedConstantsOverflow2 1368// CHECK-DAG: %[[true:.+]] = arith.constant true 1369// CHECK-DAG: %[[c_2:.+]] = arith.constant -2 : i32 1370// CHECK-NEXT: return %[[c_2]], %[[true]] 1371func.func @adduiExtendedConstantsOverflow2() -> (i32, i1) { 1372 %max = arith.constant 4294967295 : i32 1373 %sum, %overflow = arith.addui_extended %max, %max: i32, i1 1374 return %sum, %overflow : i32, i1 1375} 1376 1377// CHECK-LABEL: @adduiExtendedConstantsOverflowVector 1378// CHECK-DAG: %[[sum:.+]] = arith.constant dense<[1, 6, 2, 14]> : vector<4xi32> 1379// CHECK-DAG: %[[overflow:.+]] = arith.constant dense<[false, false, true, false]> : vector<4xi1> 1380// CHECK-NEXT: return %[[sum]], %[[overflow]] 1381func.func @adduiExtendedConstantsOverflowVector() -> (vector<4xi32>, vector<4xi1>) { 1382 %v1 = arith.constant dense<[1, 3, 3, 7]> : vector<4xi32> 1383 %v2 = arith.constant dense<[0, 3, 4294967295, 7]> : vector<4xi32> 1384 %sum, %overflow = arith.addui_extended %v1, %v2 : vector<4xi32>, vector<4xi1> 1385 return %sum, %overflow : vector<4xi32>, vector<4xi1> 1386} 1387 1388// CHECK-LABEL: @adduiExtendedConstantsSplatVector 1389// CHECK-DAG: %[[sum:.+]] = arith.constant dense<3> : vector<4xi32> 1390// CHECK-DAG: %[[overflow:.+]] = arith.constant dense<false> : vector<4xi1> 1391// CHECK-NEXT: return %[[sum]], %[[overflow]] 1392func.func @adduiExtendedConstantsSplatVector() -> (vector<4xi32>, vector<4xi1>) { 1393 %v1 = arith.constant dense<1> : vector<4xi32> 1394 %v2 = arith.constant dense<2> : vector<4xi32> 1395 %sum, %overflow = arith.addui_extended %v1, %v2 : vector<4xi32>, vector<4xi1> 1396 return %sum, %overflow : vector<4xi32>, vector<4xi1> 1397} 1398 1399// CHECK-LABEL: @mulsiExtendedZeroRhs 1400// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i32 1401// CHECK-NEXT: return %[[zero]], %[[zero]] 1402func.func @mulsiExtendedZeroRhs(%arg0: i32) -> (i32, i32) { 1403 %zero = arith.constant 0 : i32 1404 %low, %high = arith.mulsi_extended %arg0, %zero: i32 1405 return %low, %high : i32, i32 1406} 1407 1408// CHECK-LABEL: @mulsiExtendedZeroRhsSplat 1409// CHECK-NEXT: %[[zero:.+]] = arith.constant dense<0> : vector<3xi32> 1410// CHECK-NEXT: return %[[zero]], %[[zero]] 1411func.func @mulsiExtendedZeroRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) { 1412 %zero = arith.constant dense<0> : vector<3xi32> 1413 %low, %high = arith.mulsi_extended %arg0, %zero: vector<3xi32> 1414 return %low, %high : vector<3xi32>, vector<3xi32> 1415} 1416 1417// CHECK-LABEL: @mulsiExtendedZeroLhs 1418// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i32 1419// CHECK-NEXT: return %[[zero]], %[[zero]] 1420func.func @mulsiExtendedZeroLhs(%arg0: i32) -> (i32, i32) { 1421 %zero = arith.constant 0 : i32 1422 %low, %high = arith.mulsi_extended %zero, %arg0: i32 1423 return %low, %high : i32, i32 1424} 1425 1426// CHECK-LABEL: @mulsiExtendedOneRhs 1427// CHECK-SAME: (%[[ARG:.+]]: i32) -> (i32, i32) 1428// CHECK-NEXT: %[[C0:.+]] = arith.constant 0 : i32 1429// CHECK-NEXT: %[[CMP:.+]] = arith.cmpi slt, %[[ARG]], %[[C0]] : i32 1430// CHECK-NEXT: %[[EXT:.+]] = arith.extsi %[[CMP]] : i1 to i32 1431// CHECK-NEXT: return %[[ARG]], %[[EXT]] : i32, i32 1432func.func @mulsiExtendedOneRhs(%arg0: i32) -> (i32, i32) { 1433 %one = arith.constant 1 : i32 1434 %low, %high = arith.mulsi_extended %arg0, %one: i32 1435 return %low, %high : i32, i32 1436} 1437 1438// CHECK-LABEL: @mulsiExtendedOneRhsSplat 1439// CHECK-SAME: (%[[ARG:.+]]: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) 1440// CHECK-NEXT: %[[C0:.+]] = arith.constant dense<0> : vector<3xi32> 1441// CHECK-NEXT: %[[CMP:.+]] = arith.cmpi slt, %[[ARG]], %[[C0]] : vector<3xi32> 1442// CHECK-NEXT: %[[EXT:.+]] = arith.extsi %[[CMP]] : vector<3xi1> to vector<3xi32> 1443// CHECK-NEXT: return %[[ARG]], %[[EXT]] : vector<3xi32>, vector<3xi32> 1444func.func @mulsiExtendedOneRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) { 1445 %one = arith.constant dense<1> : vector<3xi32> 1446 %low, %high = arith.mulsi_extended %arg0, %one: vector<3xi32> 1447 return %low, %high : vector<3xi32>, vector<3xi32> 1448} 1449 1450// CHECK-LABEL: @mulsiExtendedOneRhsI1 1451// CHECK-SAME: (%[[ARG:.+]]: i1) -> (i1, i1) 1452// CHECK-NEXT: %[[T:.+]] = arith.constant true 1453// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[ARG]], %[[T]] : i1 1454// CHECK-NEXT: return %[[LOW]], %[[HIGH]] : i1, i1 1455func.func @mulsiExtendedOneRhsI1(%arg0: i1) -> (i1, i1) { 1456 %one = arith.constant true 1457 %low, %high = arith.mulsi_extended %arg0, %one: i1 1458 return %low, %high : i1, i1 1459} 1460 1461// CHECK-LABEL: @mulsiExtendedOneRhsSplatI1 1462// CHECK-SAME: (%[[ARG:.+]]: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>) 1463// CHECK-NEXT: %[[TS:.+]] = arith.constant dense<true> : vector<3xi1> 1464// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[ARG]], %[[TS]] : vector<3xi1> 1465// CHECK-NEXT: return %[[LOW]], %[[HIGH]] : vector<3xi1>, vector<3xi1> 1466func.func @mulsiExtendedOneRhsSplatI1(%arg0: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>) { 1467 %one = arith.constant dense<true> : vector<3xi1> 1468 %low, %high = arith.mulsi_extended %arg0, %one: vector<3xi1> 1469 return %low, %high : vector<3xi1>, vector<3xi1> 1470} 1471 1472// CHECK-LABEL: @mulsiExtendedUnusedHigh 1473// CHECK-SAME: (%[[ARG:.+]]: i32) -> i32 1474// CHECK-NEXT: %[[RES:.+]] = arith.muli %[[ARG]], %[[ARG]] : i32 1475// CHECK-NEXT: return %[[RES]] 1476func.func @mulsiExtendedUnusedHigh(%arg0: i32) -> i32 { 1477 %low, %high = arith.mulsi_extended %arg0, %arg0: i32 1478 return %low : i32 1479} 1480 1481// CHECK-LABEL: @mulsiExtendedScalarConstants 1482// CHECK-DAG: %[[c27:.+]] = arith.constant 27 : i8 1483// CHECK-DAG: %[[c_n3:.+]] = arith.constant -3 : i8 1484// CHECK-NEXT: return %[[c27]], %[[c_n3]] 1485func.func @mulsiExtendedScalarConstants() -> (i8, i8) { 1486 %c57 = arith.constant 57 : i8 1487 %c_n13 = arith.constant -13 : i8 1488 %low, %high = arith.mulsi_extended %c57, %c_n13: i8 1489 return %low, %high : i8, i8 1490} 1491 1492// CHECK-LABEL: @mulsiExtendedVectorConstants 1493// CHECK-DAG: %[[cstLo:.+]] = arith.constant dense<[65, 79, 34]> : vector<3xi8> 1494// CHECK-DAG: %[[cstHi:.+]] = arith.constant dense<[0, 14, 0]> : vector<3xi8> 1495// CHECK-NEXT: return %[[cstLo]], %[[cstHi]] 1496func.func @mulsiExtendedVectorConstants() -> (vector<3xi8>, vector<3xi8>) { 1497 %cstA = arith.constant dense<[5, 37, -17]> : vector<3xi8> 1498 %cstB = arith.constant dense<[13, 99, -2]> : vector<3xi8> 1499 %low, %high = arith.mulsi_extended %cstA, %cstB: vector<3xi8> 1500 return %low, %high : vector<3xi8>, vector<3xi8> 1501} 1502 1503// CHECK-LABEL: @muluiExtendedZeroRhs 1504// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i32 1505// CHECK-NEXT: return %[[zero]], %[[zero]] 1506func.func @muluiExtendedZeroRhs(%arg0: i32) -> (i32, i32) { 1507 %zero = arith.constant 0 : i32 1508 %low, %high = arith.mului_extended %arg0, %zero: i32 1509 return %low, %high : i32, i32 1510} 1511 1512// CHECK-LABEL: @muluiExtendedZeroRhsSplat 1513// CHECK-NEXT: %[[zero:.+]] = arith.constant dense<0> : vector<3xi32> 1514// CHECK-NEXT: return %[[zero]], %[[zero]] 1515func.func @muluiExtendedZeroRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) { 1516 %zero = arith.constant dense<0> : vector<3xi32> 1517 %low, %high = arith.mului_extended %arg0, %zero: vector<3xi32> 1518 return %low, %high : vector<3xi32>, vector<3xi32> 1519} 1520 1521// CHECK-LABEL: @muluiExtendedZeroLhs 1522// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i32 1523// CHECK-NEXT: return %[[zero]], %[[zero]] 1524func.func @muluiExtendedZeroLhs(%arg0: i32) -> (i32, i32) { 1525 %zero = arith.constant 0 : i32 1526 %low, %high = arith.mului_extended %zero, %arg0: i32 1527 return %low, %high : i32, i32 1528} 1529 1530// CHECK-LABEL: @muluiExtendedOneRhs 1531// CHECK-SAME: (%[[ARG:.+]]: i32) -> (i32, i32) 1532// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i32 1533// CHECK-NEXT: return %[[ARG]], %[[zero]] 1534func.func @muluiExtendedOneRhs(%arg0: i32) -> (i32, i32) { 1535 %zero = arith.constant 1 : i32 1536 %low, %high = arith.mului_extended %arg0, %zero: i32 1537 return %low, %high : i32, i32 1538} 1539 1540// CHECK-LABEL: @muluiExtendedOneRhsSplat 1541// CHECK-SAME: (%[[ARG:.+]]: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) 1542// CHECK-NEXT: %[[zero:.+]] = arith.constant dense<0> : vector<3xi32> 1543// CHECK-NEXT: return %[[ARG]], %[[zero]] 1544func.func @muluiExtendedOneRhsSplat(%arg0: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) { 1545 %zero = arith.constant dense<1> : vector<3xi32> 1546 %low, %high = arith.mului_extended %arg0, %zero: vector<3xi32> 1547 return %low, %high : vector<3xi32>, vector<3xi32> 1548} 1549 1550// CHECK-LABEL: @muluiExtendedOneLhs 1551// CHECK-SAME: (%[[ARG:.+]]: i32) -> (i32, i32) 1552// CHECK-NEXT: %[[zero:.+]] = arith.constant 0 : i32 1553// CHECK-NEXT: return %[[ARG]], %[[zero]] 1554func.func @muluiExtendedOneLhs(%arg0: i32) -> (i32, i32) { 1555 %zero = arith.constant 1 : i32 1556 %low, %high = arith.mului_extended %zero, %arg0: i32 1557 return %low, %high : i32, i32 1558} 1559 1560// CHECK-LABEL: @muluiExtendedUnusedHigh 1561// CHECK-SAME: (%[[ARG:.+]]: i32) -> i32 1562// CHECK-NEXT: %[[RES:.+]] = arith.muli %[[ARG]], %[[ARG]] : i32 1563// CHECK-NEXT: return %[[RES]] 1564func.func @muluiExtendedUnusedHigh(%arg0: i32) -> i32 { 1565 %low, %high = arith.mului_extended %arg0, %arg0: i32 1566 return %low : i32 1567} 1568 1569// This shouldn't be folded. 1570// CHECK-LABEL: @muluiExtendedUnusedLow 1571// CHECK-SAME: (%[[ARG:.+]]: i32) -> i32 1572// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mului_extended %[[ARG]], %[[ARG]] : i32 1573// CHECK-NEXT: return %[[HIGH]] 1574func.func @muluiExtendedUnusedLow(%arg0: i32) -> i32 { 1575 %low, %high = arith.mului_extended %arg0, %arg0: i32 1576 return %high : i32 1577} 1578 1579// CHECK-LABEL: @muluiExtendedScalarConstants 1580// CHECK-DAG: %[[c157:.+]] = arith.constant -99 : i8 1581// CHECK-DAG: %[[c29:.+]] = arith.constant 29 : i8 1582// CHECK-NEXT: return %[[c157]], %[[c29]] 1583func.func @muluiExtendedScalarConstants() -> (i8, i8) { 1584 %c57 = arith.constant 57 : i8 1585 %c133 = arith.constant 133 : i8 1586 %low, %high = arith.mului_extended %c57, %c133: i8 // = 7581 1587 return %low, %high : i8, i8 1588} 1589 1590// CHECK-LABEL: @muluiExtendedVectorConstants 1591// CHECK-DAG: %[[cstLo:.+]] = arith.constant dense<[65, 79, 1]> : vector<3xi8> 1592// CHECK-DAG: %[[cstHi:.+]] = arith.constant dense<[0, 14, -2]> : vector<3xi8> 1593// CHECK-NEXT: return %[[cstLo]], %[[cstHi]] 1594func.func @muluiExtendedVectorConstants() -> (vector<3xi8>, vector<3xi8>) { 1595 %cstA = arith.constant dense<[5, 37, 255]> : vector<3xi8> 1596 %cstB = arith.constant dense<[13, 99, 255]> : vector<3xi8> 1597 %low, %high = arith.mului_extended %cstA, %cstB: vector<3xi8> 1598 return %low, %high : vector<3xi8>, vector<3xi8> 1599} 1600 1601// CHECK-LABEL: @notCmpEQ 1602// CHECK: %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 1603// CHECK: return %[[cres]] 1604func.func @notCmpEQ(%arg0: i8, %arg1: i8) -> i1 { 1605 %true = arith.constant true 1606 %cmp = arith.cmpi "eq", %arg0, %arg1 : i8 1607 %ncmp = arith.xori %cmp, %true : i1 1608 return %ncmp : i1 1609} 1610 1611// CHECK-LABEL: @notCmpEQ2 1612// CHECK: %[[cres:.+]] = arith.cmpi ne, %arg0, %arg1 : i8 1613// CHECK: return %[[cres]] 1614func.func @notCmpEQ2(%arg0: i8, %arg1: i8) -> i1 { 1615 %true = arith.constant true 1616 %cmp = arith.cmpi "eq", %arg0, %arg1 : i8 1617 %ncmp = arith.xori %true, %cmp : i1 1618 return %ncmp : i1 1619} 1620 1621// CHECK-LABEL: @notCmpNE 1622// CHECK: %[[cres:.+]] = arith.cmpi eq, %arg0, %arg1 : i8 1623// CHECK: return %[[cres]] 1624func.func @notCmpNE(%arg0: i8, %arg1: i8) -> i1 { 1625 %true = arith.constant true 1626 %cmp = arith.cmpi "ne", %arg0, %arg1 : i8 1627 %ncmp = arith.xori %cmp, %true : i1 1628 return %ncmp : i1 1629} 1630 1631// CHECK-LABEL: @notCmpSLT 1632// CHECK: %[[cres:.+]] = arith.cmpi sge, %arg0, %arg1 : i8 1633// CHECK: return %[[cres]] 1634func.func @notCmpSLT(%arg0: i8, %arg1: i8) -> i1 { 1635 %true = arith.constant true 1636 %cmp = arith.cmpi "slt", %arg0, %arg1 : i8 1637 %ncmp = arith.xori %cmp, %true : i1 1638 return %ncmp : i1 1639} 1640 1641// CHECK-LABEL: @notCmpSLE 1642// CHECK: %[[cres:.+]] = arith.cmpi sgt, %arg0, %arg1 : i8 1643// CHECK: return %[[cres]] 1644func.func @notCmpSLE(%arg0: i8, %arg1: i8) -> i1 { 1645 %true = arith.constant true 1646 %cmp = arith.cmpi "sle", %arg0, %arg1 : i8 1647 %ncmp = arith.xori %cmp, %true : i1 1648 return %ncmp : i1 1649} 1650 1651// CHECK-LABEL: @notCmpSGT 1652// CHECK: %[[cres:.+]] = arith.cmpi sle, %arg0, %arg1 : i8 1653// CHECK: return %[[cres]] 1654func.func @notCmpSGT(%arg0: i8, %arg1: i8) -> i1 { 1655 %true = arith.constant true 1656 %cmp = arith.cmpi "sgt", %arg0, %arg1 : i8 1657 %ncmp = arith.xori %cmp, %true : i1 1658 return %ncmp : i1 1659} 1660 1661// CHECK-LABEL: @notCmpSGE 1662// CHECK: %[[cres:.+]] = arith.cmpi slt, %arg0, %arg1 : i8 1663// CHECK: return %[[cres]] 1664func.func @notCmpSGE(%arg0: i8, %arg1: i8) -> i1 { 1665 %true = arith.constant true 1666 %cmp = arith.cmpi "sge", %arg0, %arg1 : i8 1667 %ncmp = arith.xori %cmp, %true : i1 1668 return %ncmp : i1 1669} 1670 1671// CHECK-LABEL: @notCmpULT 1672// CHECK: %[[cres:.+]] = arith.cmpi uge, %arg0, %arg1 : i8 1673// CHECK: return %[[cres]] 1674func.func @notCmpULT(%arg0: i8, %arg1: i8) -> i1 { 1675 %true = arith.constant true 1676 %cmp = arith.cmpi "ult", %arg0, %arg1 : i8 1677 %ncmp = arith.xori %cmp, %true : i1 1678 return %ncmp : i1 1679} 1680 1681// CHECK-LABEL: @notCmpULE 1682// CHECK: %[[cres:.+]] = arith.cmpi ugt, %arg0, %arg1 : i8 1683// CHECK: return %[[cres]] 1684func.func @notCmpULE(%arg0: i8, %arg1: i8) -> i1 { 1685 %true = arith.constant true 1686 %cmp = arith.cmpi "ule", %arg0, %arg1 : i8 1687 %ncmp = arith.xori %cmp, %true : i1 1688 return %ncmp : i1 1689} 1690 1691// CHECK-LABEL: @notCmpUGT 1692// CHECK: %[[cres:.+]] = arith.cmpi ule, %arg0, %arg1 : i8 1693// CHECK: return %[[cres]] 1694func.func @notCmpUGT(%arg0: i8, %arg1: i8) -> i1 { 1695 %true = arith.constant true 1696 %cmp = arith.cmpi "ugt", %arg0, %arg1 : i8 1697 %ncmp = arith.xori %cmp, %true : i1 1698 return %ncmp : i1 1699} 1700 1701// CHECK-LABEL: @notCmpUGE 1702// CHECK: %[[cres:.+]] = arith.cmpi ult, %arg0, %arg1 : i8 1703// CHECK: return %[[cres]] 1704func.func @notCmpUGE(%arg0: i8, %arg1: i8) -> i1 { 1705 %true = arith.constant true 1706 %cmp = arith.cmpi "uge", %arg0, %arg1 : i8 1707 %ncmp = arith.xori %cmp, %true : i1 1708 return %ncmp : i1 1709} 1710 1711// ----- 1712 1713// CHECK-LABEL: @xorxor( 1714// CHECK-NOT: xori 1715// CHECK: return %arg0 1716func.func @xorxor(%cmp : i1) -> i1 { 1717 %true = arith.constant true 1718 %ncmp = arith.xori %cmp, %true : i1 1719 %nncmp = arith.xori %ncmp, %true : i1 1720 return %nncmp : i1 1721} 1722 1723// CHECK-LABEL: @xorOfExtSI 1724// CHECK: %[[comb:.+]] = arith.xori %arg0, %arg1 : i8 1725// CHECK: %[[ext:.+]] = arith.extsi %[[comb]] : i8 to i64 1726// CHECK: return %[[ext]] 1727func.func @xorOfExtSI(%arg0: i8, %arg1: i8) -> i64 { 1728 %ext0 = arith.extsi %arg0 : i8 to i64 1729 %ext1 = arith.extsi %arg1 : i8 to i64 1730 %res = arith.xori %ext0, %ext1 : i64 1731 return %res : i64 1732} 1733 1734// CHECK-LABEL: @xorOfExtUI 1735// CHECK: %[[comb:.+]] = arith.xori %arg0, %arg1 : i8 1736// CHECK: %[[ext:.+]] = arith.extui %[[comb]] : i8 to i64 1737// CHECK: return %[[ext]] 1738func.func @xorOfExtUI(%arg0: i8, %arg1: i8) -> i64 { 1739 %ext0 = arith.extui %arg0 : i8 to i64 1740 %ext1 = arith.extui %arg1 : i8 to i64 1741 %res = arith.xori %ext0, %ext1 : i64 1742 return %res : i64 1743} 1744 1745// ----- 1746 1747// CHECK-LABEL: @bitcastSameType( 1748// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]] 1749func.func @bitcastSameType(%arg : f32) -> f32 { 1750 // CHECK: return %[[ARG]] 1751 %res = arith.bitcast %arg : f32 to f32 1752 return %res : f32 1753} 1754 1755// ----- 1756 1757// CHECK-LABEL: @bitcastConstantFPtoI( 1758func.func @bitcastConstantFPtoI() -> i32 { 1759 // CHECK: %[[C0:.+]] = arith.constant 0 : i32 1760 // CHECK: return %[[C0]] 1761 %c0 = arith.constant 0.0 : f32 1762 %res = arith.bitcast %c0 : f32 to i32 1763 return %res : i32 1764} 1765 1766// ----- 1767 1768// CHECK-LABEL: @bitcastConstantItoFP( 1769func.func @bitcastConstantItoFP() -> f32 { 1770 // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f32 1771 // CHECK: return %[[C0]] 1772 %c0 = arith.constant 0 : i32 1773 %res = arith.bitcast %c0 : i32 to f32 1774 return %res : f32 1775} 1776 1777// ----- 1778 1779// CHECK-LABEL: @bitcastConstantFPtoFP( 1780func.func @bitcastConstantFPtoFP() -> f16 { 1781 // CHECK: %[[C0:.+]] = arith.constant 0.0{{.*}} : f16 1782 // CHECK: return %[[C0]] 1783 %c0 = arith.constant 0.0 : bf16 1784 %res = arith.bitcast %c0 : bf16 to f16 1785 return %res : f16 1786} 1787 1788// ----- 1789 1790// CHECK-LABEL: @bitcastConstantVecFPtoI( 1791func.func @bitcastConstantVecFPtoI() -> vector<3xf32> { 1792 // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xf32> 1793 // CHECK: return %[[C0]] 1794 %c0 = arith.constant dense<0> : vector<3xi32> 1795 %res = arith.bitcast %c0 : vector<3xi32> to vector<3xf32> 1796 return %res : vector<3xf32> 1797} 1798 1799// ----- 1800 1801// CHECK-LABEL: @bitcastConstantVecItoFP( 1802func.func @bitcastConstantVecItoFP() -> vector<3xi32> { 1803 // CHECK: %[[C0:.+]] = arith.constant dense<0> : vector<3xi32> 1804 // CHECK: return %[[C0]] 1805 %c0 = arith.constant dense<0.0> : vector<3xf32> 1806 %res = arith.bitcast %c0 : vector<3xf32> to vector<3xi32> 1807 return %res : vector<3xi32> 1808} 1809 1810// ----- 1811 1812// CHECK-LABEL: @bitcastConstantVecFPtoFP( 1813func.func @bitcastConstantVecFPtoFP() -> vector<3xbf16> { 1814 // CHECK: %[[C0:.+]] = arith.constant dense<0.0{{.*}}> : vector<3xbf16> 1815 // CHECK: return %[[C0]] 1816 %c0 = arith.constant dense<0.0> : vector<3xf16> 1817 %res = arith.bitcast %c0 : vector<3xf16> to vector<3xbf16> 1818 return %res : vector<3xbf16> 1819} 1820 1821// ----- 1822 1823// CHECK-LABEL: @bitcastBackAndForth( 1824// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]] 1825func.func @bitcastBackAndForth(%arg : i32) -> i32 { 1826 // CHECK: return %[[ARG]] 1827 %f = arith.bitcast %arg : i32 to f32 1828 %res = arith.bitcast %f : f32 to i32 1829 return %res : i32 1830} 1831 1832// ----- 1833 1834// CHECK-LABEL: @bitcastOfBitcast( 1835// CHECK-SAME: %[[ARG:[a-zA-Z0-9_]*]] 1836func.func @bitcastOfBitcast(%arg : i16) -> i16 { 1837 // CHECK: return %[[ARG]] 1838 %f = arith.bitcast %arg : i16 to f16 1839 %bf = arith.bitcast %f : f16 to bf16 1840 %res = arith.bitcast %bf : bf16 to i16 1841 return %res : i16 1842} 1843 1844// ----- 1845 1846// CHECK-LABEL: test_maxsi 1847// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1848// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant 127 1849// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]] 1850// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 1851func.func @test_maxsi(%arg0 : i8) -> (i8, i8, i8, i8) { 1852 %maxIntCst = arith.constant 127 : i8 1853 %minIntCst = arith.constant -128 : i8 1854 %c0 = arith.constant 42 : i8 1855 %0 = arith.maxsi %arg0, %arg0 : i8 1856 %1 = arith.maxsi %arg0, %maxIntCst : i8 1857 %2 = arith.maxsi %arg0, %minIntCst : i8 1858 %3 = arith.maxsi %arg0, %c0 : i8 1859 return %0, %1, %2, %3: i8, i8, i8, i8 1860} 1861 1862// CHECK-LABEL: test_maxsi2 1863// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1864// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant 127 1865// CHECK: %[[X:.+]] = arith.maxsi %arg0, %[[C0]] 1866// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 1867func.func @test_maxsi2(%arg0 : i8) -> (i8, i8, i8, i8) { 1868 %maxIntCst = arith.constant 127 : i8 1869 %minIntCst = arith.constant -128 : i8 1870 %c0 = arith.constant 42 : i8 1871 %0 = arith.maxsi %arg0, %arg0 : i8 1872 %1 = arith.maxsi %maxIntCst, %arg0: i8 1873 %2 = arith.maxsi %minIntCst, %arg0: i8 1874 %3 = arith.maxsi %c0, %arg0 : i8 1875 return %0, %1, %2, %3: i8, i8, i8, i8 1876} 1877 1878// ----- 1879 1880// CHECK-LABEL: test_maxui 1881// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1882// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant -1 1883// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]] 1884// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 1885func.func @test_maxui(%arg0 : i8) -> (i8, i8, i8, i8) { 1886 %maxIntCst = arith.constant 255 : i8 1887 %minIntCst = arith.constant 0 : i8 1888 %c0 = arith.constant 42 : i8 1889 %0 = arith.maxui %arg0, %arg0 : i8 1890 %1 = arith.maxui %arg0, %maxIntCst : i8 1891 %2 = arith.maxui %arg0, %minIntCst : i8 1892 %3 = arith.maxui %arg0, %c0 : i8 1893 return %0, %1, %2, %3: i8, i8, i8, i8 1894} 1895 1896// CHECK-LABEL: test_maxui 1897// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1898// CHECK-DAG: %[[MAX_INT_CST:.+]] = arith.constant -1 1899// CHECK: %[[X:.+]] = arith.maxui %arg0, %[[C0]] 1900// CHECK: return %arg0, %[[MAX_INT_CST]], %arg0, %[[X]] 1901func.func @test_maxui2(%arg0 : i8) -> (i8, i8, i8, i8) { 1902 %maxIntCst = arith.constant 255 : i8 1903 %minIntCst = arith.constant 0 : i8 1904 %c0 = arith.constant 42 : i8 1905 %0 = arith.maxui %arg0, %arg0 : i8 1906 %1 = arith.maxui %maxIntCst, %arg0 : i8 1907 %2 = arith.maxui %minIntCst, %arg0 : i8 1908 %3 = arith.maxui %c0, %arg0 : i8 1909 return %0, %1, %2, %3: i8, i8, i8, i8 1910} 1911 1912// ----- 1913 1914// CHECK-LABEL: test_minsi 1915// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1916// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant -128 1917// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]] 1918// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 1919func.func @test_minsi(%arg0 : i8) -> (i8, i8, i8, i8) { 1920 %maxIntCst = arith.constant 127 : i8 1921 %minIntCst = arith.constant -128 : i8 1922 %c0 = arith.constant 42 : i8 1923 %0 = arith.minsi %arg0, %arg0 : i8 1924 %1 = arith.minsi %arg0, %maxIntCst : i8 1925 %2 = arith.minsi %arg0, %minIntCst : i8 1926 %3 = arith.minsi %arg0, %c0 : i8 1927 return %0, %1, %2, %3: i8, i8, i8, i8 1928} 1929 1930// CHECK-LABEL: test_minsi 1931// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1932// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant -128 1933// CHECK: %[[X:.+]] = arith.minsi %arg0, %[[C0]] 1934// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 1935func.func @test_minsi2(%arg0 : i8) -> (i8, i8, i8, i8) { 1936 %maxIntCst = arith.constant 127 : i8 1937 %minIntCst = arith.constant -128 : i8 1938 %c0 = arith.constant 42 : i8 1939 %0 = arith.minsi %arg0, %arg0 : i8 1940 %1 = arith.minsi %maxIntCst, %arg0 : i8 1941 %2 = arith.minsi %minIntCst, %arg0 : i8 1942 %3 = arith.minsi %c0, %arg0 : i8 1943 return %0, %1, %2, %3: i8, i8, i8, i8 1944} 1945 1946// ----- 1947 1948// CHECK-LABEL: test_minui 1949// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1950// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant 0 1951// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]] 1952// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 1953func.func @test_minui(%arg0 : i8) -> (i8, i8, i8, i8) { 1954 %maxIntCst = arith.constant 255 : i8 1955 %minIntCst = arith.constant 0 : i8 1956 %c0 = arith.constant 42 : i8 1957 %0 = arith.minui %arg0, %arg0 : i8 1958 %1 = arith.minui %arg0, %maxIntCst : i8 1959 %2 = arith.minui %arg0, %minIntCst : i8 1960 %3 = arith.minui %arg0, %c0 : i8 1961 return %0, %1, %2, %3: i8, i8, i8, i8 1962} 1963 1964// CHECK-LABEL: test_minui 1965// CHECK-DAG: %[[C0:.+]] = arith.constant 42 1966// CHECK-DAG: %[[MIN_INT_CST:.+]] = arith.constant 0 1967// CHECK: %[[X:.+]] = arith.minui %arg0, %[[C0]] 1968// CHECK: return %arg0, %arg0, %[[MIN_INT_CST]], %[[X]] 1969func.func @test_minui2(%arg0 : i8) -> (i8, i8, i8, i8) { 1970 %maxIntCst = arith.constant 255 : i8 1971 %minIntCst = arith.constant 0 : i8 1972 %c0 = arith.constant 42 : i8 1973 %0 = arith.minui %arg0, %arg0 : i8 1974 %1 = arith.minui %maxIntCst, %arg0 : i8 1975 %2 = arith.minui %minIntCst, %arg0 : i8 1976 %3 = arith.minui %c0, %arg0 : i8 1977 return %0, %1, %2, %3: i8, i8, i8, i8 1978} 1979 1980// ----- 1981 1982// CHECK-LABEL: @test_minimumf( 1983func.func @test_minimumf(%arg0 : f32) -> (f32, f32, f32) { 1984 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.0 1985 // CHECK-NEXT: %[[X:.+]] = arith.minimumf %arg0, %[[C0]] 1986 // CHECK-NEXT: return %[[X]], %arg0, %arg0 1987 %c0 = arith.constant 0.0 : f32 1988 %inf = arith.constant 0x7F800000 : f32 1989 %0 = arith.minimumf %c0, %arg0 : f32 1990 %1 = arith.minimumf %arg0, %arg0 : f32 1991 %2 = arith.minimumf %inf, %arg0 : f32 1992 return %0, %1, %2 : f32, f32, f32 1993} 1994 1995// ----- 1996 1997// CHECK-LABEL: @test_maximumf( 1998func.func @test_maximumf(%arg0 : f32) -> (f32, f32, f32) { 1999 // CHECK-DAG: %[[C0:.+]] = arith.constant 2000 // CHECK-NEXT: %[[X:.+]] = arith.maximumf %arg0, %[[C0]] 2001 // CHECK-NEXT: return %[[X]], %arg0, %arg0 2002 %c0 = arith.constant 0.0 : f32 2003 %-inf = arith.constant 0xFF800000 : f32 2004 %0 = arith.maximumf %c0, %arg0 : f32 2005 %1 = arith.maximumf %arg0, %arg0 : f32 2006 %2 = arith.maximumf %-inf, %arg0 : f32 2007 return %0, %1, %2 : f32, f32, f32 2008} 2009 2010// ----- 2011 2012// CHECK-LABEL: @test_minnumf( 2013func.func @test_minnumf(%arg0 : f32) -> (f32, f32, f32, f32) { 2014 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.0 2015 // CHECK-DAG: %[[INF:.+]] = arith.constant 2016 // CHECK-NEXT: %[[X:.+]] = arith.minnumf %arg0, %[[C0]] 2017 // CHECK-NEXT: %[[Y:.+]] = arith.minnumf %arg0, %[[INF]] 2018 // CHECK-NEXT: return %[[X]], %arg0, %[[Y]], %arg0 2019 %c0 = arith.constant 0.0 : f32 2020 %inf = arith.constant 0x7F800000 : f32 2021 %nan = arith.constant 0x7FC00000 : f32 2022 %0 = arith.minnumf %c0, %arg0 : f32 2023 %1 = arith.minnumf %arg0, %arg0 : f32 2024 %2 = arith.minnumf %inf, %arg0 : f32 2025 %3 = arith.minnumf %nan, %arg0 : f32 2026 return %0, %1, %2, %3 : f32, f32, f32, f32 2027} 2028 2029// ----- 2030 2031// CHECK-LABEL: @test_maxnumf( 2032func.func @test_maxnumf(%arg0 : f32) -> (f32, f32, f32, f32) { 2033 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.0 2034 // CHECK-DAG: %[[NINF:.+]] = arith.constant 2035 // CHECK-NEXT: %[[X:.+]] = arith.maxnumf %arg0, %[[C0]] 2036 // CHECK-NEXT: %[[Y:.+]] = arith.maxnumf %arg0, %[[NINF]] 2037 // CHECK-NEXT: return %[[X]], %arg0, %[[Y]], %arg0 2038 %c0 = arith.constant 0.0 : f32 2039 %-inf = arith.constant 0xFF800000 : f32 2040 %nan = arith.constant 0x7FC00000 : f32 2041 %0 = arith.maxnumf %c0, %arg0 : f32 2042 %1 = arith.maxnumf %arg0, %arg0 : f32 2043 %2 = arith.maxnumf %-inf, %arg0 : f32 2044 %3 = arith.maxnumf %nan, %arg0 : f32 2045 return %0, %1, %2, %3 : f32, f32, f32, f32 2046} 2047 2048// ----- 2049 2050// CHECK-LABEL: @test_addf( 2051func.func @test_addf(%arg0 : f32) -> (f32, f32, f32, f32) { 2052 // CHECK-DAG: %[[C2:.+]] = arith.constant 2.0 2053 // CHECK-DAG: %[[C0:.+]] = arith.constant 0.0 2054 // CHECK-NEXT: %[[X:.+]] = arith.addf %arg0, %[[C0]] 2055 // CHECK-NEXT: return %[[X]], %arg0, %arg0, %[[C2]] 2056 %c0 = arith.constant 0.0 : f32 2057 %c-0 = arith.constant -0.0 : f32 2058 %c1 = arith.constant 1.0 : f32 2059 %0 = arith.addf %c0, %arg0 : f32 2060 %1 = arith.addf %arg0, %c-0 : f32 2061 %2 = arith.addf %c-0, %arg0 : f32 2062 %3 = arith.addf %c1, %c1 : f32 2063 return %0, %1, %2, %3 : f32, f32, f32, f32 2064} 2065 2066// ----- 2067 2068// CHECK-LABEL: @test_subf( 2069func.func @test_subf(%arg0 : f16) -> (f16, f16, f16) { 2070 // CHECK-DAG: %[[C1:.+]] = arith.constant -1.0 2071 // CHECK-DAG: %[[C0:.+]] = arith.constant -0.0 2072 // CHECK-NEXT: %[[X:.+]] = arith.subf %arg0, %[[C0]] 2073 // CHECK-NEXT: return %arg0, %[[X]], %[[C1]] 2074 %c0 = arith.constant 0.0 : f16 2075 %c-0 = arith.constant -0.0 : f16 2076 %c1 = arith.constant 1.0 : f16 2077 %0 = arith.subf %arg0, %c0 : f16 2078 %1 = arith.subf %arg0, %c-0 : f16 2079 %2 = arith.subf %c0, %c1 : f16 2080 return %0, %1, %2 : f16, f16, f16 2081} 2082 2083// ----- 2084 2085// CHECK-LABEL: @test_mulf( 2086func.func @test_mulf(%arg0 : f32) -> (f32, f32, f32, f32) { 2087 // CHECK-DAG: %[[C2:.+]] = arith.constant 2.0 2088 // CHECK-DAG: %[[C4:.+]] = arith.constant 4.0 2089 // CHECK-NEXT: %[[X:.+]] = arith.mulf %arg0, %[[C2]] 2090 // CHECK-NEXT: return %[[X]], %arg0, %arg0, %[[C4]] 2091 %c1 = arith.constant 1.0 : f32 2092 %c2 = arith.constant 2.0 : f32 2093 %0 = arith.mulf %c2, %arg0 : f32 2094 %1 = arith.mulf %arg0, %c1 : f32 2095 %2 = arith.mulf %c1, %arg0 : f32 2096 %3 = arith.mulf %c2, %c2 : f32 2097 return %0, %1, %2, %3 : f32, f32, f32, f32 2098} 2099 2100// CHECK-LABEL: @test_mulf1( 2101func.func @test_mulf1(%arg0 : f32, %arg1 : f32) -> (f32) { 2102 // CHECK-NEXT: %[[X:.+]] = arith.mulf %arg0, %arg1 : f32 2103 // CHECK-NEXT: return %[[X]] 2104 %0 = arith.negf %arg0 : f32 2105 %1 = arith.negf %arg1 : f32 2106 %2 = arith.mulf %0, %1 : f32 2107 return %2 : f32 2108} 2109 2110// ----- 2111 2112// CHECK-LABEL: @test_divf( 2113func.func @test_divf(%arg0 : f64) -> (f64, f64) { 2114 // CHECK-NEXT: %[[C5:.+]] = arith.constant 5.000000e-01 2115 // CHECK-NEXT: return %arg0, %[[C5]] 2116 %c1 = arith.constant 1.0 : f64 2117 %c2 = arith.constant 2.0 : f64 2118 %0 = arith.divf %arg0, %c1 : f64 2119 %1 = arith.divf %c1, %c2 : f64 2120 return %0, %1 : f64, f64 2121} 2122 2123// CHECK-LABEL: @test_divf1( 2124func.func @test_divf1(%arg0 : f32, %arg1 : f32) -> (f32) { 2125 // CHECK-NEXT: %[[X:.+]] = arith.divf %arg0, %arg1 : f32 2126 // CHECK-NEXT: return %[[X]] 2127 %0 = arith.negf %arg0 : f32 2128 %1 = arith.negf %arg1 : f32 2129 %2 = arith.divf %0, %1 : f32 2130 return %2 : f32 2131} 2132 2133// ----- 2134 2135func.func @fold_divui_of_muli_0(%arg0 : index, %arg1 : index) -> index { 2136 %0 = arith.muli %arg0, %arg1 overflow<nuw> : index 2137 %1 = arith.divui %0, %arg0 : index 2138 return %1 : index 2139} 2140// CHECK-LABEL: func @fold_divui_of_muli_0( 2141// CHECK-SAME: %[[ARG0:.+]]: index, 2142// CHECK-SAME: %[[ARG1:.+]]: index) 2143// CHECK: return %[[ARG1]] 2144 2145func.func @fold_divui_of_muli_1(%arg0 : index, %arg1 : index) -> index { 2146 %0 = arith.muli %arg0, %arg1 overflow<nuw> : index 2147 %1 = arith.divui %0, %arg1 : index 2148 return %1 : index 2149} 2150// CHECK-LABEL: func @fold_divui_of_muli_1( 2151// CHECK-SAME: %[[ARG0:.+]]: index, 2152// CHECK-SAME: %[[ARG1:.+]]: index) 2153// CHECK: return %[[ARG0]] 2154 2155func.func @fold_divsi_of_muli_0(%arg0 : index, %arg1 : index) -> index { 2156 %0 = arith.muli %arg0, %arg1 overflow<nsw> : index 2157 %1 = arith.divsi %0, %arg0 : index 2158 return %1 : index 2159} 2160// CHECK-LABEL: func @fold_divsi_of_muli_0( 2161// CHECK-SAME: %[[ARG0:.+]]: index, 2162// CHECK-SAME: %[[ARG1:.+]]: index) 2163// CHECK: return %[[ARG1]] 2164 2165func.func @fold_divsi_of_muli_1(%arg0 : index, %arg1 : index) -> index { 2166 %0 = arith.muli %arg0, %arg1 overflow<nsw> : index 2167 %1 = arith.divsi %0, %arg1 : index 2168 return %1 : index 2169} 2170// CHECK-LABEL: func @fold_divsi_of_muli_1( 2171// CHECK-SAME: %[[ARG0:.+]]: index, 2172// CHECK-SAME: %[[ARG1:.+]]: index) 2173// CHECK: return %[[ARG0]] 2174 2175// Do not fold divui(mul(a, v), v) -> a with nuw attribute. 2176func.func @no_fold_divui_of_muli(%arg0 : index, %arg1 : index) -> index { 2177 %0 = arith.muli %arg0, %arg1 : index 2178 %1 = arith.divui %0, %arg0 : index 2179 return %1 : index 2180} 2181// CHECK-LABEL: func @no_fold_divui_of_muli 2182// CHECK: %[[T0:.+]] = arith.muli 2183// CHECK: %[[T1:.+]] = arith.divui %[[T0]], 2184// CHECK: return %[[T1]] 2185 2186// Do not fold divsi(mul(a, v), v) -> a with nuw attribute. 2187func.func @no_fold_divsi_of_muli(%arg0 : index, %arg1 : index) -> index { 2188 %0 = arith.muli %arg0, %arg1 : index 2189 %1 = arith.divsi %0, %arg0 : index 2190 return %1 : index 2191} 2192// CHECK-LABEL: func @no_fold_divsi_of_muli 2193// CHECK: %[[T0:.+]] = arith.muli 2194// CHECK: %[[T1:.+]] = arith.divsi %[[T0]], 2195// CHECK: return %[[T1]] 2196 2197// ----- 2198 2199// CHECK-LABEL: @test_cmpf( 2200func.func @test_cmpf(%arg0 : f32) -> (i1, i1, i1, i1) { 2201// CHECK-DAG: %[[T:.*]] = arith.constant true 2202// CHECK-DAG: %[[F:.*]] = arith.constant false 2203// CHECK: return %[[F]], %[[F]], %[[T]], %[[T]] 2204 %nan = arith.constant 0x7fffffff : f32 2205 %0 = arith.cmpf olt, %nan, %arg0 : f32 2206 %1 = arith.cmpf olt, %arg0, %nan : f32 2207 %2 = arith.cmpf ugt, %nan, %arg0 : f32 2208 %3 = arith.cmpf ugt, %arg0, %nan : f32 2209 return %0, %1, %2, %3 : i1, i1, i1, i1 2210} 2211 2212// ----- 2213 2214// CHECK-LABEL: @constant_FPtoUI( 2215func.func @constant_FPtoUI() -> i32 { 2216 // CHECK: %[[C0:.+]] = arith.constant 2 : i32 2217 // CHECK: return %[[C0]] 2218 %c0 = arith.constant 2.0 : f32 2219 %res = arith.fptoui %c0 : f32 to i32 2220 return %res : i32 2221} 2222 2223// CHECK-LABEL: @constant_FPtoUI_splat( 2224func.func @constant_FPtoUI_splat() -> vector<4xi32> { 2225 // CHECK: %[[C0:.+]] = arith.constant dense<2> : vector<4xi32> 2226 // CHECK: return %[[C0]] 2227 %c0 = arith.constant 2.0 : f32 2228 %splat = vector.splat %c0 : vector<4xf32> 2229 %res = arith.fptoui %splat : vector<4xf32> to vector<4xi32> 2230 return %res : vector<4xi32> 2231} 2232 2233// CHECK-LABEL: @constant_FPtoUI_vector( 2234func.func @constant_FPtoUI_vector() -> vector<4xi32> { 2235 // CHECK: %[[C0:.+]] = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 2236 // CHECK: return %[[C0]] 2237 %vector = arith.constant dense<[1.0, 3.0, 5.0, 7.0]> : vector<4xf32> 2238 %res = arith.fptoui %vector : vector<4xf32> to vector<4xi32> 2239 return %res : vector<4xi32> 2240} 2241 2242// ----- 2243// CHECK-LABEL: @invalid_constant_FPtoUI( 2244func.func @invalid_constant_FPtoUI() -> i32 { 2245 // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32 2246 // CHECK: %[[C1:.+]] = arith.fptoui %[[C0]] : f32 to i32 2247 // CHECK: return %[[C1]] 2248 %c0 = arith.constant -2.0 : f32 2249 %res = arith.fptoui %c0 : f32 to i32 2250 return %res : i32 2251} 2252 2253// ----- 2254// CHECK-LABEL: @constant_FPtoSI( 2255func.func @constant_FPtoSI() -> i32 { 2256 // CHECK: %[[C0:.+]] = arith.constant -2 : i32 2257 // CHECK: return %[[C0]] 2258 %c0 = arith.constant -2.0 : f32 2259 %res = arith.fptosi %c0 : f32 to i32 2260 return %res : i32 2261} 2262 2263// CHECK-LABEL: @constant_FPtoSI_splat( 2264func.func @constant_FPtoSI_splat() -> vector<4xi32> { 2265 // CHECK: %[[C0:.+]] = arith.constant dense<-2> : vector<4xi32> 2266 // CHECK: return %[[C0]] 2267 %c0 = arith.constant -2.0 : f32 2268 %splat = vector.splat %c0 : vector<4xf32> 2269 %res = arith.fptosi %splat : vector<4xf32> to vector<4xi32> 2270 return %res : vector<4xi32> 2271} 2272 2273// CHECK-LABEL: @constant_FPtoSI_vector( 2274func.func @constant_FPtoSI_vector() -> vector<4xi32> { 2275 // CHECK: %[[C0:.+]] = arith.constant dense<[-1, -3, -5, -7]> : vector<4xi32> 2276 // CHECK: return %[[C0]] 2277 %vector = arith.constant dense<[-1.0, -3.0, -5.0, -7.0]> : vector<4xf32> 2278 %res = arith.fptosi %vector : vector<4xf32> to vector<4xi32> 2279 return %res : vector<4xi32> 2280} 2281 2282// ----- 2283// CHECK-LABEL: @invalid_constant_FPtoSI( 2284func.func @invalid_constant_FPtoSI() -> i8 { 2285 // CHECK: %[[C0:.+]] = arith.constant 2.000000e+10 : f32 2286 // CHECK: %[[C1:.+]] = arith.fptosi %[[C0]] : f32 to i8 2287 // CHECK: return %[[C1]] 2288 %c0 = arith.constant 2.0e10 : f32 2289 %res = arith.fptosi %c0 : f32 to i8 2290 return %res : i8 2291} 2292 2293// CHECK-LABEL: @constant_SItoFP( 2294func.func @constant_SItoFP() -> f32 { 2295 // CHECK: %[[C0:.+]] = arith.constant -2.000000e+00 : f32 2296 // CHECK: return %[[C0]] 2297 %c0 = arith.constant -2 : i32 2298 %res = arith.sitofp %c0 : i32 to f32 2299 return %res : f32 2300} 2301 2302// CHECK-LABEL: @constant_SItoFP_splat( 2303func.func @constant_SItoFP_splat() -> vector<4xf32> { 2304 // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32> 2305 // CHECK: return %[[C0]] 2306 %c0 = arith.constant 2 : i32 2307 %splat = vector.splat %c0 : vector<4xi32> 2308 %res = arith.sitofp %splat : vector<4xi32> to vector<4xf32> 2309 return %res : vector<4xf32> 2310} 2311 2312// CHECK-LABEL: @constant_SItoFP_vector( 2313func.func @constant_SItoFP_vector() -> vector<4xf32> { 2314 // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32> 2315 // CHECK: return %[[C0]] 2316 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 2317 %res = arith.sitofp %vector : vector<4xi32> to vector<4xf32> 2318 return %res : vector<4xf32> 2319} 2320 2321// ----- 2322// CHECK-LABEL: @constant_UItoFP( 2323func.func @constant_UItoFP() -> f32 { 2324 // CHECK: %[[C0:.+]] = arith.constant 2.000000e+00 : f32 2325 // CHECK: return %[[C0]] 2326 %c0 = arith.constant 2 : i32 2327 %res = arith.uitofp %c0 : i32 to f32 2328 return %res : f32 2329} 2330 2331// CHECK-LABEL: @constant_UItoFP_splat( 2332func.func @constant_UItoFP_splat() -> vector<4xf32> { 2333 // CHECK: %[[C0:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32> 2334 // CHECK: return %[[C0]] 2335 %c0 = arith.constant 2 : i32 2336 %splat = vector.splat %c0 : vector<4xi32> 2337 %res = arith.uitofp %splat : vector<4xi32> to vector<4xf32> 2338 return %res : vector<4xf32> 2339} 2340 2341// CHECK-LABEL: @constant_UItoFP_vector( 2342func.func @constant_UItoFP_vector() -> vector<4xf32> { 2343 // CHECK: %[[C0:.+]] = arith.constant dense<[1.000000e+00, 3.000000e+00, 5.000000e+00, 7.000000e+00]> : vector<4xf32> 2344 // CHECK: return %[[C0]] 2345 %vector = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 2346 %res = arith.uitofp %vector : vector<4xi32> to vector<4xf32> 2347 return %res : vector<4xf32> 2348} 2349 2350// ----- 2351 2352// Tests rewritten from https://github.com/llvm/llvm-project/blob/main/llvm/test/Transforms/InstCombine/2008-11-08-FCmp.ll 2353// When inst combining an FCMP with the LHS coming from a arith.uitofp instruction, we 2354// can lower it to signed ICMP instructions. 2355 2356// CHECK-LABEL: @test1( 2357// CHECK-SAME: %[[arg0:.+]]: 2358func.func @test1(%arg0: i32) -> i1 { 2359 %cst = arith.constant 0.000000e+00 : f64 2360 %1 = arith.uitofp %arg0: i32 to f64 2361 %2 = arith.cmpf ole, %1, %cst : f64 2362 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 2363 // CHECK: arith.cmpi ule, %[[arg0]], %[[c0]] : i32 2364 return %2 : i1 2365} 2366 2367// CHECK-LABEL: @test2( 2368// CHECK-SAME: %[[arg0:.+]]: 2369func.func @test2(%arg0: i32) -> i1 { 2370 %cst = arith.constant 0.000000e+00 : f64 2371 %1 = arith.uitofp %arg0: i32 to f64 2372 %2 = arith.cmpf olt, %1, %cst : f64 2373 return %2 : i1 2374 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 2375 // CHECK: arith.cmpi ult, %[[arg0]], %[[c0]] : i32 2376} 2377 2378// CHECK-LABEL: @test3( 2379// CHECK-SAME: %[[arg0:.+]]: 2380func.func @test3(%arg0: i32) -> i1 { 2381 %cst = arith.constant 0.000000e+00 : f64 2382 %1 = arith.uitofp %arg0: i32 to f64 2383 %2 = arith.cmpf oge, %1, %cst : f64 2384 return %2 : i1 2385 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 2386 // CHECK: arith.cmpi uge, %[[arg0]], %[[c0]] : i32 2387} 2388 2389// CHECK-LABEL: @test4( 2390// CHECK-SAME: %[[arg0:.+]]: 2391func.func @test4(%arg0: i32) -> i1 { 2392 %cst = arith.constant 0.000000e+00 : f64 2393 %1 = arith.uitofp %arg0: i32 to f64 2394 %2 = arith.cmpf ogt, %1, %cst : f64 2395 // CHECK: %[[c0:.+]] = arith.constant 0 : i32 2396 // CHECK: arith.cmpi ugt, %[[arg0]], %[[c0]] : i32 2397 return %2 : i1 2398} 2399 2400// CHECK-LABEL: @test5( 2401func.func @test5(%arg0: i32) -> i1 { 2402 %cst = arith.constant -4.400000e+00 : f64 2403 %1 = arith.uitofp %arg0: i32 to f64 2404 %2 = arith.cmpf ogt, %1, %cst : f64 2405 return %2 : i1 2406 // CHECK: %[[true:.+]] = arith.constant true 2407 // CHECK: return %[[true]] : i1 2408} 2409 2410// CHECK-LABEL: @test6( 2411func.func @test6(%arg0: i32) -> i1 { 2412 %cst = arith.constant -4.400000e+00 : f64 2413 %1 = arith.uitofp %arg0: i32 to f64 2414 %2 = arith.cmpf olt, %1, %cst : f64 2415 return %2 : i1 2416 // CHECK: %[[false:.+]] = arith.constant false 2417 // CHECK: return %[[false]] : i1 2418} 2419 2420// Check that optimizing unsigned >= comparisons correctly distinguishes 2421// positive and negative constants. 2422// CHECK-LABEL: @test7( 2423// CHECK-SAME: %[[arg0:.+]]: 2424func.func @test7(%arg0: i32) -> i1 { 2425 %cst = arith.constant 3.200000e+00 : f64 2426 %1 = arith.uitofp %arg0: i32 to f64 2427 %2 = arith.cmpf oge, %1, %cst : f64 2428 return %2 : i1 2429 // CHECK: %[[c3:.+]] = arith.constant 3 : i32 2430 // CHECK: arith.cmpi ugt, %[[arg0]], %[[c3]] : i32 2431} 2432 2433// ----- 2434 2435// CHECK-LABEL: @foldShl( 2436// CHECK: %[[res:.+]] = arith.constant 4294967296 : i64 2437// CHECK: return %[[res]] 2438func.func @foldShl() -> i64 { 2439 %c1 = arith.constant 1 : i64 2440 %c32 = arith.constant 32 : i64 2441 %r = arith.shli %c1, %c32 : i64 2442 return %r : i64 2443} 2444 2445// CHECK-LABEL: @nofoldShl( 2446// CHECK: %[[res:.+]] = arith.shli 2447// CHECK: return %[[res]] 2448func.func @nofoldShl() -> i64 { 2449 %c1 = arith.constant 1 : i64 2450 %c132 = arith.constant 132 : i64 2451 %r = arith.shli %c1, %c132 : i64 2452 return %r : i64 2453} 2454 2455// CHECK-LABEL: @nofoldShl2( 2456// CHECK: %[[res:.+]] = arith.shli 2457// CHECK: return %[[res]] 2458func.func @nofoldShl2() -> i64 { 2459 %c1 = arith.constant 1 : i64 2460 %cm32 = arith.constant -32 : i64 2461 %r = arith.shli %c1, %cm32 : i64 2462 return %r : i64 2463} 2464 2465// CHECK-LABEL: @nofoldShl3( 2466// CHECK: %[[res:.+]] = arith.shli 2467// CHECK: return %[[res]] 2468func.func @nofoldShl3() -> i64 { 2469 %c1 = arith.constant 1 : i64 2470 %c64 = arith.constant 64 : i64 2471 // Note that this should return Poison in the future. 2472 %r = arith.shli %c1, %c64 : i64 2473 return %r : i64 2474} 2475 2476// CHECK-LABEL: @foldShru( 2477// CHECK: %[[res:.+]] = arith.constant 2 : i64 2478// CHECK: return %[[res]] 2479func.func @foldShru() -> i64 { 2480 %c1 = arith.constant 8 : i64 2481 %c32 = arith.constant 2 : i64 2482 %r = arith.shrui %c1, %c32 : i64 2483 return %r : i64 2484} 2485 2486// CHECK-LABEL: @foldShru2( 2487// CHECK: %[[res:.+]] = arith.constant 9223372036854775807 : i64 2488// CHECK: return %[[res]] 2489func.func @foldShru2() -> i64 { 2490 %c1 = arith.constant -2 : i64 2491 %c32 = arith.constant 1 : i64 2492 %r = arith.shrui %c1, %c32 : i64 2493 return %r : i64 2494} 2495 2496// CHECK-LABEL: @nofoldShru( 2497// CHECK: %[[res:.+]] = arith.shrui 2498// CHECK: return %[[res]] 2499func.func @nofoldShru() -> i64 { 2500 %c1 = arith.constant 8 : i64 2501 %c132 = arith.constant 132 : i64 2502 %r = arith.shrui %c1, %c132 : i64 2503 return %r : i64 2504} 2505 2506// CHECK-LABEL: @nofoldShru2( 2507// CHECK: %[[res:.+]] = arith.shrui 2508// CHECK: return %[[res]] 2509func.func @nofoldShru2() -> i64 { 2510 %c1 = arith.constant 8 : i64 2511 %cm32 = arith.constant -32 : i64 2512 %r = arith.shrui %c1, %cm32 : i64 2513 return %r : i64 2514} 2515 2516// CHECK-LABEL: @nofoldShru3( 2517// CHECK: %[[res:.+]] = arith.shrui 2518// CHECK: return %[[res]] 2519func.func @nofoldShru3() -> i64 { 2520 %c1 = arith.constant 8 : i64 2521 %c64 = arith.constant 64 : i64 2522 // Note that this should return Poison in the future. 2523 %r = arith.shrui %c1, %c64 : i64 2524 return %r : i64 2525} 2526 2527// CHECK-LABEL: @foldShrs( 2528// CHECK: %[[res:.+]] = arith.constant 2 : i64 2529// CHECK: return %[[res]] 2530func.func @foldShrs() -> i64 { 2531 %c1 = arith.constant 8 : i64 2532 %c32 = arith.constant 2 : i64 2533 %r = arith.shrsi %c1, %c32 : i64 2534 return %r : i64 2535} 2536 2537// CHECK-LABEL: @foldShrs2( 2538// CHECK: %[[res:.+]] = arith.constant -1 : i64 2539// CHECK: return %[[res]] 2540func.func @foldShrs2() -> i64 { 2541 %c1 = arith.constant -2 : i64 2542 %c32 = arith.constant 1 : i64 2543 %r = arith.shrsi %c1, %c32 : i64 2544 return %r : i64 2545} 2546 2547// CHECK-LABEL: @nofoldShrs( 2548// CHECK: %[[res:.+]] = arith.shrsi 2549// CHECK: return %[[res]] 2550func.func @nofoldShrs() -> i64 { 2551 %c1 = arith.constant 8 : i64 2552 %c132 = arith.constant 132 : i64 2553 %r = arith.shrsi %c1, %c132 : i64 2554 return %r : i64 2555} 2556 2557// CHECK-LABEL: @nofoldShrs2( 2558// CHECK: %[[res:.+]] = arith.shrsi 2559// CHECK: return %[[res]] 2560func.func @nofoldShrs2() -> i64 { 2561 %c1 = arith.constant 8 : i64 2562 %cm32 = arith.constant -32 : i64 2563 %r = arith.shrsi %c1, %cm32 : i64 2564 return %r : i64 2565} 2566 2567// CHECK-LABEL: @nofoldShrs3( 2568// CHECK: %[[res:.+]] = arith.shrsi 2569// CHECK: return %[[res]] 2570func.func @nofoldShrs3() -> i64 { 2571 %c1 = arith.constant 8 : i64 2572 %c64 = arith.constant 64 : i64 2573 // Note that this should return Poison in the future. 2574 %r = arith.shrsi %c1, %c64 : i64 2575 return %r : i64 2576} 2577 2578// ----- 2579 2580// CHECK-LABEL: @test_negf( 2581// CHECK: %[[res:.+]] = arith.constant -2.0 2582// CHECK: return %[[res]] 2583func.func @test_negf() -> (f32) { 2584 %c = arith.constant 2.0 : f32 2585 %0 = arith.negf %c : f32 2586 return %0: f32 2587} 2588 2589// CHECK-LABEL: @test_negf1( 2590// CHECK-SAME: %[[arg0:.+]]: 2591// CHECK: return %[[arg0]] 2592func.func @test_negf1(%f : f32) -> (f32) { 2593 %0 = arith.negf %f : f32 2594 %1 = arith.negf %0 : f32 2595 return %1: f32 2596} 2597 2598// ----- 2599 2600// CHECK-LABEL: @test_remui( 2601// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32> 2602// CHECK: return %[[res]] 2603func.func @test_remui() -> (vector<4xi32>) { 2604 %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32> 2605 %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 2606 %0 = arith.remui %v1, %v2 : vector<4xi32> 2607 return %0 : vector<4xi32> 2608} 2609 2610// // ----- 2611 2612// CHECK-LABEL: @test_remui_1( 2613// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32> 2614// CHECK: return %[[res]] 2615func.func @test_remui_1(%arg : vector<4xi32>) -> (vector<4xi32>) { 2616 %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32> 2617 %0 = arith.remui %arg, %v : vector<4xi32> 2618 return %0 : vector<4xi32> 2619} 2620 2621// ----- 2622 2623// CHECK-LABEL: @test_remsi( 2624// CHECK: %[[res:.+]] = arith.constant dense<[0, 0, 4, 2]> : vector<4xi32> 2625// CHECK: return %[[res]] 2626func.func @test_remsi() -> (vector<4xi32>) { 2627 %v1 = arith.constant dense<[9, 9, 9, 9]> : vector<4xi32> 2628 %v2 = arith.constant dense<[1, 3, 5, 7]> : vector<4xi32> 2629 %0 = arith.remsi %v1, %v2 : vector<4xi32> 2630 return %0 : vector<4xi32> 2631} 2632 2633// // ----- 2634 2635// CHECK-LABEL: @test_remsi_1( 2636// CHECK: %[[res:.+]] = arith.constant dense<0> : vector<4xi32> 2637// CHECK: return %[[res]] 2638func.func @test_remsi_1(%arg : vector<4xi32>) -> (vector<4xi32>) { 2639 %v = arith.constant dense<[1, 1, 1, 1]> : vector<4xi32> 2640 %0 = arith.remsi %arg, %v : vector<4xi32> 2641 return %0 : vector<4xi32> 2642} 2643 2644// ----- 2645 2646// CHECK-LABEL: @test_remf( 2647// CHECK: %[[res:.+]] = arith.constant 1.000000e+00 : f32 2648// CHECK: return %[[res]] 2649func.func @test_remf() -> (f32) { 2650 %v1 = arith.constant 3.0 : f32 2651 %v2 = arith.constant 2.0 : f32 2652 %0 = arith.remf %v1, %v2 : f32 2653 return %0 : f32 2654} 2655 2656// CHECK-LABEL: @test_remf2( 2657// CHECK: %[[respos:.+]] = arith.constant 1.000000e+00 : f32 2658// CHECK: %[[resneg:.+]] = arith.constant -1.000000e+00 : f32 2659// CHECK: return %[[respos]], %[[resneg]] 2660func.func @test_remf2() -> (f32, f32) { 2661 %v1 = arith.constant 3.0 : f32 2662 %v2 = arith.constant -2.0 : f32 2663 %v3 = arith.constant -3.0 : f32 2664 %0 = arith.remf %v1, %v2 : f32 2665 %1 = arith.remf %v3, %v2 : f32 2666 return %0, %1 : f32, f32 2667} 2668 2669// CHECK-LABEL: @test_remf_vec( 2670// CHECK: %[[res:.+]] = arith.constant dense<[1.000000e+00, 0.000000e+00, -1.000000e+00, 0.000000e+00]> : vector<4xf32> 2671// CHECK: return %[[res]] 2672func.func @test_remf_vec() -> (vector<4xf32>) { 2673 %v1 = arith.constant dense<[1.0, 2.0, -3.0, 4.0]> : vector<4xf32> 2674 %v2 = arith.constant dense<[2.0, 2.0, 2.0, 2.0]> : vector<4xf32> 2675 %0 = arith.remf %v1, %v2 : vector<4xf32> 2676 return %0 : vector<4xf32> 2677} 2678 2679// ----- 2680 2681// CHECK-LABEL: @test_andi_not_fold_rhs( 2682// CHECK-SAME: %[[ARG0:[[:alnum:]]+]] 2683// CHECK: %[[C:.*]] = arith.constant 0 : index 2684// CHECK: return %[[C]] 2685 2686func.func @test_andi_not_fold_rhs(%arg0 : index) -> index { 2687 %0 = arith.constant -1 : index 2688 %1 = arith.xori %arg0, %0 : index 2689 %2 = arith.andi %arg0, %1 : index 2690 return %2 : index 2691} 2692 2693 2694// CHECK-LABEL: @test_andi_not_fold_lhs( 2695// CHECK-SAME: %[[ARG0:[[:alnum:]]+]] 2696// CHECK: %[[C:.*]] = arith.constant 0 : index 2697// CHECK: return %[[C]] 2698 2699func.func @test_andi_not_fold_lhs(%arg0 : index) -> index { 2700 %0 = arith.constant -1 : index 2701 %1 = arith.xori %arg0, %0 : index 2702 %2 = arith.andi %1, %arg0 : index 2703 return %2 : index 2704} 2705 2706// ----- 2707 2708// CHECK-LABEL: @test_andi_not_fold_rhs_vec( 2709// CHECK-SAME: %[[ARG0:[[:alnum:]]+]] 2710// CHECK: %[[C:.*]] = arith.constant dense<0> : vector<2xi32> 2711// CHECK: return %[[C]] 2712 2713func.func @test_andi_not_fold_rhs_vec(%arg0 : vector<2xi32>) -> vector<2xi32> { 2714 %0 = arith.constant dense<[-1, -1]> : vector<2xi32> 2715 %1 = arith.xori %arg0, %0 : vector<2xi32> 2716 %2 = arith.andi %arg0, %1 : vector<2xi32> 2717 return %2 : vector<2xi32> 2718} 2719 2720 2721// CHECK-LABEL: @test_andi_not_fold_lhs_vec( 2722// CHECK-SAME: %[[ARG0:[[:alnum:]]+]] 2723// CHECK: %[[C:.*]] = arith.constant dense<0> : vector<2xi32> 2724// CHECK: return %[[C]] 2725 2726func.func @test_andi_not_fold_lhs_vec(%arg0 : vector<2xi32>) -> vector<2xi32> { 2727 %0 = arith.constant dense<[-1, -1]> : vector<2xi32> 2728 %1 = arith.xori %arg0, %0 : vector<2xi32> 2729 %2 = arith.andi %1, %arg0 : vector<2xi32> 2730 return %2 : vector<2xi32> 2731} 2732 2733// ----- 2734/// xor(xor(x, a), a) -> x 2735 2736// CHECK-LABEL: @xorxor0( 2737// CHECK-NOT: xori 2738// CHECK: return %arg0 2739func.func @xorxor0(%a : i32, %b : i32) -> i32 { 2740 %c = arith.xori %a, %b : i32 2741 %res = arith.xori %c, %b : i32 2742 return %res : i32 2743} 2744 2745// ----- 2746/// xor(xor(a, x), a) -> x 2747 2748// CHECK-LABEL: @xorxor1( 2749// CHECK-NOT: xori 2750// CHECK: return %arg0 2751func.func @xorxor1(%a : i32, %b : i32) -> i32 { 2752 %c = arith.xori %b, %a : i32 2753 %res = arith.xori %c, %b : i32 2754 return %res : i32 2755} 2756 2757// ----- 2758/// xor(a, xor(x, a)) -> x 2759 2760// CHECK-LABEL: @xorxor2( 2761// CHECK-NOT: xori 2762// CHECK: return %arg0 2763func.func @xorxor2(%a : i32, %b : i32) -> i32 { 2764 %c = arith.xori %a, %b : i32 2765 %res = arith.xori %b, %c : i32 2766 return %res : i32 2767} 2768 2769// ----- 2770/// xor(a, xor(a, x)) -> x 2771 2772// CHECK-LABEL: @xorxor3( 2773// CHECK-NOT: xori 2774// CHECK: return %arg0 2775func.func @xorxor3(%a : i32, %b : i32) -> i32 { 2776 %c = arith.xori %b, %a : i32 2777 %res = arith.xori %b, %c : i32 2778 return %res : i32 2779} 2780 2781// ----- 2782 2783/// and(a, and(a, b)) -> and(a, b) 2784 2785// CHECK-LABEL: @andand0 2786// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32) 2787// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32 2788// CHECK: return %[[RES]] 2789func.func @andand0(%a : i32, %b : i32) -> i32 { 2790 %c = arith.andi %a, %b : i32 2791 %res = arith.andi %a, %c : i32 2792 return %res : i32 2793} 2794 2795// CHECK-LABEL: @andand1 2796// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32) 2797// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32 2798// CHECK: return %[[RES]] 2799func.func @andand1(%a : i32, %b : i32) -> i32 { 2800 %c = arith.andi %a, %b : i32 2801 %res = arith.andi %c, %a : i32 2802 return %res : i32 2803} 2804 2805// CHECK-LABEL: @andand2 2806// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32) 2807// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32 2808// CHECK: return %[[RES]] 2809func.func @andand2(%a : i32, %b : i32) -> i32 { 2810 %c = arith.andi %a, %b : i32 2811 %res = arith.andi %b, %c : i32 2812 return %res : i32 2813} 2814 2815// CHECK-LABEL: @andand3 2816// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32) 2817// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32 2818// CHECK: return %[[RES]] 2819func.func @andand3(%a : i32, %b : i32) -> i32 { 2820 %c = arith.andi %a, %b : i32 2821 %res = arith.andi %c, %b : i32 2822 return %res : i32 2823} 2824 2825// ----- 2826 2827// CHECK-LABEL: @truncIShrSIToTrunciShrUI 2828// CHECK-SAME: (%[[A:.+]]: i64) 2829// CHECK-NEXT: %[[C32:.+]] = arith.constant 32 : i64 2830// CHECK-NEXT: %[[SHR:.+]] = arith.shrui %[[A]], %[[C32]] : i64 2831// CHECK-NEXT: %[[TRU:.+]] = arith.trunci %[[SHR]] : i64 to i32 2832// CHECK-NEXT: return %[[TRU]] : i32 2833func.func @truncIShrSIToTrunciShrUI(%a: i64) -> i32 { 2834 %c32 = arith.constant 32: i64 2835 %sh = arith.shrsi %a, %c32 : i64 2836 %hi = arith.trunci %sh: i64 to i32 2837 return %hi : i32 2838} 2839 2840// CHECK-LABEL: @truncIShrSIToTrunciShrUIBadShiftAmt1 2841// CHECK: arith.shrsi 2842func.func @truncIShrSIToTrunciShrUIBadShiftAmt1(%a: i64) -> i32 { 2843 %c33 = arith.constant 33: i64 2844 %sh = arith.shrsi %a, %c33 : i64 2845 %hi = arith.trunci %sh: i64 to i32 2846 return %hi : i32 2847} 2848 2849// CHECK-LABEL: @truncIShrSIToTrunciShrUIBadShiftAmt2 2850// CHECK: arith.shrsi 2851func.func @truncIShrSIToTrunciShrUIBadShiftAmt2(%a: i64) -> i32 { 2852 %c31 = arith.constant 31: i64 2853 %sh = arith.shrsi %a, %c31 : i64 2854 %hi = arith.trunci %sh: i64 to i32 2855 return %hi : i32 2856} 2857 2858// CHECK-LABEL: @wideMulToMulSIExtended 2859// CHECK-SAME: (%[[A:.+]]: i32, %[[B:.+]]: i32) 2860// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[A]], %[[B]] : i32 2861// CHECK-NEXT: return %[[HIGH]] : i32 2862func.func @wideMulToMulSIExtended(%a: i32, %b: i32) -> i32 { 2863 %x = arith.extsi %a: i32 to i64 2864 %y = arith.extsi %b: i32 to i64 2865 %m = arith.muli %x, %y: i64 2866 %c32 = arith.constant 32: i64 2867 %sh = arith.shrui %m, %c32 : i64 2868 %hi = arith.trunci %sh: i64 to i32 2869 return %hi : i32 2870} 2871 2872// CHECK-LABEL: @wideMulToMulSIExtendedVector 2873// CHECK-SAME: (%[[A:.+]]: vector<3xi32>, %[[B:.+]]: vector<3xi32>) 2874// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mulsi_extended %[[A]], %[[B]] : vector<3xi32> 2875// CHECK-NEXT: return %[[HIGH]] : vector<3xi32> 2876func.func @wideMulToMulSIExtendedVector(%a: vector<3xi32>, %b: vector<3xi32>) -> vector<3xi32> { 2877 %x = arith.extsi %a: vector<3xi32> to vector<3xi64> 2878 %y = arith.extsi %b: vector<3xi32> to vector<3xi64> 2879 %m = arith.muli %x, %y: vector<3xi64> 2880 %c32 = arith.constant dense<32>: vector<3xi64> 2881 %sh = arith.shrui %m, %c32 : vector<3xi64> 2882 %hi = arith.trunci %sh: vector<3xi64> to vector<3xi32> 2883 return %hi : vector<3xi32> 2884} 2885 2886// CHECK-LABEL: @wideMulToMulUIExtended 2887// CHECK-SAME: (%[[A:.+]]: i32, %[[B:.+]]: i32) 2888// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mului_extended %[[A]], %[[B]] : i32 2889// CHECK-NEXT: return %[[HIGH]] : i32 2890func.func @wideMulToMulUIExtended(%a: i32, %b: i32) -> i32 { 2891 %x = arith.extui %a: i32 to i64 2892 %y = arith.extui %b: i32 to i64 2893 %m = arith.muli %x, %y: i64 2894 %c32 = arith.constant 32: i64 2895 %sh = arith.shrui %m, %c32 : i64 2896 %hi = arith.trunci %sh: i64 to i32 2897 return %hi : i32 2898} 2899 2900// CHECK-LABEL: @wideMulToMulUIExtendedVector 2901// CHECK-SAME: (%[[A:.+]]: vector<3xi32>, %[[B:.+]]: vector<3xi32>) 2902// CHECK-NEXT: %[[LOW:.+]], %[[HIGH:.+]] = arith.mului_extended %[[A]], %[[B]] : vector<3xi32> 2903// CHECK-NEXT: return %[[HIGH]] : vector<3xi32> 2904func.func @wideMulToMulUIExtendedVector(%a: vector<3xi32>, %b: vector<3xi32>) -> vector<3xi32> { 2905 %x = arith.extui %a: vector<3xi32> to vector<3xi64> 2906 %y = arith.extui %b: vector<3xi32> to vector<3xi64> 2907 %m = arith.muli %x, %y: vector<3xi64> 2908 %c32 = arith.constant dense<32>: vector<3xi64> 2909 %sh = arith.shrui %m, %c32 : vector<3xi64> 2910 %hi = arith.trunci %sh: vector<3xi64> to vector<3xi32> 2911 return %hi : vector<3xi32> 2912} 2913 2914// CHECK-LABEL: @wideMulToMulIExtendedMixedExt 2915// CHECK: arith.muli 2916// CHECK: arith.shrui 2917// CHECK: arith.trunci 2918func.func @wideMulToMulIExtendedMixedExt(%a: i32, %b: i32) -> i32 { 2919 %x = arith.extsi %a: i32 to i64 2920 %y = arith.extui %b: i32 to i64 2921 %m = arith.muli %x, %y: i64 2922 %c32 = arith.constant 32: i64 2923 %sh = arith.shrui %m, %c32 : i64 2924 %hi = arith.trunci %sh: i64 to i32 2925 return %hi : i32 2926} 2927 2928// CHECK-LABEL: @wideMulToMulSIExtendedBadExt 2929// CHECK: arith.muli 2930// CHECK: arith.shrui 2931// CHECK: arith.trunci 2932func.func @wideMulToMulSIExtendedBadExt(%a: i16, %b: i16) -> i32 { 2933 %x = arith.extsi %a: i16 to i64 2934 %y = arith.extsi %b: i16 to i64 2935 %m = arith.muli %x, %y: i64 2936 %c32 = arith.constant 32: i64 2937 %sh = arith.shrui %m, %c32 : i64 2938 %hi = arith.trunci %sh: i64 to i32 2939 return %hi : i32 2940} 2941 2942// CHECK-LABEL: @wideMulToMulSIExtendedBadShift1 2943// CHECK: arith.muli 2944// CHECK: arith.shrui 2945// CHECK: arith.trunci 2946func.func @wideMulToMulSIExtendedBadShift1(%a: i32, %b: i32) -> i32 { 2947 %x = arith.extsi %a: i32 to i64 2948 %y = arith.extsi %b: i32 to i64 2949 %m = arith.muli %x, %y: i64 2950 %c33 = arith.constant 33: i64 2951 %sh = arith.shrui %m, %c33 : i64 2952 %hi = arith.trunci %sh: i64 to i32 2953 return %hi : i32 2954} 2955 2956// CHECK-LABEL: @wideMulToMulSIExtendedBadShift2 2957// CHECK: arith.muli 2958// CHECK: arith.shrui 2959// CHECK: arith.trunci 2960func.func @wideMulToMulSIExtendedBadShift2(%a: i32, %b: i32) -> i32 { 2961 %x = arith.extsi %a: i32 to i64 2962 %y = arith.extsi %b: i32 to i64 2963 %m = arith.muli %x, %y: i64 2964 %c31 = arith.constant 31: i64 2965 %sh = arith.shrui %m, %c31 : i64 2966 %hi = arith.trunci %sh: i64 to i32 2967 return %hi : i32 2968} 2969 2970// CHECK-LABEL: @foldShli0 2971// CHECK-SAME: (%[[ARG:.*]]: i64) 2972// CHECK: return %[[ARG]] : i64 2973func.func @foldShli0(%x : i64) -> i64 { 2974 %c0 = arith.constant 0 : i64 2975 %r = arith.shli %x, %c0 : i64 2976 return %r : i64 2977} 2978 2979// CHECK-LABEL: @foldShrui0 2980// CHECK-SAME: (%[[ARG:.*]]: i64) 2981// CHECK: return %[[ARG]] : i64 2982func.func @foldShrui0(%x : i64) -> i64 { 2983 %c0 = arith.constant 0 : i64 2984 %r = arith.shrui %x, %c0 : i64 2985 return %r : i64 2986} 2987 2988// CHECK-LABEL: @foldShrsi0 2989// CHECK-SAME: (%[[ARG:.*]]: i64) 2990// CHECK: return %[[ARG]] : i64 2991func.func @foldShrsi0(%x : i64) -> i64 { 2992 %c0 = arith.constant 0 : i64 2993 %r = arith.shrsi %x, %c0 : i64 2994 return %r : i64 2995} 2996 2997// CHECK-LABEL: @foldOrXor1 2998// CHECK-SAME: (%[[ARG:.*]]: i1) 2999// CHECK: %[[ONE:.*]] = arith.constant true 3000// CHECK: return %[[ONE]] 3001func.func @foldOrXor1(%arg0: i1) -> i1 { 3002 %0 = arith.constant true 3003 %1 = arith.xori %arg0, %0 : i1 3004 %2 = arith.ori %arg0, %1 : i1 3005 return %2 : i1 3006} 3007 3008// CHECK-LABEL: @foldOrXor2 3009// CHECK-SAME: (%[[ARG:.*]]: i1) 3010// CHECK: %[[ONE:.*]] = arith.constant true 3011// CHECK: return %[[ONE]] 3012func.func @foldOrXor2(%arg0: i1) -> i1 { 3013 %0 = arith.constant true 3014 %1 = arith.xori %0, %arg0 : i1 3015 %2 = arith.ori %arg0, %1 : i1 3016 return %2 : i1 3017} 3018 3019// CHECK-LABEL: @foldOrXor3 3020// CHECK-SAME: (%[[ARG:.*]]: i1) 3021// CHECK: %[[ONE:.*]] = arith.constant true 3022// CHECK: return %[[ONE]] 3023func.func @foldOrXor3(%arg0: i1) -> i1 { 3024 %0 = arith.constant true 3025 %1 = arith.xori %arg0, %0 : i1 3026 %2 = arith.ori %1, %arg0 : i1 3027 return %2 : i1 3028} 3029 3030// CHECK-LABEL: @foldOrXor4 3031// CHECK-SAME: (%[[ARG:.*]]: i1) 3032// CHECK: %[[ONE:.*]] = arith.constant true 3033// CHECK: return %[[ONE]] 3034func.func @foldOrXor4(%arg0: i1) -> i1 { 3035 %0 = arith.constant true 3036 %1 = arith.xori %0, %arg0 : i1 3037 %2 = arith.ori %1, %arg0 : i1 3038 return %2 : i1 3039} 3040 3041// CHECK-LABEL: @foldOrXor5 3042// CHECK-SAME: (%[[ARG:.*]]: i32) 3043// CHECK: %[[ONE:.*]] = arith.constant -1 3044// CHECK: return %[[ONE]] 3045func.func @foldOrXor5(%arg0: i32) -> i32 { 3046 %0 = arith.constant -1 : i32 3047 %1 = arith.xori %arg0, %0 : i32 3048 %2 = arith.ori %arg0, %1 : i32 3049 return %2 : i32 3050} 3051 3052// CHECK-LABEL: @foldOrXor6 3053// CHECK-SAME: (%[[ARG:.*]]: index) 3054// CHECK: %[[ONE:.*]] = arith.constant -1 3055// CHECK: return %[[ONE]] 3056func.func @foldOrXor6(%arg0: index) -> index { 3057 %0 = arith.constant -1 : index 3058 %1 = arith.xori %arg0, %0 : index 3059 %2 = arith.ori %arg0, %1 : index 3060 return %2 : index 3061} 3062 3063// CHECK-LABEL: @selectOfPoison 3064// CHECK-SAME: %[[ARG:[[:alnum:]]+]]: i32 3065// CHECK: %[[UB:.*]] = ub.poison : i32 3066// CHECK: return %[[ARG]], %[[ARG]], %[[UB]], %[[ARG]] 3067func.func @selectOfPoison(%cond : i1, %arg: i32) -> (i32, i32, i32, i32) { 3068 %poison = ub.poison : i32 3069 %select1 = arith.select %cond, %poison, %arg : i32 3070 %select2 = arith.select %cond, %arg, %poison : i32 3071 3072 // Check that constant folding is applied prior to poison handling. 3073 %true = arith.constant true 3074 %false = arith.constant false 3075 %select3 = arith.select %true, %poison, %arg : i32 3076 %select4 = arith.select %false, %poison, %arg : i32 3077 return %select1, %select2, %select3, %select4 : i32, i32, i32, i32 3078} 3079 3080// CHECK-LABEL: @addi_poison1 3081// CHECK: %[[P:.*]] = ub.poison : i32 3082// CHECK: return %[[P]] 3083func.func @addi_poison1(%arg: i32) -> i32 { 3084 %0 = ub.poison : i32 3085 %1 = arith.addi %0, %arg : i32 3086 return %1 : i32 3087} 3088 3089// CHECK-LABEL: @addi_poison2 3090// CHECK: %[[P:.*]] = ub.poison : i32 3091// CHECK: return %[[P]] 3092func.func @addi_poison2(%arg: i32) -> i32 { 3093 %0 = ub.poison : i32 3094 %1 = arith.addi %arg, %0 : i32 3095 return %1 : i32 3096} 3097 3098// CHECK-LABEL: @addf_poison1 3099// CHECK: %[[P:.*]] = ub.poison : f32 3100// CHECK: return %[[P]] 3101func.func @addf_poison1(%arg: f32) -> f32 { 3102 %0 = ub.poison : f32 3103 %1 = arith.addf %0, %arg : f32 3104 return %1 : f32 3105} 3106 3107// CHECK-LABEL: @addf_poison2 3108// CHECK: %[[P:.*]] = ub.poison : f32 3109// CHECK: return %[[P]] 3110func.func @addf_poison2(%arg: f32) -> f32 { 3111 %0 = ub.poison : f32 3112 %1 = arith.addf %arg, %0 : f32 3113 return %1 : f32 3114} 3115 3116 3117// CHECK-LABEL: @negf_poison 3118// CHECK: %[[P:.*]] = ub.poison : f32 3119// CHECK: return %[[P]] 3120func.func @negf_poison() -> f32 { 3121 %0 = ub.poison : f32 3122 %1 = arith.negf %0 : f32 3123 return %1 : f32 3124} 3125 3126// CHECK-LABEL: @extsi_poison 3127// CHECK: %[[P:.*]] = ub.poison : i64 3128// CHECK: return %[[P]] 3129func.func @extsi_poison() -> i64 { 3130 %0 = ub.poison : i32 3131 %1 = arith.extsi %0 : i32 to i64 3132 return %1 : i64 3133} 3134 3135// Just checks that this doesn't crash. 3136// CHECK-LABEL: @unsignedExtendConstantResource 3137func.func @unsignedExtendConstantResource() -> tensor<i16> { 3138 %c2 = arith.constant dense_resource<blob1> : tensor<i8> 3139 %ext = arith.extui %c2 : tensor<i8> to tensor<i16> 3140 return %ext : tensor<i16> 3141} 3142 3143// CHECK-LABEL: @extsi_i0 3144// CHECK: %[[ZERO:.*]] = arith.constant 0 : i16 3145// CHECK: return %[[ZERO]] : i16 3146func.func @extsi_i0() -> i16 { 3147 %c0 = arith.constant 0 : i0 3148 %extsi = arith.extsi %c0 : i0 to i16 3149 return %extsi : i16 3150} 3151 3152// CHECK-LABEL: @extui_i0 3153// CHECK: %[[ZERO:.*]] = arith.constant 0 : i16 3154// CHECK: return %[[ZERO]] : i16 3155func.func @extui_i0() -> i16 { 3156 %c0 = arith.constant 0 : i0 3157 %extui = arith.extui %c0 : i0 to i16 3158 return %extui : i16 3159} 3160 3161// CHECK-LABEL: @trunc_i0 3162// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0 3163// CHECK: return %[[ZERO]] : i0 3164func.func @trunc_i0() -> i0 { 3165 %cFF = arith.constant 0xFF : i8 3166 %trunc = arith.trunci %cFF : i8 to i0 3167 return %trunc : i0 3168} 3169 3170// CHECK-LABEL: @shli_i0 3171// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0 3172// CHECK: return %[[ZERO]] : i0 3173func.func @shli_i0() -> i0 { 3174 %c0 = arith.constant 0 : i0 3175 %shli = arith.shli %c0, %c0 : i0 3176 return %shli : i0 3177} 3178 3179// CHECK-LABEL: @shrsi_i0 3180// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0 3181// CHECK: return %[[ZERO]] : i0 3182func.func @shrsi_i0() -> i0 { 3183 %c0 = arith.constant 0 : i0 3184 %shrsi = arith.shrsi %c0, %c0 : i0 3185 return %shrsi : i0 3186} 3187 3188// CHECK-LABEL: @shrui_i0 3189// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0 3190// CHECK: return %[[ZERO]] : i0 3191func.func @shrui_i0() -> i0 { 3192 %c0 = arith.constant 0 : i0 3193 %shrui = arith.shrui %c0, %c0 : i0 3194 return %shrui : i0 3195} 3196 3197// CHECK-LABEL: @maxsi_i0 3198// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0 3199// CHECK: return %[[ZERO]] : i0 3200func.func @maxsi_i0() -> i0 { 3201 %c0 = arith.constant 0 : i0 3202 %maxsi = arith.maxsi %c0, %c0 : i0 3203 return %maxsi : i0 3204} 3205 3206// CHECK-LABEL: @minsi_i0 3207// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0 3208// CHECK: return %[[ZERO]] : i0 3209func.func @minsi_i0() -> i0 { 3210 %c0 = arith.constant 0 : i0 3211 %minsi = arith.minsi %c0, %c0 : i0 3212 return %minsi : i0 3213} 3214 3215// CHECK-LABEL: @mulsi_extended_i0 3216// CHECK: %[[ZERO:.*]] = arith.constant 0 : i0 3217// CHECK: return %[[ZERO]], %[[ZERO]] : i0 3218func.func @mulsi_extended_i0() -> (i0, i0) { 3219 %c0 = arith.constant 0 : i0 3220 %mulsi_extended:2 = arith.mulsi_extended %c0, %c0 : i0 3221 return %mulsi_extended#0, %mulsi_extended#1 : i0, i0 3222} 3223 3224// CHECK-LABEL: @sequences_fastmath_contract 3225// CHECK-SAME: ([[ARG0:%.+]]: bf16) 3226// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]] 3227// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]] 3228// CHECK: [[SIN:%.+]] = math.sin [[ABSF]] 3229// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]] 3230// CHECK: return [[TRUNCF]] : bf16 3231func.func @sequences_fastmath_contract(%arg0: bf16) -> bf16 { 3232 %0 = arith.extf %arg0 fastmath<contract> : bf16 to f32 3233 %1 = math.absf %0 : f32 3234 %2 = arith.truncf %1 fastmath<contract> : f32 to bf16 3235 %3 = arith.extf %2 fastmath<contract> : bf16 to f32 3236 %4 = math.sin %3 : f32 3237 %5 = arith.truncf %4 fastmath<contract> : f32 to bf16 3238 return %5 : bf16 3239} 3240 3241// CHECK-LABEL: @sequences_no_fastmath 3242// CHECK-SAME: ([[ARG0:%.+]]: bf16) 3243// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]] 3244// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]] 3245// CHECK: [[TRUNCF1:%.+]] = arith.truncf [[ABSF]] 3246// CHECK: [[EXTF1:%.+]] = arith.extf [[TRUNCF1]] 3247// CHECK: [[SIN:%.+]] = math.sin [[EXTF1]] 3248// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]] 3249// CHECK: return [[TRUNCF]] : bf16 3250func.func @sequences_no_fastmath(%arg0: bf16) -> bf16 { 3251 %0 = arith.extf %arg0 : bf16 to f32 3252 %1 = math.absf %0 : f32 3253 %2 = arith.truncf %1 : f32 to bf16 3254 %3 = arith.extf %2 : bf16 to f32 3255 %4 = math.sin %3 : f32 3256 %5 = arith.truncf %4 : f32 to bf16 3257 return %5 : bf16 3258} 3259 3260// CHECK-LABEL: @eliminate_cast_to_f16 3261// CHECK: return [[arg0:%.+]] : f32 3262func.func @eliminate_cast_to_f16(%arg0: f32) -> f32 { 3263 %0 = arith.truncf %arg0 fastmath<contract> : f32 to f16 3264 %1 = arith.extf %0 fastmath<contract> : f16 to f32 3265 return %1 : f32 3266} 3267 3268// CHECK-LABEL: @eliminate_cast_to_bf16 3269// CHECK: return [[arg0:%.+]] : f32 3270func.func @eliminate_cast_to_bf16(%arg0: f32) -> f32 { 3271 %0 = arith.truncf %arg0 fastmath<contract> : f32 to bf16 3272 %1 = arith.extf %0 fastmath<contract> : bf16 to f32 3273 return %1 : f32 3274} 3275 3276// CHECK-LABEL: @bf16_sin_vector 3277// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>) 3278// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]] 3279// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]] 3280// CHECK: [[SIN:%.+]] = math.sin [[ABSF]] 3281// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]] 3282// CHECK: return [[TRUNCF]] : vector<32x32x32xbf16> 3283func.func @bf16_sin_vector(%arg0: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> { 3284 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3285 %1 = math.absf %0 : vector<32x32x32xf32> 3286 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3287 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3288 %4 = math.sin %3 : vector<32x32x32xf32> 3289 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3290 return %5 : vector<32x32x32xbf16> 3291} 3292 3293// CHECK-LABEL: @f16_sin_vector 3294// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xf16>) 3295// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]] 3296// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]] 3297// CHECK: [[SIN:%.+]] = math.sin [[ABSF]] 3298// CHECK: [[TRUNCF:%.+]] = arith.truncf [[SIN]] 3299// CHECK: return [[TRUNCF]] : vector<32x32x32xf16> 3300func.func @f16_sin_vector(%arg0: vector<32x32x32xf16>) -> vector<32x32x32xf16> { 3301 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xf16> to vector<32x32x32xf32> 3302 %1 = math.absf %0 : vector<32x32x32xf32> 3303 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xf16> 3304 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xf16> to vector<32x32x32xf32> 3305 %4 = math.sin %3 : vector<32x32x32xf32> 3306 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xf16> 3307 return %5 : vector<32x32x32xf16> 3308} 3309 3310// CHECK-LABEL: @bf16_branch_vector 3311// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>) 3312// CHECK: [[EXTF:%.+]] = arith.extf [[ARG0]] 3313// CHECK: [[ABSF:%.+]] = math.absf [[EXTF]] 3314// CHECK-DAG: [[SIN:%.+]] = math.sin [[ABSF]] 3315// CHECK-DAG: [[COS:%.+]] = math.cos [[ABSF]] 3316// CHECK: [[ADDF:%.+]] = arith.addf [[SIN]], [[COS]] 3317// CHECK: [[TRUNCF:%.+]] = arith.truncf [[ADDF]] 3318// CHECK: return [[TRUNCF]] : vector<32x32x32xbf16> 3319func.func @bf16_branch_vector(%arg0: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> { 3320 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3321 %1 = math.absf %0 : vector<32x32x32xf32> 3322 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3323 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3324 %4 = math.sin %3 : vector<32x32x32xf32> 3325 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3326 %6 = arith.extf %5 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3327 %7 = math.cos %3 : vector<32x32x32xf32> 3328 %8 = arith.truncf %7 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3329 %9 = arith.extf %8 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3330 %10 = arith.addf %6, %9 : vector<32x32x32xf32> 3331 %11 = arith.truncf %10 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3332 return %11 : vector<32x32x32xbf16> 3333} 3334 3335// CHECK-LABEL: @bf16_fma 3336// CHECK-SAME: ([[ARG0:%.+]]: vector<32x32x32xbf16>, [[ARG1:%.+]]: vector<32x32x32xbf16>, [[ARG2:%.+]]: vector<32x32x32xbf16>) 3337// CHECK: [[EXTF0:%.+]] = arith.extf [[ARG0]] 3338// CHECK: [[ABSF:%.+]] = math.absf [[EXTF0]] 3339// CHECK-DAG: [[SIN:%.+]] = math.sin [[ABSF]] 3340// CHECK: [[TRUNCF0:%.+]] = arith.truncf [[SIN]] 3341// CHECK-DAG: [[FMA:%.+]] = math.fma [[TRUNCF0]], [[ARG1]], [[ARG2]] 3342// CHECK: [[EXTF1:%.+]] = arith.extf [[FMA]] 3343// CHECK: [[ADDF:%.+]] = arith.addf [[EXTF1]], [[SIN]] 3344// CHECK: [[TRUNCF1:%.+]] = arith.truncf [[ADDF]] 3345// CHECK: return [[TRUNCF1]] : vector<32x32x32xbf16> 3346func.func @bf16_fma(%arg0: vector<32x32x32xbf16>, %arg1: vector<32x32x32xbf16>, %arg2: vector<32x32x32xbf16>) -> vector<32x32x32xbf16> { 3347 %0 = arith.extf %arg0 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3348 %1 = math.absf %0 : vector<32x32x32xf32> 3349 %2 = arith.truncf %1 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3350 %3 = arith.extf %2 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3351 %4 = math.sin %3 : vector<32x32x32xf32> 3352 %5 = arith.truncf %4 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3353 %6 = arith.extf %5 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3354 %7 = math.fma %5, %arg1, %arg2 : vector<32x32x32xbf16> 3355 %8 = arith.extf %7 fastmath<contract> : vector<32x32x32xbf16> to vector<32x32x32xf32> 3356 %9 = arith.addf %8, %6 : vector<32x32x32xf32> 3357 %10 = arith.truncf %9 fastmath<contract> : vector<32x32x32xf32> to vector<32x32x32xbf16> 3358 return %10 : vector<32x32x32xbf16> 3359} 3360 3361{-# 3362 dialect_resources: { 3363 builtin: { 3364 // Note: This is just copied blob, the actual value isn't used or checked. 3365 blob1: "0x08000000010000000000000002000000000000000300000000000000" 3366 } 3367 } 3368#-} 3369