1f3bdb56dSRob Suderman// RUN: mlir-opt %s --split-input-file -test-expand-math | FileCheck %s 2f3bdb56dSRob Suderman 3f3bdb56dSRob Suderman// CHECK-LABEL: func @tanh 4f3bdb56dSRob Sudermanfunc.func @tanh(%arg: f32) -> f32 { 5f3bdb56dSRob Suderman %res = math.tanh %arg : f32 6f3bdb56dSRob Suderman return %res : f32 7f3bdb56dSRob Suderman} 8f3bdb56dSRob Suderman// CHECK-DAG: %[[ZERO:.+]] = arith.constant 0.000000e+00 : f32 9f3bdb56dSRob Suderman// CHECK-DAG: %[[ONE:.+]] = arith.constant 1.000000e+00 : f32 10d39ac3a8Ssrcarroll// CHECK-DAG: %[[TWO:.+]] = arith.constant -2.000000e+00 : f32 11d39ac3a8Ssrcarroll// CHECK: %[[VAL0:.+]] = arith.cmpf olt, %arg0, %[[ZERO]] : f32 12d39ac3a8Ssrcarroll// CHECK: %[[VAL1:.+]] = arith.uitofp %[[VAL0]] : i1 to f32 13d39ac3a8Ssrcarroll// CHECK: %[[VAL2:.+]] = arith.mulf %[[VAL1]], %[[TWO]] : f32 14d39ac3a8Ssrcarroll// CHECK: %[[SIGN:.+]] = arith.addf %[[VAL2]], %[[ONE]] : f32 15d39ac3a8Ssrcarroll// CHECK: %[[POSX:.+]] = arith.mulf %[[SIGN]], %arg0 : f32 16d39ac3a8Ssrcarroll// CHECK: %[[NEGDOUBLEDX:.+]] = arith.mulf %[[POSX]], %[[TWO]] : f32 17f3bdb56dSRob Suderman// CHECK: %[[EXP1:.+]] = math.exp %[[NEGDOUBLEDX]] : f32 18f3bdb56dSRob Suderman// CHECK: %[[DIVIDEND1:.+]] = arith.subf %[[ONE]], %[[EXP1]] : f32 19f3bdb56dSRob Suderman// CHECK: %[[DIVISOR1:.+]] = arith.addf %[[EXP1]], %[[ONE]] : f32 20d39ac3a8Ssrcarroll// CHECK: %[[POSRES:.+]] = arith.divf %[[DIVIDEND1]], %[[DIVISOR1]] : f32 21d39ac3a8Ssrcarroll// CHECK: %[[RESULT:.+]] = arith.mulf %[[SIGN]], %[[POSRES]] : f32 22f3bdb56dSRob Suderman// CHECK: return %[[RESULT]] 23f3bdb56dSRob Suderman 24ed9194beSMatthias Springer// ----- 25f3bdb56dSRob Suderman 26711c5893SRobert Suderman 27711c5893SRobert Suderman// CHECK-LABEL: func @vector_tanh 28711c5893SRobert Sudermanfunc.func @vector_tanh(%arg: vector<4xf32>) -> vector<4xf32> { 29711c5893SRobert Suderman // CHECK-NOT: math.tanh 30711c5893SRobert Suderman %res = math.tanh %arg : vector<4xf32> 31711c5893SRobert Suderman return %res : vector<4xf32> 32711c5893SRobert Suderman} 33711c5893SRobert Suderman 34711c5893SRobert Suderman// ----- 35711c5893SRobert Suderman 36740e2e90SRobert Suderman// CHECK-LABEL: func @tan 37740e2e90SRobert Sudermanfunc.func @tan(%arg: f32) -> f32 { 38740e2e90SRobert Suderman %res = math.tan %arg : f32 39740e2e90SRobert Suderman return %res : f32 40740e2e90SRobert Suderman} 41740e2e90SRobert Suderman 42740e2e90SRobert Suderman// CHECK-SAME: %[[ARG0:.+]]: f32 43740e2e90SRobert Suderman// CHECK: %[[SIN:.+]] = math.sin %[[ARG0]] 44740e2e90SRobert Suderman// CHECK: %[[COS:.+]] = math.cos %[[ARG0]] 45711c5893SRobert Suderman// CHECK: %[[DIV:.+]] = arith.divf %[[SIN]], %[[COS]] 46711c5893SRobert Suderman 47740e2e90SRobert Suderman 48740e2e90SRobert Suderman// ----- 49740e2e90SRobert Suderman 50711c5893SRobert Suderman// CHECK-LABEL: func @vector_tan 51711c5893SRobert Sudermanfunc.func @vector_tan(%arg: vector<4xf32>) -> vector<4xf32> { 52711c5893SRobert Suderman %res = math.tan %arg : vector<4xf32> 53711c5893SRobert Suderman return %res : vector<4xf32> 54711c5893SRobert Suderman} 55f3bdb56dSRob Suderman 56711c5893SRobert Suderman// CHECK-NOT: math.tan 57711c5893SRobert Suderman 58711c5893SRobert Suderman// ----- 59711c5893SRobert Suderman 60711c5893SRobert Sudermanfunc.func @ctlz(%arg: i32) -> i32 { 61711c5893SRobert Suderman %res = math.ctlz %arg : i32 62f3bdb56dSRob Suderman return %res : i32 63f3bdb56dSRob Suderman} 64711c5893SRobert Suderman 65711c5893SRobert Suderman// CHECK-LABEL: @ctlz 66711c5893SRobert Suderman// CHECK-SAME: %[[ARG0:.+]]: i32 67bb6d5c22SMatthias Springer// CHECK-DAG: %[[C0:.+]] = arith.constant 0 : i32 68bb6d5c22SMatthias Springer// CHECK-DAG: %[[C16:.+]] = arith.constant 16 : i32 69bb6d5c22SMatthias Springer// CHECK-DAG: %[[C65535:.+]] = arith.constant 65535 : i32 70bb6d5c22SMatthias Springer// CHECK-DAG: %[[C8:.+]] = arith.constant 8 : i32 71bb6d5c22SMatthias Springer// CHECK-DAG: %[[C16777215:.+]] = arith.constant 16777215 : i32 72bb6d5c22SMatthias Springer// CHECK-DAG: %[[C4:.+]] = arith.constant 4 : i32 73bb6d5c22SMatthias Springer// CHECK-DAG: %[[C268435455:.+]] = arith.constant 268435455 : i32 74bb6d5c22SMatthias Springer// CHECK-DAG: %[[C2:.+]] = arith.constant 2 : i32 75bb6d5c22SMatthias Springer// CHECK-DAG: %[[C1073741823:.+]] = arith.constant 1073741823 : i32 76bb6d5c22SMatthias Springer// CHECK-DAG: %[[C1:.+]] = arith.constant 1 : i32 77bb6d5c22SMatthias Springer// CHECK-DAG: %[[C2147483647:.+]] = arith.constant 2147483647 : i32 78bb6d5c22SMatthias Springer// CHECK-DAG: %[[C32:.+]] = arith.constant 32 : i32 79711c5893SRobert Suderman 80711c5893SRobert Suderman// CHECK: %[[PRED:.+]] = arith.cmpi ule, %[[ARG0]], %[[C65535]] 81711c5893SRobert Suderman// CHECK: %[[SHL:.+]] = arith.shli %[[ARG0]], %[[C16]] 82711c5893SRobert Suderman// CHECK: %[[SELX0:.+]] = arith.select %[[PRED]], %[[SHL]], %[[ARG0]] 83711c5893SRobert Suderman// CHECK: %[[SELY0:.+]] = arith.select %[[PRED]], %[[C16]], %[[C0]] 84711c5893SRobert Suderman 85711c5893SRobert Suderman// CHECK: %[[PRED:.+]] = arith.cmpi ule, %[[SELX0]], %[[C16777215]] 86711c5893SRobert Suderman// CHECK: %[[ADD:.+]] = arith.addi %[[SELY0]], %[[C8]] 87711c5893SRobert Suderman// CHECK: %[[SHL:.+]] = arith.shli %[[SELX0]], %[[C8]] 88711c5893SRobert Suderman// CHECK: %[[SELX1:.+]] = arith.select %[[PRED]], %[[SHL]], %[[SELX0]] 89711c5893SRobert Suderman// CHECK: %[[SELY1:.+]] = arith.select %[[PRED]], %[[ADD]], %[[SELY0]] 90711c5893SRobert Suderman 91711c5893SRobert Suderman// CHECK: %[[PRED:.+]] = arith.cmpi ule, %[[SELX1]], %[[C268435455]] : i32 92711c5893SRobert Suderman// CHECK: %[[ADD:.+]] = arith.addi %[[SELY1]], %[[C4]] 93711c5893SRobert Suderman// CHECK: %[[SHL:.+]] = arith.shli %[[SELX1]], %[[C4]] 94711c5893SRobert Suderman// CHECK: %[[SELX2:.+]] = arith.select %[[PRED]], %[[SHL]], %[[SELX1]] 95711c5893SRobert Suderman// CHECK: %[[SELY2:.+]] = arith.select %[[PRED]], %[[ADD]], %[[SELY1]] 96711c5893SRobert Suderman 97711c5893SRobert Suderman 98711c5893SRobert Suderman// CHECK: %[[PRED:.+]] = arith.cmpi ule, %[[SELX2]], %[[C1073741823]] : i32 99711c5893SRobert Suderman// CHECK: %[[ADD:.+]] = arith.addi %[[SELY2]], %[[C2]] 100711c5893SRobert Suderman// CHECK: %[[SHL:.+]] = arith.shli %[[SELX2]], %[[C2]] 101711c5893SRobert Suderman// CHECK: %[[SELX3:.+]] = arith.select %[[PRED]], %[[SHL]], %[[SELX2]] 102711c5893SRobert Suderman// CHECK: %[[SELY3:.+]] = arith.select %[[PRED]], %[[ADD]], %[[SELY2]] 103711c5893SRobert Suderman 104711c5893SRobert Suderman// CHECK: %[[PRED:.+]] = arith.cmpi ule, %[[SELX3]], %[[C2147483647]] : i32 105711c5893SRobert Suderman// CHECK: %[[ADD:.+]] = arith.addi %[[SELY3]], %[[C1]] 106711c5893SRobert Suderman// CHECK: %[[SELY4:.+]] = arith.select %[[PRED]], %[[ADD]], %[[SELY3]] 107711c5893SRobert Suderman 108711c5893SRobert Suderman// CHECK: %[[PRED:.+]] = arith.cmpi eq, %[[ARG0]], %[[C0]] : i32 109711c5893SRobert Suderman// CHECK: %[[SEL:.+]] = arith.select %[[PRED]], %[[C32]], %[[SELY4]] : i32 110711c5893SRobert Suderman// CHECK: return %[[SEL]] 111711c5893SRobert Suderman 112711c5893SRobert Suderman// ----- 113711c5893SRobert Suderman 114711c5893SRobert Sudermanfunc.func @ctlz_vector(%arg: vector<4xi32>) -> vector<4xi32> { 115711c5893SRobert Suderman %res = math.ctlz %arg : vector<4xi32> 116711c5893SRobert Suderman return %res : vector<4xi32> 117711c5893SRobert Suderman} 118711c5893SRobert Suderman 119711c5893SRobert Suderman// CHECK-LABEL: @ctlz_vector 120711c5893SRobert Suderman// CHECK-NOT: math.ctlz 121a7c2102dSBalaji V. Iyer 122a7c2102dSBalaji V. Iyer// ----- 123a7c2102dSBalaji V. Iyer 124a7c2102dSBalaji V. Iyer// CHECK-LABEL: func @fmaf_func 125a7c2102dSBalaji V. Iyer// CHECK-SAME: ([[ARG0:%.+]]: f64, [[ARG1:%.+]]: f64, [[ARG2:%.+]]: f64) -> f64 126a7c2102dSBalaji V. Iyerfunc.func @fmaf_func(%a: f64, %b: f64, %c: f64) -> f64 { 127a7c2102dSBalaji V. Iyer // CHECK-NEXT: [[MULF:%.+]] = arith.mulf [[ARG0]], [[ARG1]] 128a7c2102dSBalaji V. Iyer // CHECK-NEXT: [[ADDF:%.+]] = arith.addf [[MULF]], [[ARG2]] 129a7c2102dSBalaji V. Iyer // CHECK-NEXT: return [[ADDF]] 130a7c2102dSBalaji V. Iyer %ret = math.fma %a, %b, %c : f64 131a7c2102dSBalaji V. Iyer return %ret : f64 132a7c2102dSBalaji V. Iyer} 133af9eb1e3SBalaji V. Iyer 134af9eb1e3SBalaji V. Iyer// ----- 135af9eb1e3SBalaji V. Iyer 1362217888dSBalaji V. Iyer// CHECK-LABEL: func @ceilf_func 1372217888dSBalaji V. Iyer// CHECK-SAME: ([[ARG0:%.+]]: f64) -> f64 1382217888dSBalaji V. Iyerfunc.func @ceilf_func(%a: f64) -> f64 { 1392217888dSBalaji V. Iyer // CHECK-DAG: [[CST:%.+]] = arith.constant 0.000 1402217888dSBalaji V. Iyer // CHECK-DAG: [[CST_0:%.+]] = arith.constant 1.000 1412217888dSBalaji V. Iyer // CHECK-NEXT: [[CVTI:%.+]] = arith.fptosi [[ARG0]] 1422217888dSBalaji V. Iyer // CHECK-NEXT: [[CVTF:%.+]] = arith.sitofp [[CVTI]] 14344baa655SRamiro Leal-Cavazos // CHECK-NEXT: [[COPYSIGN:%.+]] = math.copysign [[CVTF]], [[ARG0]] 14444baa655SRamiro Leal-Cavazos // CHECK-NEXT: [[COMP:%.+]] = arith.cmpf ogt, [[ARG0]], [[COPYSIGN]] 1452217888dSBalaji V. Iyer // CHECK-NEXT: [[INCR:%.+]] = arith.select [[COMP]], [[CST_0]], [[CST]] 14644baa655SRamiro Leal-Cavazos // CHECK-NEXT: [[ADDF:%.+]] = arith.addf [[COPYSIGN]], [[INCR]] 1472217888dSBalaji V. Iyer // CHECK-NEXT: return [[ADDF]] 1482217888dSBalaji V. Iyer %ret = math.ceil %a : f64 1492217888dSBalaji V. Iyer return %ret : f64 1502217888dSBalaji V. Iyer} 1514da96515SBalaji V. Iyer 1524da96515SBalaji V. Iyer// ----- 1534da96515SBalaji V. Iyer 1544da96515SBalaji V. Iyer// CHECK-LABEL: func @exp2f_func 1554da96515SBalaji V. Iyer// CHECK-SAME: ([[ARG0:%.+]]: f64) -> f64 1564da96515SBalaji V. Iyerfunc.func @exp2f_func(%a: f64) -> f64 { 1574da96515SBalaji V. Iyer // CHECK-DAG: [[CST:%.+]] = arith.constant 0.69314718055994529 1584da96515SBalaji V. Iyer // CHECK: [[MULF:%.+]] = arith.mulf [[ARG0]], [[CST]] 1594da96515SBalaji V. Iyer // CHECK: [[EXP:%.+]] = math.exp [[MULF]] 1604da96515SBalaji V. Iyer // CHECK: return [[EXP]] 1614da96515SBalaji V. Iyer %ret = math.exp2 %a : f64 1624da96515SBalaji V. Iyer return %ret : f64 1634da96515SBalaji V. Iyer} 1644da96515SBalaji V. Iyer 1654da96515SBalaji V. Iyer// CHECK-LABEL: func @exp2f_func_tensor 1664da96515SBalaji V. Iyer// CHECK-SAME: ([[ARG0:%.+]]: tensor<1xf32>) -> tensor<1xf32> 1674da96515SBalaji V. Iyerfunc.func @exp2f_func_tensor(%a: tensor<1xf32>) -> tensor<1xf32> { 1684da96515SBalaji V. Iyer // CHECK-DAG: [[CST:%.+]] = arith.constant dense<0.693147182> 1694da96515SBalaji V. Iyer // CHECK: [[MULF:%.+]] = arith.mulf [[ARG0]], [[CST]] 1704da96515SBalaji V. Iyer // CHECK: [[EXP:%.+]] = math.exp [[MULF]] 1714da96515SBalaji V. Iyer // CHECK: return [[EXP]] 1724da96515SBalaji V. Iyer %ret = math.exp2 %a : tensor<1xf32> 1734da96515SBalaji V. Iyer return %ret : tensor<1xf32> 1744da96515SBalaji V. Iyer} 175be911578SBalaji V. Iyer 176be911578SBalaji V. Iyer// ----- 177be911578SBalaji V. Iyer 178be911578SBalaji V. Iyer// CHECK-LABEL: func @roundf_func 17944baa655SRamiro Leal-Cavazos// CHECK-SAME: (%[[ARG0:.*]]: f32) -> f32 18044baa655SRamiro Leal-Cavazosfunc.func @roundf_func(%a: f32) -> f32 { 18144baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01 18244baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[C23:.*]] = arith.constant 23 18344baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[C127:.*]] = arith.constant 127 18444baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[EXP_MASK:.*]] = arith.constant 255 18544baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[SHIFT:.*]] = math.copysign %[[HALF]], %[[ARG0]] 18644baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[ARG_SHIFTED:.*]] = arith.addf %[[ARG0]], %[[SHIFT]] 18744baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[FIXED_CONVERT:.*]] = arith.fptosi %[[ARG_SHIFTED]] 18844baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[FP_FIXED_CONVERT_0:.*]] = arith.sitofp %[[FIXED_CONVERT]] 18944baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[FP_FIXED_CONVERT_1:.*]] = math.copysign %[[FP_FIXED_CONVERT_0]], %[[ARG_SHIFTED]] 19044baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[ARG_BITCAST:.*]] = arith.bitcast %[[ARG0]] : f32 to i32 19144baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[ARG_BITCAST_SHIFTED:.*]] = arith.shrui %[[ARG_BITCAST]], %[[C23]] 19244baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[ARG_EXP:.*]] = arith.andi %[[ARG_BITCAST_SHIFTED]], %[[EXP_MASK]] 19344baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[ARG_BIASED_EXP:.*]] = arith.subi %[[ARG_EXP]], %[[C127]] 19444baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[IS_SPECIAL_VAL:.*]] = arith.cmpi sge, %[[ARG_BIASED_EXP]], %[[C23]] 19544baa655SRamiro Leal-Cavazos // CHECK-DAG: %[[RESULT:.*]] = arith.select %[[IS_SPECIAL_VAL]], %[[ARG0]], %[[FP_FIXED_CONVERT_1]] 19644baa655SRamiro Leal-Cavazos // CHECK: return %[[RESULT]] 19744baa655SRamiro Leal-Cavazos %ret = math.round %a : f32 19844baa655SRamiro Leal-Cavazos return %ret : f32 199be911578SBalaji V. Iyer} 2002d4e8567SBalaji V. Iyer 2012d4e8567SBalaji V. Iyer// ----- 2022d4e8567SBalaji V. Iyer 2032d4e8567SBalaji V. Iyer// CHECK-LABEL: func @powf_func 2042d4e8567SBalaji V. Iyer// CHECK-SAME: ([[ARG0:%.+]]: f64, [[ARG1:%.+]]: f64) 2052d4e8567SBalaji V. Iyerfunc.func @powf_func(%a: f64, %b: f64) -> f64 { 206f0b0c025Sklensy // CHECK-DAG: [[CST0:%.+]] = arith.constant 0.000000e+00 207a92e3df3SChristopher Bate // CHECK-DAG: [[CST1:%.+]] = arith.constant 1.0 208*3a337757SHyunsung Lee // CHECK: [[LOGA:%.+]] = math.log [[ARG0]] 209*3a337757SHyunsung Lee // CHECK: [[MULB:%.+]] = arith.mulf [[ARG1]], [[LOGA]] 210*3a337757SHyunsung Lee // CHECK: [[EXP:%.+]] = math.exp [[MULB]] 211*3a337757SHyunsung Lee // CHECK: [[CMPF:%.+]] = arith.cmpf oeq, [[ARG1]], [[CST0]] 212*3a337757SHyunsung Lee // CHECK: [[SEL:%.+]] = arith.select [[CMPF]], [[CST1]], [[EXP]] 213*3a337757SHyunsung Lee // CHECK: return [[SEL]] 2142d4e8567SBalaji V. Iyer %ret = math.powf %a, %b : f64 2152d4e8567SBalaji V. Iyer return %ret : f64 2162d4e8567SBalaji V. Iyer} 21744baa655SRamiro Leal-Cavazos 21844baa655SRamiro Leal-Cavazos// ----- 21944baa655SRamiro Leal-Cavazos 220fe355a44SAlexander Shaposhnikov// CHECK-LABEL: func.func @roundeven64 221fe355a44SAlexander Shaposhnikovfunc.func @roundeven64(%arg: f64) -> f64 { 222fe355a44SAlexander Shaposhnikov %res = math.roundeven %arg : f64 223fe355a44SAlexander Shaposhnikov return %res : f64 224fe355a44SAlexander Shaposhnikov} 225fe355a44SAlexander Shaposhnikov 226fe355a44SAlexander Shaposhnikov// CHECK-SAME: %[[VAL_0:.*]]: f64) -> f64 { 227fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_0:.*]] = arith.constant 0 : i64 228fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_1:.*]] = arith.constant 1 : i64 229fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_NEG_1:.*]] = arith.constant -1 : i64 230fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_1_FLOAT:.*]] = arith.constant 1.000000e+00 : f64 231fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_52:.*]] = arith.constant 52 : i64 232fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_63:.*]] = arith.constant 63 : i64 233fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_1023:.*]] = arith.constant 1023 : i64 234fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_2251799813685248:.*]] = arith.constant 2251799813685248 : i64 235fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_4503599627370495:.*]] = arith.constant 4503599627370495 : i64 236fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[EXP_MASK:.*]] = arith.constant 2047 : i64 237fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_BITCAST:.*]] = arith.bitcast %[[VAL_0]] : f64 to i64 238fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND:.*]] = math.round %[[VAL_0]] : f64 239fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_BITCAST:.*]] = arith.bitcast %[[ROUND]] : f64 to i64 240fe355a44SAlexander Shaposhnikov 241fe355a44SAlexander Shaposhnikov// Get biased exponents of `round` and `operand` 242fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_OPERAND_BITCAST:.*]] = arith.shrui %[[OPERAND_BITCAST]], %[[C_52]] : i64 243fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_EXP:.*]] = arith.andi %[[SHIFTED_OPERAND_BITCAST]], %[[EXP_MASK]] : i64 244fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_BIASED_EXP:.*]] = arith.subi %[[OPERAND_EXP]], %[[C_1023]] : i64 245fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_ROUND_BITCAST:.*]] = arith.shrui %[[ROUND_BITCAST]], %[[C_52]] : i64 246fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_EXP:.*]] = arith.andi %[[SHIFTED_ROUND_BITCAST]], %[[EXP_MASK]] : i64 247fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_BIASED_EXP:.*]] = arith.subi %[[ROUND_EXP]], %[[C_1023]] : i64 248fe355a44SAlexander Shaposhnikov 249fe355a44SAlexander Shaposhnikov// Determine if `ROUND_BITCAST` is an even whole number or a special value 250fe355a44SAlexander Shaposhnikov// +-inf, +-nan. 251fe355a44SAlexander Shaposhnikov// Mask mantissa of `ROUND_BITCAST` with a mask shifted to the right by 252fe355a44SAlexander Shaposhnikov// `ROUND_BIASED_EXP - 1` 253fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_BIASED_EXP_MINUS_1:.*]] = arith.subi %[[ROUND_BIASED_EXP]], %[[C_1]] : i64 254fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[CLAMPED_SHIFT_0:.*]] = arith.maxsi %[[ROUND_BIASED_EXP_MINUS_1]], %[[C_0]] : i64 255fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[CLAMPED_SHIFT_1:.*]] = arith.minsi %[[CLAMPED_SHIFT_0]], %[[C_63]] : i64 256fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[SHIFTED_MANTISSA_MASK_0:.*]] = arith.shrui %[[C_4503599627370495]], %[[CLAMPED_SHIFT_1]] : i64 257fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_MASKED_MANTISSA:.*]] = arith.andi %[[ROUND_BITCAST]], %[[SHIFTED_MANTISSA_MASK_0]] : i64 258fe355a44SAlexander Shaposhnikov 259fe355a44SAlexander Shaposhnikov// `ROUND_BITCAST` is not even whole number or special value if masked 260fe355a44SAlexander Shaposhnikov// mantissa is != 0 or `ROUND_BIASED_EXP == 0` 261fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_0:.*]] = arith.cmpi ne, %[[ROUND_MASKED_MANTISSA]], %[[C_0]] : i64 262fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_BIASED_EXP_EQ_0:.*]] = arith.cmpi eq, %[[ROUND_BIASED_EXP]], %[[C_0]] : i64 263fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_1:.*]] = arith.ori %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_0]], %[[ROUND_BIASED_EXP_EQ_0]] : i1 264fe355a44SAlexander Shaposhnikov 265fe355a44SAlexander Shaposhnikov// Determine if operand is halfway between two integer values 266fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_BIASED_EXP_EQ_NEG_1:.*]] = arith.cmpi eq, %[[OPERAND_BIASED_EXP]], %[[C_NEG_1]] : i64 267fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_2:.*]] = arith.maxsi %[[OPERAND_BIASED_EXP]], %[[C_0]] : i64 268fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_3:.*]] = arith.minsi %[[CLAMPED_SHIFT_2]], %[[C_63]] : i64 269fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_2_TO_9:.*]] = arith.shrui %[[C_2251799813685248]], %[[CLAMPED_SHIFT_3]] : i64 270fe355a44SAlexander Shaposhnikov 271fe355a44SAlexander Shaposhnikov// CHECK: %[[EXPECTED_OPERAND_MASKED_MANTISSA:.*]] = arith.select %[[OPERAND_BIASED_EXP_EQ_NEG_1]], %[[C_0]], %[[SHIFTED_2_TO_9]] : i64 272fe355a44SAlexander Shaposhnikov 273fe355a44SAlexander Shaposhnikov// Mask mantissa of `OPERAND_BITCAST` with a mask shifted to the right by 274fe355a44SAlexander Shaposhnikov// `OPERAND_BIASED_EXP` 275fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_4:.*]] = arith.maxsi %[[OPERAND_BIASED_EXP]], %[[C_0]] : i64 276fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_5:.*]] = arith.minsi %[[CLAMPED_SHIFT_4]], %[[C_63]] : i64 277fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_MANTISSA_MASK_1:.*]] = arith.shrui %[[C_4503599627370495]], %[[CLAMPED_SHIFT_5]] : i64 278fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_MASKED_MANTISSA:.*]] = arith.andi %[[OPERAND_BITCAST]], %[[SHIFTED_MANTISSA_MASK_1]] : i64 279fe355a44SAlexander Shaposhnikov 280fe355a44SAlexander Shaposhnikov// The operand is halfway between two integers if the masked mantissa is equal 281fe355a44SAlexander Shaposhnikov// to the expected mantissa and the biased exponent is in the range 282fe355a44SAlexander Shaposhnikov// [-1, 52). 283fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_BIASED_EXP_GE_NEG_1:.*]] = arith.cmpi sge, %[[OPERAND_BIASED_EXP]], %[[C_NEG_1]] : i64 284fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_BIASED_EXP_LT_10:.*]] = arith.cmpi slt, %[[OPERAND_BIASED_EXP]], %[[C_52]] : i64 285fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_IS_HALFWAY_0:.*]] = arith.cmpi eq, %[[OPERAND_MASKED_MANTISSA]], %[[EXPECTED_OPERAND_MASKED_MANTISSA]] : i64 286fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_IS_HALFWAY_1:.*]] = arith.andi %[[OPERAND_IS_HALFWAY_0]], %[[OPERAND_BIASED_EXP_LT_10]] : i1 287fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_IS_HALFWAY_2:.*]] = arith.andi %[[OPERAND_IS_HALFWAY_1]], %[[OPERAND_BIASED_EXP_GE_NEG_1]] : i1 288fe355a44SAlexander Shaposhnikov 289fe355a44SAlexander Shaposhnikov// Adjust rounded operand with `round(operand) - sign(operand)` to correct the 290fe355a44SAlexander Shaposhnikov// case where `round` rounded in the oppositve direction of `roundeven`. 291fe355a44SAlexander Shaposhnikov// CHECK: %[[SIGN:.*]] = math.copysign %[[C_1_FLOAT]], %[[VAL_0]] : f64 292fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_SHIFTED:.*]] = arith.subf %[[ROUND]], %[[SIGN]] : f64 293fe355a44SAlexander Shaposhnikov// CHECK: %[[NEEDS_SHIFT:.*]] = arith.andi %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_1]], %[[OPERAND_IS_HALFWAY_2]] : i1 294fe355a44SAlexander Shaposhnikov// CHECK: %[[RESULT:.*]] = arith.select %[[NEEDS_SHIFT]], %[[ROUND_SHIFTED]], %[[ROUND]] : f64 295fe355a44SAlexander Shaposhnikov 296fe355a44SAlexander Shaposhnikov// The `x - sign` adjustment does not preserve the sign when we are adjusting the value -1 to -0. 297fe355a44SAlexander Shaposhnikov// CHECK: %[[COPYSIGN:.*]] = math.copysign %[[RESULT]], %[[VAL_0]] : f64 298fe355a44SAlexander Shaposhnikov 299fe355a44SAlexander Shaposhnikov// CHECK: return %[[COPYSIGN]] : f64 300fe355a44SAlexander Shaposhnikov 301fe355a44SAlexander Shaposhnikov// ----- 302fe355a44SAlexander Shaposhnikov 303fe355a44SAlexander Shaposhnikov// CHECK-LABEL: func.func @roundeven32 304fe355a44SAlexander Shaposhnikovfunc.func @roundeven32(%arg: f32) -> f32 { 30544baa655SRamiro Leal-Cavazos %res = math.roundeven %arg : f32 30644baa655SRamiro Leal-Cavazos return %res : f32 30744baa655SRamiro Leal-Cavazos} 30844baa655SRamiro Leal-Cavazos 30944baa655SRamiro Leal-Cavazos// CHECK-SAME: %[[VAL_0:.*]]: f32) -> f32 { 31044baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_0:.*]] = arith.constant 0 : i32 31144baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_1:.*]] = arith.constant 1 : i32 31244baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_NEG_1:.*]] = arith.constant -1 : i32 31344baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_1_FLOAT:.*]] = arith.constant 1.000000e+00 : f32 31444baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_23:.*]] = arith.constant 23 : i32 31544baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_31:.*]] = arith.constant 31 : i32 31644baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_127:.*]] = arith.constant 127 : i32 31744baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_4194304:.*]] = arith.constant 4194304 : i32 31844baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[C_8388607:.*]] = arith.constant 8388607 : i32 31944baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[EXP_MASK:.*]] = arith.constant 255 : i32 32044baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01 32144baa655SRamiro Leal-Cavazos 32244baa655SRamiro Leal-Cavazos// CHECK: %[[OPERAND_BITCAST:.*]] = arith.bitcast %[[VAL_0]] : f32 to i32 32344baa655SRamiro Leal-Cavazos 32444baa655SRamiro Leal-Cavazos// Calculate `math.round(operand)` using expansion pattern for `round` and 32544baa655SRamiro Leal-Cavazos// bitcast result to i32 32644baa655SRamiro Leal-Cavazos// CHECK: %[[SHIFT:.*]] = math.copysign %[[HALF]], %[[VAL_0]] 32744baa655SRamiro Leal-Cavazos// CHECK: %[[ARG_SHIFTED:.*]] = arith.addf %[[VAL_0]], %[[SHIFT]] 32844baa655SRamiro Leal-Cavazos// CHECK: %[[FIXED_CONVERT:.*]] = arith.fptosi %[[ARG_SHIFTED]] 32944baa655SRamiro Leal-Cavazos// CHECK: %[[FP_FIXED_CONVERT_0:.*]] = arith.sitofp %[[FIXED_CONVERT]] 33044baa655SRamiro Leal-Cavazos// CHECK: %[[FP_FIXED_CONVERT_1:.*]] = math.copysign %[[FP_FIXED_CONVERT_0]], %[[ARG_SHIFTED]] 33144baa655SRamiro Leal-Cavazos// CHECK: %[[ARG_BITCAST:.*]] = arith.bitcast %[[VAL_0]] : f32 to i32 33244baa655SRamiro Leal-Cavazos// CHECK: %[[ARG_BITCAST_SHIFTED:.*]] = arith.shrui %[[ARG_BITCAST]], %[[C_23]] 33344baa655SRamiro Leal-Cavazos// CHECK: %[[ARG_EXP:.*]] = arith.andi %[[ARG_BITCAST_SHIFTED]], %[[EXP_MASK]] 33444baa655SRamiro Leal-Cavazos// CHECK: %[[ARG_BIASED_EXP:.*]] = arith.subi %[[ARG_EXP]], %[[C_127]] 33544baa655SRamiro Leal-Cavazos// CHECK: %[[IS_SPECIAL_VAL:.*]] = arith.cmpi sge, %[[ARG_BIASED_EXP]], %[[C_23]] 33644baa655SRamiro Leal-Cavazos// CHECK: %[[ROUND:.*]] = arith.select %[[IS_SPECIAL_VAL]], %[[VAL_0]], %[[FP_FIXED_CONVERT_1]] 33744baa655SRamiro Leal-Cavazos// CHECK: %[[ROUND_BITCAST:.*]] = arith.bitcast %[[ROUND]] : f32 to i32 33844baa655SRamiro Leal-Cavazos 33944baa655SRamiro Leal-Cavazos// Get biased exponents of `round` and `operand` 34044baa655SRamiro Leal-Cavazos// CHECK: %[[SHIFTED_OPERAND_BITCAST:.*]] = arith.shrui %[[OPERAND_BITCAST]], %[[C_23]] : i32 34144baa655SRamiro Leal-Cavazos// CHECK: %[[OPERAND_EXP:.*]] = arith.andi %[[SHIFTED_OPERAND_BITCAST]], %[[EXP_MASK]] : i32 34244baa655SRamiro Leal-Cavazos// CHECK: %[[OPERAND_BIASED_EXP:.*]] = arith.subi %[[OPERAND_EXP]], %[[C_127]] : i32 34344baa655SRamiro Leal-Cavazos// CHECK: %[[SHIFTED_ROUND_BITCAST:.*]] = arith.shrui %[[ROUND_BITCAST]], %[[C_23]] : i32 34444baa655SRamiro Leal-Cavazos// CHECK: %[[ROUND_EXP:.*]] = arith.andi %[[SHIFTED_ROUND_BITCAST]], %[[EXP_MASK]] : i32 34544baa655SRamiro Leal-Cavazos// CHECK: %[[ROUND_BIASED_EXP:.*]] = arith.subi %[[ROUND_EXP]], %[[C_127]] : i32 34644baa655SRamiro Leal-Cavazos 34744baa655SRamiro Leal-Cavazos// Determine if `ROUND_BITCAST` is an even whole number or a special value 34844baa655SRamiro Leal-Cavazos// +-inf, +-nan. 34944baa655SRamiro Leal-Cavazos// Mask mantissa of `ROUND_BITCAST` with a mask shifted to the right by 35044baa655SRamiro Leal-Cavazos// `ROUND_BIASED_EXP - 1` 35144baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[ROUND_BIASED_EXP_MINUS_1:.*]] = arith.subi %[[ROUND_BIASED_EXP]], %[[C_1]] : i32 35244baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[CLAMPED_SHIFT_0:.*]] = arith.maxsi %[[ROUND_BIASED_EXP_MINUS_1]], %[[C_0]] : i32 35344baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[CLAMPED_SHIFT_1:.*]] = arith.minsi %[[CLAMPED_SHIFT_0]], %[[C_31]] : i32 35444baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[SHIFTED_MANTISSA_MASK_0:.*]] = arith.shrui %[[C_8388607]], %[[CLAMPED_SHIFT_1]] : i32 35544baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[ROUND_MASKED_MANTISSA:.*]] = arith.andi %[[ROUND_BITCAST]], %[[SHIFTED_MANTISSA_MASK_0]] : i32 35644baa655SRamiro Leal-Cavazos 35744baa655SRamiro Leal-Cavazos// `ROUND_BITCAST` is not even whole number or special value if masked 35844baa655SRamiro Leal-Cavazos// mantissa is != 0 or `ROUND_BIASED_EXP == 0` 35944baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_0:.*]] = arith.cmpi ne, %[[ROUND_MASKED_MANTISSA]], %[[C_0]] : i32 36044baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[ROUND_BIASED_EXP_EQ_0:.*]] = arith.cmpi eq, %[[ROUND_BIASED_EXP]], %[[C_0]] : i32 36144baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_1:.*]] = arith.ori %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_0]], %[[ROUND_BIASED_EXP_EQ_0]] : i1 36244baa655SRamiro Leal-Cavazos 36344baa655SRamiro Leal-Cavazos// Determine if operand is halfway between two integer values 36444baa655SRamiro Leal-Cavazos// CHECK: %[[OPERAND_BIASED_EXP_EQ_NEG_1:.*]] = arith.cmpi eq, %[[OPERAND_BIASED_EXP]], %[[C_NEG_1]] : i32 36544baa655SRamiro Leal-Cavazos// CHECK: %[[CLAMPED_SHIFT_2:.*]] = arith.maxsi %[[OPERAND_BIASED_EXP]], %[[C_0]] : i32 36644baa655SRamiro Leal-Cavazos// CHECK: %[[CLAMPED_SHIFT_3:.*]] = arith.minsi %[[CLAMPED_SHIFT_2]], %[[C_31]] : i32 36744baa655SRamiro Leal-Cavazos// CHECK: %[[SHIFTED_2_TO_22:.*]] = arith.shrui %[[C_4194304]], %[[CLAMPED_SHIFT_3]] : i32 36844baa655SRamiro Leal-Cavazos 36944baa655SRamiro Leal-Cavazos// A value with `0 <= BIASED_EXP < 23` is halfway between two consecutive 37044baa655SRamiro Leal-Cavazos// integers if the bit at index `BIASED_EXP` starting from the left in the 37144baa655SRamiro Leal-Cavazos// mantissa is 1 and all the bits to the right are zero. For the case where 37244baa655SRamiro Leal-Cavazos// `BIASED_EXP == -1, the expected mantissa is all zeros. 37344baa655SRamiro Leal-Cavazos// CHECK: %[[EXPECTED_OPERAND_MASKED_MANTISSA:.*]] = arith.select %[[OPERAND_BIASED_EXP_EQ_NEG_1]], %[[C_0]], %[[SHIFTED_2_TO_22]] : i32 37444baa655SRamiro Leal-Cavazos 37544baa655SRamiro Leal-Cavazos// Mask mantissa of `OPERAND_BITCAST` with a mask shifted to the right by 37644baa655SRamiro Leal-Cavazos// `OPERAND_BIASED_EXP` 37744baa655SRamiro Leal-Cavazos// CHECK: %[[CLAMPED_SHIFT_4:.*]] = arith.maxsi %[[OPERAND_BIASED_EXP]], %[[C_0]] : i32 37844baa655SRamiro Leal-Cavazos// CHECK: %[[CLAMPED_SHIFT_5:.*]] = arith.minsi %[[CLAMPED_SHIFT_4]], %[[C_31]] : i32 37944baa655SRamiro Leal-Cavazos// CHECK: %[[SHIFTED_MANTISSA_MASK_1:.*]] = arith.shrui %[[C_8388607]], %[[CLAMPED_SHIFT_5]] : i32 38044baa655SRamiro Leal-Cavazos// CHECK: %[[OPERAND_MASKED_MANTISSA:.*]] = arith.andi %[[OPERAND_BITCAST]], %[[SHIFTED_MANTISSA_MASK_1]] : i32 38144baa655SRamiro Leal-Cavazos 38244baa655SRamiro Leal-Cavazos// The operand is halfway between two integers if the masked mantissa is equal 38344baa655SRamiro Leal-Cavazos// to the expected mantissa and the biased exponent is in the range 38444baa655SRamiro Leal-Cavazos// [-1, 23). 38544baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[OPERAND_BIASED_EXP_GE_NEG_1:.*]] = arith.cmpi sge, %[[OPERAND_BIASED_EXP]], %[[C_NEG_1]] : i32 38644baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[OPERAND_BIASED_EXP_LT_23:.*]] = arith.cmpi slt, %[[OPERAND_BIASED_EXP]], %[[C_23]] : i32 38744baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[OPERAND_IS_HALFWAY_0:.*]] = arith.cmpi eq, %[[OPERAND_MASKED_MANTISSA]], %[[EXPECTED_OPERAND_MASKED_MANTISSA]] : i32 38844baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[OPERAND_IS_HALFWAY_1:.*]] = arith.andi %[[OPERAND_IS_HALFWAY_0]], %[[OPERAND_BIASED_EXP_LT_23]] : i1 38944baa655SRamiro Leal-Cavazos// CHECK-DAG: %[[OPERAND_IS_HALFWAY_2:.*]] = arith.andi %[[OPERAND_IS_HALFWAY_1]], %[[OPERAND_BIASED_EXP_GE_NEG_1]] : i1 39044baa655SRamiro Leal-Cavazos 39144baa655SRamiro Leal-Cavazos// Adjust rounded operand with `round(operand) - sign(operand)` to correct the 39244baa655SRamiro Leal-Cavazos// case where `round` rounded in the oppositve direction of `roundeven`. 39344baa655SRamiro Leal-Cavazos// CHECK: %[[SIGN:.*]] = math.copysign %[[C_1_FLOAT]], %[[VAL_0]] : f32 39444baa655SRamiro Leal-Cavazos// CHECK: %[[ROUND_SHIFTED:.*]] = arith.subf %[[ROUND]], %[[SIGN]] : f32 39544baa655SRamiro Leal-Cavazos// CHECK: %[[NEEDS_SHIFT:.*]] = arith.andi %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_1]], %[[OPERAND_IS_HALFWAY_2]] : i1 39644baa655SRamiro Leal-Cavazos// CHECK: %[[RESULT:.*]] = arith.select %[[NEEDS_SHIFT]], %[[ROUND_SHIFTED]], %[[ROUND]] : f32 39744baa655SRamiro Leal-Cavazos 39844baa655SRamiro Leal-Cavazos// The `x - sign` adjustment does not preserve the sign when we are adjusting the value -1 to -0. 39944baa655SRamiro Leal-Cavazos// CHECK: %[[COPYSIGN:.*]] = math.copysign %[[RESULT]], %[[VAL_0]] : f32 40044baa655SRamiro Leal-Cavazos 40144baa655SRamiro Leal-Cavazos// CHECK: return %[[COPYSIGN]] : f32 402fe355a44SAlexander Shaposhnikov 403fe355a44SAlexander Shaposhnikov// ----- 404fe355a44SAlexander Shaposhnikov 405fe355a44SAlexander Shaposhnikov// CHECK-LABEL: func.func @roundeven16 406fe355a44SAlexander Shaposhnikovfunc.func @roundeven16(%arg: f16) -> f16 { 407fe355a44SAlexander Shaposhnikov %res = math.roundeven %arg : f16 408fe355a44SAlexander Shaposhnikov return %res : f16 409fe355a44SAlexander Shaposhnikov} 410fe355a44SAlexander Shaposhnikov 411fe355a44SAlexander Shaposhnikov// CHECK-SAME: %[[VAL_0:.*]]: f16) -> f16 { 412fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_0:.*]] = arith.constant 0 : i16 413fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_1:.*]] = arith.constant 1 : i16 414fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_NEG_1:.*]] = arith.constant -1 : i16 415fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_1_FLOAT:.*]] = arith.constant 1.000000e+00 : f16 416fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_10:.*]] = arith.constant 10 : i16 417fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_15:.*]] = arith.constant 15 : i16 418fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_512:.*]] = arith.constant 512 : i16 419fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[C_1023:.*]] = arith.constant 1023 : i16 420fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[EXP_MASK:.*]] = arith.constant 31 : i16 421fe355a44SAlexander Shaposhnikov 422fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_BITCAST:.*]] = arith.bitcast %[[VAL_0]] : f16 to i16 423fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND:.*]] = math.round %[[VAL_0]] : f16 424fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_BITCAST:.*]] = arith.bitcast %[[ROUND]] : f16 to i16 425fe355a44SAlexander Shaposhnikov 426fe355a44SAlexander Shaposhnikov// Get biased exponents of `round` and `operand` 427fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_OPERAND_BITCAST:.*]] = arith.shrui %[[OPERAND_BITCAST]], %[[C_10]] : i16 428fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_EXP:.*]] = arith.andi %[[SHIFTED_OPERAND_BITCAST]], %[[EXP_MASK]] : i16 429fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_BIASED_EXP:.*]] = arith.subi %[[OPERAND_EXP]], %[[C_15]] : i16 430fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_ROUND_BITCAST:.*]] = arith.shrui %[[ROUND_BITCAST]], %[[C_10]] : i16 431fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_EXP:.*]] = arith.andi %[[SHIFTED_ROUND_BITCAST]], %[[EXP_MASK]] : i16 432fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_BIASED_EXP:.*]] = arith.subi %[[ROUND_EXP]], %[[C_15]] : i16 433fe355a44SAlexander Shaposhnikov 434fe355a44SAlexander Shaposhnikov// Determine if `ROUND_BITCAST` is an even whole number or a special value 435fe355a44SAlexander Shaposhnikov// +-inf, +-nan. 436fe355a44SAlexander Shaposhnikov// Mask mantissa of `ROUND_BITCAST` with a mask shifted to the right by 437fe355a44SAlexander Shaposhnikov// `ROUND_BIASED_EXP - 1` 438fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_BIASED_EXP_MINUS_1:.*]] = arith.subi %[[ROUND_BIASED_EXP]], %[[C_1]] : i16 439fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[CLAMPED_SHIFT_0:.*]] = arith.maxsi %[[ROUND_BIASED_EXP_MINUS_1]], %[[C_0]] : i16 440fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[CLAMPED_SHIFT_1:.*]] = arith.minsi %[[CLAMPED_SHIFT_0]], %[[C_15]] : i16 441fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[SHIFTED_MANTISSA_MASK_0:.*]] = arith.shrui %[[C_1023]], %[[CLAMPED_SHIFT_1]] : i16 442fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_MASKED_MANTISSA:.*]] = arith.andi %[[ROUND_BITCAST]], %[[SHIFTED_MANTISSA_MASK_0]] : i16 443fe355a44SAlexander Shaposhnikov 444fe355a44SAlexander Shaposhnikov// `ROUND_BITCAST` is not even whole number or special value if masked 445fe355a44SAlexander Shaposhnikov// mantissa is != 0 or `ROUND_BIASED_EXP == 0` 446fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_0:.*]] = arith.cmpi ne, %[[ROUND_MASKED_MANTISSA]], %[[C_0]] : i16 447fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_BIASED_EXP_EQ_0:.*]] = arith.cmpi eq, %[[ROUND_BIASED_EXP]], %[[C_0]] : i16 448fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_1:.*]] = arith.ori %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_0]], %[[ROUND_BIASED_EXP_EQ_0]] : i1 449fe355a44SAlexander Shaposhnikov 450fe355a44SAlexander Shaposhnikov// Determine if operand is halfway between two integer values 451fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_BIASED_EXP_EQ_NEG_1:.*]] = arith.cmpi eq, %[[OPERAND_BIASED_EXP]], %[[C_NEG_1]] : i16 452fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_2:.*]] = arith.maxsi %[[OPERAND_BIASED_EXP]], %[[C_0]] : i16 453fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_3:.*]] = arith.minsi %[[CLAMPED_SHIFT_2]], %[[C_15]] : i16 454fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_2_TO_9:.*]] = arith.shrui %[[C_512]], %[[CLAMPED_SHIFT_3]] : i16 455fe355a44SAlexander Shaposhnikov 456fe355a44SAlexander Shaposhnikov// A value with `0 <= BIASED_EXP < 10` is halfway between two consecutive 457fe355a44SAlexander Shaposhnikov// integers if the bit at index `BIASED_EXP` starting from the left in the 458fe355a44SAlexander Shaposhnikov// mantissa is 1 and all the bits to the right are zero. For the case where 459fe355a44SAlexander Shaposhnikov// `BIASED_EXP == -1, the expected mantissa is all zeros. 460fe355a44SAlexander Shaposhnikov// CHECK: %[[EXPECTED_OPERAND_MASKED_MANTISSA:.*]] = arith.select %[[OPERAND_BIASED_EXP_EQ_NEG_1]], %[[C_0]], %[[SHIFTED_2_TO_9]] : i16 461fe355a44SAlexander Shaposhnikov 462fe355a44SAlexander Shaposhnikov// Mask mantissa of `OPERAND_BITCAST` with a mask shifted to the right by 463fe355a44SAlexander Shaposhnikov// `OPERAND_BIASED_EXP` 464fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_4:.*]] = arith.maxsi %[[OPERAND_BIASED_EXP]], %[[C_0]] : i16 465fe355a44SAlexander Shaposhnikov// CHECK: %[[CLAMPED_SHIFT_5:.*]] = arith.minsi %[[CLAMPED_SHIFT_4]], %[[C_15]] : i16 466fe355a44SAlexander Shaposhnikov// CHECK: %[[SHIFTED_MANTISSA_MASK_1:.*]] = arith.shrui %[[C_1023]], %[[CLAMPED_SHIFT_5]] : i16 467fe355a44SAlexander Shaposhnikov// CHECK: %[[OPERAND_MASKED_MANTISSA:.*]] = arith.andi %[[OPERAND_BITCAST]], %[[SHIFTED_MANTISSA_MASK_1]] : i16 468fe355a44SAlexander Shaposhnikov 469fe355a44SAlexander Shaposhnikov// The operand is halfway between two integers if the masked mantissa is equal 470fe355a44SAlexander Shaposhnikov// to the expected mantissa and the biased exponent is in the range 471fe355a44SAlexander Shaposhnikov// [-1, 23). 472fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_BIASED_EXP_GE_NEG_1:.*]] = arith.cmpi sge, %[[OPERAND_BIASED_EXP]], %[[C_NEG_1]] : i16 473fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_BIASED_EXP_LT_10:.*]] = arith.cmpi slt, %[[OPERAND_BIASED_EXP]], %[[C_10]] : i16 474fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_IS_HALFWAY_0:.*]] = arith.cmpi eq, %[[OPERAND_MASKED_MANTISSA]], %[[EXPECTED_OPERAND_MASKED_MANTISSA]] : i16 475fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_IS_HALFWAY_1:.*]] = arith.andi %[[OPERAND_IS_HALFWAY_0]], %[[OPERAND_BIASED_EXP_LT_10]] : i1 476fe355a44SAlexander Shaposhnikov// CHECK-DAG: %[[OPERAND_IS_HALFWAY_2:.*]] = arith.andi %[[OPERAND_IS_HALFWAY_1]], %[[OPERAND_BIASED_EXP_GE_NEG_1]] : i1 477fe355a44SAlexander Shaposhnikov 478fe355a44SAlexander Shaposhnikov// Adjust rounded operand with `round(operand) - sign(operand)` to correct the 479fe355a44SAlexander Shaposhnikov// case where `round` rounded in the oppositve direction of `roundeven`. 480fe355a44SAlexander Shaposhnikov// CHECK: %[[SIGN:.*]] = math.copysign %[[C_1_FLOAT]], %[[VAL_0]] : f16 481fe355a44SAlexander Shaposhnikov// CHECK: %[[ROUND_SHIFTED:.*]] = arith.subf %[[ROUND]], %[[SIGN]] : f16 482fe355a44SAlexander Shaposhnikov// CHECK: %[[NEEDS_SHIFT:.*]] = arith.andi %[[ROUND_IS_NOT_EVEN_OR_SPECIAL_1]], %[[OPERAND_IS_HALFWAY_2]] : i1 483fe355a44SAlexander Shaposhnikov// CHECK: %[[RESULT:.*]] = arith.select %[[NEEDS_SHIFT]], %[[ROUND_SHIFTED]], %[[ROUND]] : f16 484fe355a44SAlexander Shaposhnikov 485fe355a44SAlexander Shaposhnikov// The `x - sign` adjustment does not preserve the sign when we are adjusting the value -1 to -0. 486fe355a44SAlexander Shaposhnikov// CHECK: %[[COPYSIGN:.*]] = math.copysign %[[RESULT]], %[[VAL_0]] : f16 487fe355a44SAlexander Shaposhnikov 488fe355a44SAlexander Shaposhnikov// CHECK: return %[[COPYSIGN]] : f16 48910a57f3aSPrashant Kumar 49010a57f3aSPrashant Kumar// ----- 49110a57f3aSPrashant Kumar 49210a57f3aSPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_neg_odd_power 49310a57f3aSPrashant Kumarfunc.func @math_fpowi_neg_odd_power(%0 : tensor<8xf32>) -> tensor<8xf32> { 49410a57f3aSPrashant Kumar %1 = arith.constant dense<-3> : tensor<8xi64> 49510a57f3aSPrashant Kumar %2 = math.fpowi %0, %1 : tensor<8xf32>, tensor<8xi64> 49610a57f3aSPrashant Kumar return %2 : tensor<8xf32> 49710a57f3aSPrashant Kumar} 49810a57f3aSPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: tensor<8xf32>) -> tensor<8xf32> { 49910a57f3aSPrashant Kumar// CHECK-DAG: %[[CST1:.*]] = arith.constant dense<1.000000e+00> : tensor<8xf32> 50010a57f3aSPrashant Kumar// CHECK-DAG: %[[CST0:.*]] = arith.constant dense<0.000000e+00> : tensor<8xf32> 50110a57f3aSPrashant Kumar// CHECK-DAG: %[[CSTNEG0:.*]] = arith.constant dense<-0.000000e+00> : tensor<8xf32> 50210a57f3aSPrashant Kumar// CHECK-DAG: %[[CSTINF:.*]] = arith.constant dense<0x7F800000> : tensor<8xf32> 50310a57f3aSPrashant Kumar// CHECK-DAG: %[[CSTNEGINF:.*]] = arith.constant dense<0xFF800000> : tensor<8xf32> 50410a57f3aSPrashant Kumar// CHECK: %[[SQ:.*]] = arith.mulf %[[ARG0]], %[[ARG0]] : tensor<8xf32> 50510a57f3aSPrashant Kumar// CHECK: %[[CUBE:.*]] = arith.mulf %[[SQ]], %[[ARG0]] : tensor<8xf32> 50610a57f3aSPrashant Kumar// CHECK: %[[CMP0:.*]] = arith.cmpf oeq, %[[CUBE]], %[[CST0]] : tensor<8xf32> 50710a57f3aSPrashant Kumar// CHECK: %[[CMPNEG0:.*]] = arith.cmpf oeq, %[[CUBE]], %[[CSTNEG0]] : tensor<8xf32> 50810a57f3aSPrashant Kumar// CHECK: %[[INV:.*]] = arith.divf %[[CST1]], %[[CUBE]] : tensor<8xf32> 50910a57f3aSPrashant Kumar// CHECK: %[[UB1:.*]] = arith.select %[[CMP0]], %[[CSTINF]], %[[INV]] : tensor<8xi1>, tensor<8xf32> 51010a57f3aSPrashant Kumar// CHECK: %[[UB2:.*]] = arith.select %[[CMPNEG0]], %[[CSTNEGINF]], %[[UB1]] : tensor<8xi1>, tensor<8xf32> 51110a57f3aSPrashant Kumar// CHECK: return %[[UB2]] : tensor<8xf32> 51210a57f3aSPrashant Kumar 51310a57f3aSPrashant Kumar// ----- 51410a57f3aSPrashant Kumar 51510a57f3aSPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_neg_even_power 51610a57f3aSPrashant Kumarfunc.func @math_fpowi_neg_even_power(%0 : tensor<8xf32>) -> tensor<8xf32> { 51710a57f3aSPrashant Kumar %1 = arith.constant dense<-4> : tensor<8xi64> 51810a57f3aSPrashant Kumar %2 = math.fpowi %0, %1 : tensor<8xf32>, tensor<8xi64> 51910a57f3aSPrashant Kumar return %2 : tensor<8xf32> 52010a57f3aSPrashant Kumar} 52110a57f3aSPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: tensor<8xf32>) -> tensor<8xf32> { 52210a57f3aSPrashant Kumar// CHECK-DAG: %[[CST1:.*]] = arith.constant dense<1.000000e+00> : tensor<8xf32> 52310a57f3aSPrashant Kumar// CHECK-DAG: %[[CST0:.*]] = arith.constant dense<0.000000e+00> : tensor<8xf32> 52410a57f3aSPrashant Kumar// CHECK-DAG: %[[CSTNEG0:.*]] = arith.constant dense<-0.000000e+00> : tensor<8xf32> 52510a57f3aSPrashant Kumar// CHECK-DAG: %[[CSTINF:.*]] = arith.constant dense<0x7F800000> : tensor<8xf32> 52610a57f3aSPrashant Kumar// CHECK-DAG: %[[CSTNEGINF:.*]] = arith.constant dense<0xFF800000> : tensor<8xf32> 52710a57f3aSPrashant Kumar// CHECK: %[[SQ:.*]] = arith.mulf %[[ARG0]], %[[ARG0]] : tensor<8xf32> 52810a57f3aSPrashant Kumar// CHECK: %[[PW4:.*]] = arith.mulf %[[SQ]], %[[SQ]] : tensor<8xf32> 52910a57f3aSPrashant Kumar// CHECK: %[[CMP0:.*]] = arith.cmpf oeq, %[[PW4]], %[[CST0]] : tensor<8xf32> 53010a57f3aSPrashant Kumar// CHECK: %[[CMPNEG0:.*]] = arith.cmpf oeq, %[[PW4]], %[[CSTNEG0]] : tensor<8xf32> 53110a57f3aSPrashant Kumar// CHECK: %[[INV:.*]] = arith.divf %[[CST1]], %[[PW4]] : tensor<8xf32> 53210a57f3aSPrashant Kumar// CHECK: %[[UB1:.*]] = arith.select %[[CMP0]], %[[CSTINF]], %[[INV]] : tensor<8xi1>, tensor<8xf32> 53310a57f3aSPrashant Kumar// CHECK: %[[UB2:.*]] = arith.select %[[CMPNEG0]], %[[CSTNEGINF]], %[[UB1]] : tensor<8xi1>, tensor<8xf32> 53410a57f3aSPrashant Kumar// CHECK: return %[[UB2]] : tensor<8xf32> 53510a57f3aSPrashant Kumar 53610a57f3aSPrashant Kumar// ----- 53710a57f3aSPrashant Kumar 53810a57f3aSPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_pos_odd_power 53910a57f3aSPrashant Kumarfunc.func @math_fpowi_pos_odd_power(%0 : tensor<8xf32>) -> tensor<8xf32> { 54010a57f3aSPrashant Kumar %1 = arith.constant dense<5> : tensor<8xi64> 54110a57f3aSPrashant Kumar %2 = math.fpowi %0, %1 : tensor<8xf32>, tensor<8xi64> 54210a57f3aSPrashant Kumar return %2 : tensor<8xf32> 54310a57f3aSPrashant Kumar} 54410a57f3aSPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: tensor<8xf32>) -> tensor<8xf32> { 54510a57f3aSPrashant Kumar// CHECK: %[[SQ:.*]] = arith.mulf %[[ARG0]], %[[ARG0]] : tensor<8xf32> 54610a57f3aSPrashant Kumar// CHECK: %[[PW4:.*]] = arith.mulf %[[SQ]], %[[SQ]] : tensor<8xf32> 54710a57f3aSPrashant Kumar// CHECK: %[[PW5:.*]] = arith.mulf %[[PW4]], %[[ARG0]] : tensor<8xf32> 54810a57f3aSPrashant Kumar// CHECK: return %[[PW5]] : tensor<8xf32> 54910a57f3aSPrashant Kumar 55010a57f3aSPrashant Kumar// ----- 55110a57f3aSPrashant Kumar 55210a57f3aSPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_pos_even_power 55310a57f3aSPrashant Kumarfunc.func @math_fpowi_pos_even_power(%0 : tensor<8xf32>) -> tensor<8xf32> { 55410a57f3aSPrashant Kumar %1 = arith.constant dense<4> : tensor<8xi64> 55510a57f3aSPrashant Kumar %2 = math.fpowi %0, %1 : tensor<8xf32>, tensor<8xi64> 55610a57f3aSPrashant Kumar return %2 : tensor<8xf32> 55710a57f3aSPrashant Kumar} 55810a57f3aSPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: tensor<8xf32>) -> tensor<8xf32> { 55910a57f3aSPrashant Kumar// CHECK: %[[SQ:.*]] = arith.mulf %[[ARG0]], %[[ARG0]] : tensor<8xf32> 56010a57f3aSPrashant Kumar// CHECK: %[[PW4:.*]] = arith.mulf %[[SQ]], %[[SQ]] : tensor<8xf32> 56110a57f3aSPrashant Kumar// CHECK: return %[[PW4]] : tensor<8xf32> 56210a57f3aSPrashant Kumar 56310a57f3aSPrashant Kumar// ----- 56410a57f3aSPrashant Kumar 56510a57f3aSPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_even_scalar 56610a57f3aSPrashant Kumarfunc.func @math_fpowi_even_scalar(%0 : f32) -> f32 { 56710a57f3aSPrashant Kumar %pow = arith.constant 2 : i64 56810a57f3aSPrashant Kumar %2 = math.fpowi %0, %pow : f32, i64 56910a57f3aSPrashant Kumar return %2 : f32 57010a57f3aSPrashant Kumar} 57110a57f3aSPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: f32) -> f32 { 57210a57f3aSPrashant Kumar// CHECK: %[[SQ:.*]] = arith.mulf %[[ARG0]], %[[ARG0]] : f32 57310a57f3aSPrashant Kumar// CHECK: return %[[SQ]] : f32 57410a57f3aSPrashant Kumar 57510a57f3aSPrashant Kumar// ----- 57610a57f3aSPrashant Kumar 57710a57f3aSPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_scalar_zero 57810a57f3aSPrashant Kumarfunc.func @math_fpowi_scalar_zero(%0 : f32) -> f32 { 57910a57f3aSPrashant Kumar %pow = arith.constant 0 : i64 58010a57f3aSPrashant Kumar %2 = math.fpowi %0, %pow : f32, i64 58110a57f3aSPrashant Kumar return %2 : f32 58210a57f3aSPrashant Kumar} 58310a57f3aSPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: f32) -> f32 { 58410a57f3aSPrashant Kumar// CHECK: %[[RET:.*]] = arith.constant 1.000000e+00 : f32 58510a57f3aSPrashant Kumar// CHECK: return %[[RET]] : f32 58610a57f3aSPrashant Kumar 58710a57f3aSPrashant Kumar// ----- 5885b702be1SPrashant Kumar 5895b702be1SPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_to_powf_tensor 5905b702be1SPrashant Kumarfunc.func @math_fpowi_to_powf_tensor(%0 : tensor<8xf32>, %1: tensor<8xi32>) -> tensor<8xf32> { 5915b702be1SPrashant Kumar %2 = math.fpowi %0, %1 : tensor<8xf32>, tensor<8xi32> 5925b702be1SPrashant Kumar return %2 : tensor<8xf32> 5935b702be1SPrashant Kumar} 5945b702be1SPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: tensor<8xf32>, %[[ARG1:.*]]: tensor<8xi32>) -> tensor<8xf32> { 595a92e3df3SChristopher Bate// CHECK-DAG: %[[CST1:.+]] = arith.constant dense<1.000000e+00> : tensor<8xf32> 596*3a337757SHyunsung Lee// CHECK-DAG: %[[CST0:.*]] = arith.constant dense<0.000000e+00> : tensor<8xf32> 5975b702be1SPrashant Kumar// CHECK: %[[TOFP:.*]] = arith.sitofp %[[ARG1]] : tensor<8xi32> to tensor<8xf32> 598*3a337757SHyunsung Lee// CHECK: %[[LOGA:.*]] = math.log %[[ARG0]] : tensor<8xf32> 599*3a337757SHyunsung Lee// CHECK: %[[MUL:.*]] = arith.mulf %[[TOFP]], %[[LOGA]] : tensor<8xf32> 6005b702be1SPrashant Kumar// CHECK: %[[EXP:.*]] = math.exp %[[MUL]] : tensor<8xf32> 601*3a337757SHyunsung Lee// CHECK: %[[CMP:.*]] = arith.cmpf oeq, %[[TOFP]], %[[CST0]] : tensor<8xf32> 602*3a337757SHyunsung Lee// CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[CST1]], %[[EXP]] : tensor<8xi1>, tensor<8xf32> 603*3a337757SHyunsung Lee// CHECK: return %[[SEL]] 6045b702be1SPrashant Kumar// ----- 6055b702be1SPrashant Kumar 6065b702be1SPrashant Kumar// CHECK-LABEL: func.func @math_fpowi_to_powf_scalar 6075b702be1SPrashant Kumarfunc.func @math_fpowi_to_powf_scalar(%0 : f32, %1: i64) -> f32 { 6085b702be1SPrashant Kumar %2 = math.fpowi %0, %1 : f32, i64 6095b702be1SPrashant Kumar return %2 : f32 6105b702be1SPrashant Kumar} 6115b702be1SPrashant Kumar// CHECK-SAME: (%[[ARG0:.*]]: f32, %[[ARG1:.*]]: i64) -> f32 { 612a92e3df3SChristopher Bate// CHECK-DAG: %[[CST0:.*]] = arith.constant 0.000000e+00 : f32 613a92e3df3SChristopher Bate// CHECK-DAG: %[[CST1:.+]] = arith.constant 1.000000e+00 : f32 6145b702be1SPrashant Kumar// CHECK: %[[TOFP:.*]] = arith.sitofp %[[ARG1]] : i64 to f32 615*3a337757SHyunsung Lee// CHECK: %[[LOGA:.*]] = math.log %[[ARG0]] : f32 616*3a337757SHyunsung Lee// CHECK: %[[MUL:.*]] = arith.mulf %[[TOFP]], %[[LOGA]] : f32 6175b702be1SPrashant Kumar// CHECK: %[[EXP:.*]] = math.exp %[[MUL]] : f32 618*3a337757SHyunsung Lee// CHECK: %[[CMP:.*]] = arith.cmpf oeq, %[[TOFP]], %[[CST0]] : f32 619*3a337757SHyunsung Lee// CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[CST1]], %[[EXP]] : f32 620*3a337757SHyunsung Lee// CHECK: return %[[SEL]] : f32 621279a659eSCorentin Ferry 622279a659eSCorentin Ferry// ----- 623279a659eSCorentin Ferry 624279a659eSCorentin Ferry// CHECK-LABEL: func.func @rsqrt 625279a659eSCorentin Ferry// CHECK-SAME: (%[[ARG:.*]]: f16) 626279a659eSCorentin Ferry// CHECK-SAME: -> f16 627279a659eSCorentin Ferry// CHECK-DAG: %[[CST:.*]] = arith.constant 1.000000e+00 : f16 628279a659eSCorentin Ferry// CHECK-DAG: %[[SQRT:.*]] = math.sqrt %[[ARG]] : f16 629279a659eSCorentin Ferry// CHECK-DAG: %[[DIV:.*]] = arith.divf %[[CST]], %[[SQRT]] : f16 630279a659eSCorentin Ferry// CHECK: return %[[DIV]] : f16 631279a659eSCorentin Ferryfunc.func @rsqrt16(%float: f16) -> (f16) { 632279a659eSCorentin Ferry %float_result = math.rsqrt %float : f16 633279a659eSCorentin Ferry return %float_result : f16 634279a659eSCorentin Ferry} 635279a659eSCorentin Ferry 636279a659eSCorentin Ferry// ----- 637279a659eSCorentin Ferry 638279a659eSCorentin Ferry// CHECK-LABEL: func.func @rsqrt 639279a659eSCorentin Ferry// CHECK-SAME: (%[[ARG:.*]]: f32) 640279a659eSCorentin Ferry// CHECK-SAME: -> f32 641279a659eSCorentin Ferry// CHECK-DAG: %[[CST:.*]] = arith.constant 1.000000e+00 : f32 642279a659eSCorentin Ferry// CHECK-DAG: %[[SQRT:.*]] = math.sqrt %[[ARG]] : f32 643279a659eSCorentin Ferry// CHECK-DAG: %[[DIV:.*]] = arith.divf %[[CST]], %[[SQRT]] : f32 644279a659eSCorentin Ferry// CHECK: return %[[DIV]] : f32 645279a659eSCorentin Ferryfunc.func @rsqrt32(%float: f32) -> (f32) { 646279a659eSCorentin Ferry %float_result = math.rsqrt %float : f32 647279a659eSCorentin Ferry return %float_result : f32 648279a659eSCorentin Ferry} 649279a659eSCorentin Ferry 650279a659eSCorentin Ferry// ----- 651279a659eSCorentin Ferry 652279a659eSCorentin Ferry// CHECK-LABEL: func.func @rsqrt 653279a659eSCorentin Ferry// CHECK-SAME: (%[[ARG:.*]]: f64) 654279a659eSCorentin Ferry// CHECK-SAME: -> f64 655279a659eSCorentin Ferry// CHECK-DAG: %[[CST:.*]] = arith.constant 1.000000e+00 : f64 656279a659eSCorentin Ferry// CHECK-DAG: %[[SQRT:.*]] = math.sqrt %[[ARG]] : f64 657279a659eSCorentin Ferry// CHECK-DAG: %[[DIV:.*]] = arith.divf %[[CST]], %[[SQRT]] : f64 658279a659eSCorentin Ferry// CHECK: return %[[DIV]] : f64 659279a659eSCorentin Ferryfunc.func @rsqrt64(%float: f64) -> (f64) { 660279a659eSCorentin Ferry %float_result = math.rsqrt %float : f64 661279a659eSCorentin Ferry return %float_result : f64 662279a659eSCorentin Ferry} 663279a659eSCorentin Ferry 664279a659eSCorentin Ferry// ----- 665279a659eSCorentin Ferry 666279a659eSCorentin Ferry// CHECK-LABEL: func.func @rsqrt_vec 667279a659eSCorentin Ferry// CHECK-SAME: (%[[ARG:.*]]: vector<5xf32>) 668279a659eSCorentin Ferry// CHECK-SAME: -> vector<5xf32> 669279a659eSCorentin Ferry// CHECK-DAG: %[[CST:.*]] = arith.constant dense<1.000000e+00> : vector<5xf32> 670279a659eSCorentin Ferry// CHECK-DAG: %[[SQRT:.*]] = math.sqrt %[[ARG]] : vector<5xf32> 671279a659eSCorentin Ferry// CHECK-DAG: %[[DIV:.*]] = arith.divf %[[CST]], %[[SQRT]] : vector<5xf32> 672279a659eSCorentin Ferry// CHECK: return %[[DIV]] : vector<5xf32> 673279a659eSCorentin Ferryfunc.func @rsqrt_vec(%float: vector<5xf32>) -> (vector<5xf32>) { 674279a659eSCorentin Ferry %float_result = math.rsqrt %float : vector<5xf32> 675279a659eSCorentin Ferry return %float_result : vector<5xf32> 676279a659eSCorentin Ferry} 677279a659eSCorentin Ferry 678279a659eSCorentin Ferry// ----- 679279a659eSCorentin Ferry 680279a659eSCorentin Ferry// CHECK-LABEL: func.func @rsqrt_tns 681279a659eSCorentin Ferry// CHECK-SAME: (%[[ARG:.*]]: tensor<5x8xf32>) 682279a659eSCorentin Ferry// CHECK-SAME: -> tensor<5x8xf32> 683279a659eSCorentin Ferry// CHECK-DAG: %[[CST:.*]] = arith.constant dense<1.000000e+00> : tensor<5x8xf32> 684279a659eSCorentin Ferry// CHECK-DAG: %[[SQRT:.*]] = math.sqrt %[[ARG]] : tensor<5x8xf32> 685279a659eSCorentin Ferry// CHECK-DAG: %[[DIV:.*]] = arith.divf %[[CST]], %[[SQRT]] : tensor<5x8xf32> 686279a659eSCorentin Ferry// CHECK: return %[[DIV]] : tensor<5x8xf32> 687279a659eSCorentin Ferryfunc.func @rsqrt_tns(%float: tensor<5x8xf32>) -> (tensor<5x8xf32>) { 688279a659eSCorentin Ferry %float_result = math.rsqrt %float : tensor<5x8xf32> 689279a659eSCorentin Ferry return %float_result : tensor<5x8xf32> 690279a659eSCorentin Ferry} 691