xref: /llvm-project/mlir/test/Dialect/Math/expand-math.mlir (revision 3a3377579f137a0a6e14b60d891a9736707e7e8d)
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