xref: /llvm-project/mlir/test/Dialect/Math/polynomial-approximation.mlir (revision 72f362170fbe7834febfe08d8bd1f7ba935ddbc9)
1// RUN: mlir-opt %s -test-math-polynomial-approximation | FileCheck %s
2// RUN: mlir-opt %s -test-math-polynomial-approximation=enable-avx2 \
3// RUN: | FileCheck --check-prefix=AVX2 %s
4
5// Check that all math functions lowered to approximations built from
6// standard operations (add, mul, fma, shift, etc...).
7
8// CHECK-LABEL: func @erf_scalar(
9// CHECK-SAME:    %[[val_arg0:.*]]: f32) -> f32 {
10// CHECK-DAG:     %[[val_cst:.*]] = arith.constant 0.000000e+00 : f32
11// CHECK-DAG:     %[[val_cst_0:.*]] = arith.constant 1.000000e+00 : f32
12// CHECK-DAG:     %[[val_cst_1:.*]] = arith.constant 1.12837911 : f32
13// CHECK-DAG:     %[[val_cst_2:.*]] = arith.constant -0.523018539 : f32
14// CHECK-DAG:     %[[val_cst_3:.*]] = arith.constant 0.209741712 : f32
15// CHECK-DAG:     %[[val_cst_4:.*]] = arith.constant 0.0258146804 : f32
16// CHECK-DAG:     %[[val_cst_5:.*]] = arith.constant 1.12750685 : f32
17// CHECK-DAG:     %[[val_cst_6:.*]] = arith.constant -0.364721417 : f32
18// CHECK-DAG:     %[[val_cst_7:.*]] = arith.constant 0.118407398 : f32
19// CHECK-DAG:     %[[val_cst_8:.*]] = arith.constant 0.0370645523 : f32
20// CHECK-DAG:     %[[val_cst_9:.*]] = arith.constant -0.00330093061 : f32
21// CHECK-DAG:     %[[val_cst_10:.*]] = arith.constant 0.00351961935 : f32
22// CHECK-DAG:     %[[val_cst_11:.*]] = arith.constant -0.00141373626 : f32
23// CHECK-DAG:     %[[val_cst_12:.*]] = arith.constant 2.53447099E-4 : f32
24// CHECK-DAG:     %[[val_cst_13:.*]] = arith.constant -1.71048032E-5 : f32
25// CHECK-DAG:     %[[val_cst_14:.*]] = arith.constant -0.463513821 : f32
26// CHECK-DAG:     %[[val_cst_15:.*]] = arith.constant 0.519230127 : f32
27// CHECK-DAG:     %[[val_cst_16:.*]] = arith.constant -0.131808966 : f32
28// CHECK-DAG:     %[[val_cst_17:.*]] = arith.constant 0.0739796459 : f32
29// CHECK-DAG:     %[[val_cst_18:.*]] = arith.constant -3.276070e-01 : f32
30// CHECK-DAG:     %[[val_cst_19:.*]] = arith.constant 0.448369086 : f32
31// CHECK-DAG:     %[[val_cst_20:.*]] = arith.constant -0.0883462652 : f32
32// CHECK-DAG:     %[[val_cst_21:.*]] = arith.constant 0.0572442785 : f32
33// CHECK-DAG:     %[[val_cst_22:.*]] = arith.constant -2.0606916 : f32
34// CHECK-DAG:     %[[val_cst_23:.*]] = arith.constant 1.62705934 : f32
35// CHECK-DAG:     %[[val_cst_24:.*]] = arith.constant -0.583389878 : f32
36// CHECK-DAG:     %[[val_cst_25:.*]] = arith.constant 0.0821908935 : f32
37// CHECK-DAG:     %[[val_cst_26:.*]] = arith.constant 8.000000e-01 : f32
38// CHECK-DAG:     %[[val_cst_27:.*]] = arith.constant 2.000000e+00 : f32
39// CHECK-DAG:     %[[val_cst_28:.*]] = arith.constant 3.750000e+00 : f32
40// CHECK:         %[[val_0:.*]] = arith.cmpf olt, %[[val_arg0]], %[[val_cst]] : f32
41// CHECK:         %[[val_1:.*]] = arith.negf %[[val_arg0]] : f32
42// CHECK:         %[[val_2:.*]] = arith.select %[[val_0]], %[[val_1]], %[[val_arg0]] : f32
43// CHECK:         %[[val_3:.*]] = arith.cmpf olt, %[[val_2]], %[[val_cst_26]] : f32
44// CHECK:         %[[val_4:.*]] = arith.select %[[val_3]], %[[val_cst_1]], %[[val_cst_5]] : f32
45// CHECK:         %[[val_5:.*]] = arith.select %[[val_3]], %[[val_cst_14]], %[[val_cst_18]] : f32
46// CHECK:         %[[val_6:.*]] = arith.select %[[val_3]], %[[val_cst_2]], %[[val_cst_6]] : f32
47// CHECK:         %[[val_7:.*]] = arith.select %[[val_3]], %[[val_cst_15]], %[[val_cst_19]] : f32
48// CHECK:         %[[val_8:.*]] = arith.select %[[val_3]], %[[val_cst_3]], %[[val_cst_7]] : f32
49// CHECK:         %[[val_9:.*]] = arith.select %[[val_3]], %[[val_cst_16]], %[[val_cst_20]] : f32
50// CHECK:         %[[val_10:.*]] = arith.select %[[val_3]], %[[val_cst_4]], %[[val_cst_8]] : f32
51// CHECK:         %[[val_11:.*]] = arith.select %[[val_3]], %[[val_cst_17]], %[[val_cst_21]] : f32
52// CHECK:         %[[val_12:.*]] = arith.cmpf olt, %[[val_2]], %[[val_cst_27]] : f32
53// CHECK:         %[[val_13:.*]] = arith.select %[[val_12]], %[[val_cst]], %[[val_cst_9]] : f32
54// CHECK:         %[[val_14:.*]] = arith.select %[[val_12]], %[[val_4]], %[[val_cst_10]] : f32
55// CHECK:         %[[val_15:.*]] = arith.select %[[val_12]], %[[val_5]], %[[val_cst_22]] : f32
56// CHECK:         %[[val_16:.*]] = arith.select %[[val_12]], %[[val_6]], %[[val_cst_11]] : f32
57// CHECK:         %[[val_17:.*]] = arith.select %[[val_12]], %[[val_7]], %[[val_cst_23]] : f32
58// CHECK:         %[[val_18:.*]] = arith.select %[[val_12]], %[[val_8]], %[[val_cst_12]] : f32
59// CHECK:         %[[val_19:.*]] = arith.select %[[val_12]], %[[val_9]], %[[val_cst_24]] : f32
60// CHECK:         %[[val_20:.*]] = arith.select %[[val_12]], %[[val_10]], %[[val_cst_13]] : f32
61// CHECK:         %[[val_21:.*]] = arith.select %[[val_12]], %[[val_11]], %[[val_cst_25]] : f32
62// CHECK:         %[[val_22:.*]] = arith.select %[[val_12]], %[[val_cst]], %[[val_cst_0]] : f32
63// CHECK:         %[[val_23:.*]] = arith.cmpf ult, %[[val_2]], %[[val_cst_28]] : f32
64// CHECK:         %[[val_24:.*]] = math.fma %[[val_2]], %[[val_20]], %[[val_18]] : f32
65// CHECK:         %[[val_25:.*]] = math.fma %[[val_2]], %[[val_24]], %[[val_16]] : f32
66// CHECK:         %[[val_26:.*]] = math.fma %[[val_2]], %[[val_25]], %[[val_14]] : f32
67// CHECK:         %[[val_27:.*]] = math.fma %[[val_2]], %[[val_26]], %[[val_13]] : f32
68// CHECK:         %[[val_28:.*]] = math.fma %[[val_2]], %[[val_21]], %[[val_19]] : f32
69// CHECK:         %[[val_29:.*]] = math.fma %[[val_2]], %[[val_28]], %[[val_17]] : f32
70// CHECK:         %[[val_30:.*]] = math.fma %[[val_2]], %[[val_29]], %[[val_15]] : f32
71// CHECK:         %[[val_31:.*]] = math.fma %[[val_2]], %[[val_30]], %[[val_cst_0]] : f32
72// CHECK:         %[[val_32:.*]] = arith.divf %[[val_27]], %[[val_31]] : f32
73// CHECK:         %[[val_33:.*]] = arith.addf %[[val_22]], %[[val_32]] : f32
74// CHECK:         %[[val_34:.*]] = arith.select %[[val_23]], %[[val_33]], %[[val_cst_0]] : f32
75// CHECK:         %[[val_35:.*]] = arith.negf %[[val_34]] : f32
76// CHECK:         %[[val_36:.*]] = arith.select %[[val_0]], %[[val_35]], %[[val_34]] : f32
77// CHECK:         return %[[val_36]] : f32
78// CHECK:       }
79func.func @erf_scalar(%arg0: f32) -> f32 {
80  %0 = math.erf %arg0 : f32
81  return %0 : f32
82}
83
84// CHECK-LABEL:   func @erf_vector(
85// CHECK-SAME:                     %[[arg0:.*]]: vector<8xf32>) -> vector<8xf32> {
86// CHECK:           %[[zero:.*]] = arith.constant dense<0.000000e+00> : vector<8xf32>
87// CHECK-NOT:       erf
88// CHECK-COUNT-20:  select
89// CHECK:           %[[res:.*]] = arith.select
90// CHECK:           return %[[res]] : vector<8xf32>
91// CHECK:         }
92func.func @erf_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
93  %0 = math.erf %arg0 : vector<8xf32>
94  return %0 : vector<8xf32>
95}
96
97// CHECK-LABEL:   func @erf_scalable_vector(
98// CHECK-SAME:                     %[[arg0:.*]]: vector<[8]xf32>) -> vector<[8]xf32> {
99// CHECK:           %[[zero:.*]] = arith.constant dense<0.000000e+00> : vector<[8]xf32>
100// CHECK-NOT:       erf
101// CHECK-NOT:       vector<8xf32>
102// CHECK-COUNT-20:  select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
103// CHECK:           %[[res:.*]] = arith.select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
104// CHECK:           return %[[res]] : vector<[8]xf32>
105// CHECK:         }
106func.func @erf_scalable_vector(%arg0: vector<[8]xf32>) -> vector<[8]xf32> {
107  %0 = math.erf %arg0 : vector<[8]xf32>
108  return %0 : vector<[8]xf32>
109}
110
111// CHECK-LABEL:   func @exp_scalar(
112// CHECK-SAME:                     %[[VAL_0:.*]]: f32) -> f32 {
113// CHECK-DAG:       %[[VAL_1:.*]] = arith.constant 5.000000e-01 : f32
114// CHECK-DAG:       %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
115// CHECK-DAG:       %[[VAL_3:.*]] = arith.constant 1.44269502 : f32
116// CHECK-DAG:       %[[VAL_4:.*]] = arith.constant -0.693359375 : f32
117// CHECK-DAG:       %[[VAL_5:.*]] = arith.constant 2.12194442E-4 : f32
118// CHECK-DAG:       %[[VAL_6:.*]] = arith.constant 1.98756912E-4 : f32
119// CHECK-DAG:       %[[VAL_7:.*]] = arith.constant 0.00139819994 : f32
120// CHECK-DAG:       %[[VAL_8:.*]] = arith.constant 0.00833345205 : f32
121// CHECK-DAG:       %[[VAL_9:.*]] = arith.constant 0.0416657962 : f32
122// CHECK-DAG:       %[[VAL_10:.*]] = arith.constant 0.166666657 : f32
123// CHECK-DAG:       %[[VAL_11:.*]] = arith.constant -8.780000e+01 : f32
124// CHECK-DAG:       %[[VAL_12:.*]] = arith.constant 8.880000e+01 : f32
125// CHECK-DAG:       %[[VAL_13:.*]] = arith.constant -1.270000e+02 : f32
126// CHECK-DAG:       %[[VAL_14:.*]] = arith.constant 1.270000e+02 : f32
127// CHECK-DAG:       %[[VAL_15:.*]] = arith.constant 23 : i32
128// CHECK-DAG:       %[[VAL_16:.*]] = arith.constant 127 : i32
129// CHECK-DAG:       %[[VAL_17:.*]] = arith.cmpf uge, %[[VAL_0]], %[[VAL_11]] : f32
130// CHECK-DAG:       %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_0]], %[[VAL_11]] : f32
131// CHECK-DAG:       %[[VAL_19:.*]] = arith.cmpf ule, %[[VAL_18]], %[[VAL_12]] : f32
132// CHECK-DAG:       %[[VAL_20:.*]] = arith.select %[[VAL_19]], %[[VAL_18]], %[[VAL_12]] : f32
133// CHECK-DAG:       %[[VAL_21:.*]] = math.fma %[[VAL_20]], %[[VAL_3]], %[[VAL_1]] : f32
134// CHECK-DAG:       %[[VAL_22:.*]] = math.floor %[[VAL_21]] : f32
135// CHECK-DAG:       %[[VAL_23:.*]] = arith.cmpf uge, %[[VAL_22]], %[[VAL_13]] : f32
136// CHECK-DAG:       %[[VAL_24:.*]] = arith.select %[[VAL_23]], %[[VAL_22]], %[[VAL_13]] : f32
137// CHECK-DAG:       %[[VAL_25:.*]] = arith.cmpf ule, %[[VAL_24]], %[[VAL_14]] : f32
138// CHECK-DAG:       %[[VAL_26:.*]] = arith.select %[[VAL_25]], %[[VAL_24]], %[[VAL_14]] : f32
139// CHECK-DAG:       %[[VAL_27:.*]] = math.fma %[[VAL_4]], %[[VAL_26]], %[[VAL_20]] : f32
140// CHECK-DAG:       %[[VAL_28:.*]] = math.fma %[[VAL_5]], %[[VAL_26]], %[[VAL_27]] : f32
141// CHECK-DAG:       %[[VAL_29:.*]] = math.fma %[[VAL_28]], %[[VAL_6]], %[[VAL_7]] : f32
142// CHECK-DAG:       %[[VAL_30:.*]] = math.fma %[[VAL_29]], %[[VAL_28]], %[[VAL_8]] : f32
143// CHECK-DAG:       %[[VAL_31:.*]] = math.fma %[[VAL_30]], %[[VAL_28]], %[[VAL_9]] : f32
144// CHECK-DAG:       %[[VAL_32:.*]] = math.fma %[[VAL_31]], %[[VAL_28]], %[[VAL_10]] : f32
145// CHECK-DAG:       %[[VAL_33:.*]] = math.fma %[[VAL_32]], %[[VAL_28]], %[[VAL_1]] : f32
146// CHECK-DAG:       %[[VAL_34:.*]] = arith.mulf %[[VAL_28]], %[[VAL_28]] : f32
147// CHECK-DAG:       %[[VAL_35:.*]] = math.fma %[[VAL_33]], %[[VAL_34]], %[[VAL_28]] : f32
148// CHECK-DAG:       %[[VAL_36:.*]] = arith.addf %[[VAL_35]], %[[VAL_2]] : f32
149// CHECK-DAG:       %[[VAL_37:.*]] = arith.fptosi %[[VAL_26]] : f32 to i32
150// CHECK-DAG:       %[[VAL_38:.*]] = arith.addi %[[VAL_37]], %[[VAL_16]] : i32
151// CHECK-DAG:       %[[VAL_39:.*]] = arith.shli %[[VAL_38]], %[[VAL_15]] : i32
152// CHECK-DAG:       %[[VAL_40:.*]] = arith.bitcast %[[VAL_39]] : i32 to f32
153// CHECK-DAG:       %[[VAL_41:.*]] = arith.mulf %[[VAL_36]], %[[VAL_40]] : f32
154// CHECK:           return %[[VAL_41]] : f32
155func.func @exp_scalar(%arg0: f32) -> f32 {
156  %0 = math.exp %arg0 : f32
157  return %0 : f32
158}
159
160// CHECK-LABEL:   func @exp_vector(
161// CHECK-SAME:                     %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
162// CHECK-NOT:   math.exp
163func.func @exp_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
164  %0 = math.exp %arg0 : vector<8xf32>
165  return %0 : vector<8xf32>
166}
167
168// CHECK-LABEL:   func @exp_scalable_vector
169// CHECK-NOT:      math.exp
170// CHECK-NOT:      vector<8xf32>
171// CHECK-COUNT-46: vector<[8]x{{(i32)|(f32)}}>
172// CHECK-NOT:      vector<8xf32>
173// CHECK-NOT:      math.exp
174func.func @exp_scalable_vector(%arg0: vector<[8]xf32>) -> vector<[8]xf32> {
175  %0 = math.exp %arg0 : vector<[8]xf32>
176  return %0 : vector<[8]xf32>
177}
178
179// CHECK-LABEL:   func @expm1_scalar(
180// CHECK-SAME:                       %[[X:.*]]: f32) -> f32 {
181// CHECK-DAG:       %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f32
182// CHECK-DAG:       %[[VAL_2:.*]] = arith.constant -1.000000e+00 : f32
183// CHECK-DAG:       %[[VAL_3:.*]] = arith.constant 5.000000e-01 : f32
184// CHECK-DAG:       %[[VAL_4:.*]] = arith.constant 1.44269502 : f32
185// CHECK-DAG:       %[[VAL_5:.*]] = arith.constant -0.693359375 : f32
186// CHECK-DAG:       %[[VAL_6:.*]] = arith.constant 2.12194442E-4 : f32
187// CHECK-DAG:       %[[VAL_7:.*]] = arith.constant 1.98756912E-4 : f32
188// CHECK-DAG:       %[[VAL_8:.*]] = arith.constant 0.00139819994 : f32
189// CHECK-DAG:       %[[VAL_9:.*]] = arith.constant 0.00833345205 : f32
190// CHECK-DAG:       %[[VAL_10:.*]] = arith.constant 0.0416657962 : f32
191// CHECK-DAG:       %[[VAL_11:.*]] = arith.constant 0.166666657 : f32
192// CHECK-DAG:       %[[VAL_12:.*]] = arith.constant -8.780000e+01 : f32
193// CHECK-DAG:       %[[VAL_13:.*]] = arith.constant 8.880000e+01 : f32
194// CHECK-DAG:       %[[VAL_14:.*]] = arith.constant -1.270000e+02 : f32
195// CHECK-DAG:       %[[VAL_15:.*]] = arith.constant 1.270000e+02 : f32
196// CHECK-DAG:       %[[VAL_16:.*]] = arith.constant 23 : i32
197// CHECK-DAG:       %[[VAL_17:.*]] = arith.constant 127 : i32
198// CHECK-DAG:       %[[VAL_18:.*]] = arith.constant 0.000000e+00 : f32
199// CHECK-DAG:       %[[VAL_19:.*]] = arith.constant -5.000000e-01 : f32
200// CHECK-DAG:       %[[VAL_20:.*]] = arith.constant 1.17549435E-38 : f32
201// CHECK-DAG:       %[[VAL_21:.*]] = arith.constant 0xFF800000 : f32
202// CHECK-DAG:       %[[VAL_22:.*]] = arith.constant 0x7F800000 : f32
203// CHECK-DAG:       %[[VAL_23:.*]] = arith.constant 0x7FC00000 : f32
204// CHECK-DAG:       %[[VAL_24:.*]] = arith.constant 0.707106769 : f32
205// CHECK-DAG:       %[[VAL_25:.*]] = arith.constant 0.0703768358 : f32
206// CHECK-DAG:       %[[VAL_26:.*]] = arith.constant -0.115146101 : f32
207// CHECK-DAG:       %[[VAL_27:.*]] = arith.constant 0.116769984 : f32
208// CHECK-DAG:       %[[VAL_28:.*]] = arith.constant -0.12420141 : f32
209// CHECK-DAG:       %[[VAL_29:.*]] = arith.constant 0.142493233 : f32
210// CHECK-DAG:       %[[VAL_30:.*]] = arith.constant -0.166680574 : f32
211// CHECK-DAG:       %[[VAL_31:.*]] = arith.constant 0.200007141 : f32
212// CHECK-DAG:       %[[VAL_32:.*]] = arith.constant -0.24999994 : f32
213// CHECK-DAG:       %[[VAL_33:.*]] = arith.constant 0.333333313 : f32
214// CHECK-DAG:       %[[VAL_34:.*]] = arith.constant 1.260000e+02 : f32
215// CHECK-DAG:       %[[VAL_35:.*]] = arith.constant -2139095041 : i32
216// CHECK-DAG:       %[[VAL_36:.*]] = arith.constant 1056964608 : i32
217// CHECK-DAG:       %[[VAL_37:.*]] = arith.constant 0.693147182 : f32
218// CHECK-DAG:       %[[VAL_38:.*]] = arith.cmpf uge, %[[X]], %[[VAL_12]] : f32
219// CHECK-DAG:       %[[VAL_39:.*]] = arith.select %[[VAL_38]], %[[X]], %[[VAL_12]] : f32
220// CHECK-DAG:       %[[VAL_40:.*]] = arith.cmpf ule, %[[VAL_39]], %[[VAL_13]] : f32
221// CHECK-DAG:       %[[VAL_41:.*]] = arith.select %[[VAL_40]], %[[VAL_39]], %[[VAL_13]] : f32
222// CHECK-DAG:       %[[VAL_42:.*]] = math.fma %[[VAL_41]], %[[VAL_4]], %[[VAL_3]] : f32
223// CHECK-DAG:       %[[VAL_43:.*]] = math.floor %[[VAL_42]] : f32
224// CHECK-DAG:       %[[VAL_44:.*]] = arith.cmpf uge, %[[VAL_43]], %[[VAL_14]] : f32
225// CHECK-DAG:       %[[VAL_45:.*]] = arith.select %[[VAL_44]], %[[VAL_43]], %[[VAL_14]] : f32
226// CHECK-DAG:       %[[VAL_46:.*]] = arith.cmpf ule, %[[VAL_45]], %[[VAL_15]] : f32
227// CHECK-DAG:       %[[VAL_47:.*]] = arith.select %[[VAL_46]], %[[VAL_45]], %[[VAL_15]] : f32
228// CHECK-DAG:       %[[VAL_48:.*]] = math.fma %[[VAL_5]], %[[VAL_47]], %[[VAL_41]] : f32
229// CHECK-DAG:       %[[VAL_49:.*]] = math.fma %[[VAL_6]], %[[VAL_47]], %[[VAL_48]] : f32
230// CHECK-DAG:       %[[VAL_50:.*]] = math.fma %[[VAL_49]], %[[VAL_7]], %[[VAL_8]] : f32
231// CHECK-DAG:       %[[VAL_51:.*]] = math.fma %[[VAL_50]], %[[VAL_49]], %[[VAL_9]] : f32
232// CHECK-DAG:       %[[VAL_52:.*]] = math.fma %[[VAL_51]], %[[VAL_49]], %[[VAL_10]] : f32
233// CHECK-DAG:       %[[VAL_53:.*]] = math.fma %[[VAL_52]], %[[VAL_49]], %[[VAL_11]] : f32
234// CHECK-DAG:       %[[VAL_54:.*]] = math.fma %[[VAL_53]], %[[VAL_49]], %[[VAL_3]] : f32
235// CHECK-DAG:       %[[VAL_55:.*]] = arith.mulf %[[VAL_49]], %[[VAL_49]] : f32
236// CHECK-DAG:       %[[VAL_56:.*]] = math.fma %[[VAL_54]], %[[VAL_55]], %[[VAL_49]] : f32
237// CHECK-DAG:       %[[VAL_57:.*]] = arith.addf %[[VAL_56]], %[[VAL_1]] : f32
238// CHECK-DAG:       %[[VAL_58:.*]] = arith.fptosi %[[VAL_47]] : f32 to i32
239// CHECK-DAG:       %[[VAL_59:.*]] = arith.addi %[[VAL_58]], %[[VAL_17]] : i32
240// CHECK-DAG:       %[[VAL_60:.*]] = arith.shli %[[VAL_59]], %[[VAL_16]] : i32
241// CHECK-DAG:       %[[VAL_61:.*]] = arith.bitcast %[[VAL_60]] : i32 to f32
242// CHECK-DAG:       %[[VAL_62:.*]] = arith.mulf %[[VAL_57]], %[[VAL_61]] : f32
243// CHECK-DAG:       %[[VAL_63:.*]] = arith.cmpf ueq, %[[VAL_62]], %[[VAL_1]] : f32
244// CHECK-DAG:       %[[VAL_64:.*]] = arith.subf %[[VAL_62]], %[[VAL_1]] : f32
245// CHECK-DAG:       %[[VAL_65:.*]] = arith.cmpf oeq, %[[VAL_64]], %[[VAL_2]] : f32
246// CHECK-DAG:       %[[VAL_66:.*]] = arith.cmpf ugt, %[[VAL_62]], %[[VAL_20]] : f32
247// CHECK-DAG:       %[[VAL_67:.*]] = arith.select %[[VAL_66]], %[[VAL_62]], %[[VAL_20]] : f32
248// CHECK-DAG:       %[[VAL_68:.*]] = arith.bitcast %[[VAL_67]] : f32 to i32
249// CHECK-DAG:       %[[VAL_69:.*]] = arith.andi %[[VAL_68]], %[[VAL_35]] : i32
250// CHECK-DAG:       %[[VAL_70:.*]] = arith.ori %[[VAL_69]], %[[VAL_36]] : i32
251// CHECK-DAG:       %[[VAL_71:.*]] = arith.bitcast %[[VAL_70]] : i32 to f32
252// CHECK-DAG:       %[[VAL_72:.*]] = arith.bitcast %[[VAL_67]] : f32 to i32
253// CHECK-DAG:       %[[VAL_73:.*]] = arith.shrui %[[VAL_72]], %[[VAL_16]] : i32
254// CHECK-DAG:       %[[VAL_74:.*]] = arith.sitofp %[[VAL_73]] : i32 to f32
255// CHECK-DAG:       %[[VAL_75:.*]] = arith.subf %[[VAL_74]], %[[VAL_34]] : f32
256// CHECK-DAG:       %[[VAL_76:.*]] = arith.cmpf olt, %[[VAL_71]], %[[VAL_24]] : f32
257// CHECK-DAG:       %[[VAL_77:.*]] = arith.select %[[VAL_76]], %[[VAL_71]], %[[VAL_18]] : f32
258// CHECK-DAG:       %[[VAL_78:.*]] = arith.subf %[[VAL_71]], %[[VAL_1]] : f32
259// CHECK-DAG:       %[[VAL_79:.*]] = arith.select %[[VAL_76]], %[[VAL_1]], %[[VAL_18]] : f32
260// CHECK-DAG:       %[[VAL_80:.*]] = arith.subf %[[VAL_75]], %[[VAL_79]] : f32
261// CHECK-DAG:       %[[VAL_81:.*]] = arith.addf %[[VAL_78]], %[[VAL_77]] : f32
262// CHECK-DAG:       %[[VAL_82:.*]] = arith.mulf %[[VAL_81]], %[[VAL_81]] : f32
263// CHECK-DAG:       %[[VAL_83:.*]] = arith.mulf %[[VAL_82]], %[[VAL_81]] : f32
264// CHECK-DAG:       %[[VAL_84:.*]] = math.fma %[[VAL_25]], %[[VAL_81]], %[[VAL_26]] : f32
265// CHECK-DAG:       %[[VAL_85:.*]] = math.fma %[[VAL_28]], %[[VAL_81]], %[[VAL_29]] : f32
266// CHECK-DAG:       %[[VAL_86:.*]] = math.fma %[[VAL_31]], %[[VAL_81]], %[[VAL_32]] : f32
267// CHECK-DAG:       %[[VAL_87:.*]] = math.fma %[[VAL_84]], %[[VAL_81]], %[[VAL_27]] : f32
268// CHECK-DAG:       %[[VAL_88:.*]] = math.fma %[[VAL_85]], %[[VAL_81]], %[[VAL_30]] : f32
269// CHECK-DAG:       %[[VAL_89:.*]] = math.fma %[[VAL_86]], %[[VAL_81]], %[[VAL_33]] : f32
270// CHECK-DAG:       %[[VAL_90:.*]] = math.fma %[[VAL_87]], %[[VAL_83]], %[[VAL_88]] : f32
271// CHECK-DAG:       %[[VAL_91:.*]] = math.fma %[[VAL_90]], %[[VAL_83]], %[[VAL_89]] : f32
272// CHECK-DAG:       %[[VAL_92:.*]] = arith.mulf %[[VAL_91]], %[[VAL_83]] : f32
273// CHECK-DAG:       %[[VAL_93:.*]] = math.fma %[[VAL_19]], %[[VAL_82]], %[[VAL_92]] : f32
274// CHECK-DAG:       %[[VAL_94:.*]] = arith.addf %[[VAL_81]], %[[VAL_93]] : f32
275// CHECK-DAG:       %[[VAL_95:.*]] = math.fma %[[VAL_80]], %[[VAL_37]], %[[VAL_94]] : f32
276// CHECK-DAG:       %[[VAL_96:.*]] = arith.cmpf ult, %[[VAL_62]], %[[VAL_18]] : f32
277// CHECK-DAG:       %[[VAL_97:.*]] = arith.cmpf oeq, %[[VAL_62]], %[[VAL_18]] : f32
278// CHECK-DAG:       %[[VAL_98:.*]] = arith.cmpf oeq, %[[VAL_62]], %[[VAL_22]] : f32
279// CHECK-DAG:       %[[VAL_99:.*]] = arith.select %[[VAL_98]], %[[VAL_22]], %[[VAL_95]] : f32
280// CHECK-DAG:       %[[VAL_100:.*]] = arith.select %[[VAL_96]], %[[VAL_23]], %[[VAL_99]] : f32
281// CHECK-DAG:       %[[VAL_101:.*]] = arith.select %[[VAL_97]], %[[VAL_21]], %[[VAL_100]] : f32
282// CHECK-DAG:       %[[VAL_102:.*]] = arith.cmpf oeq, %[[VAL_101]], %[[VAL_62]] : f32
283// CHECK-DAG:       %[[VAL_103:.*]] = arith.divf %[[X]], %[[VAL_101]] : f32
284// CHECK-DAG:       %[[VAL_104:.*]] = arith.mulf %[[VAL_64]], %[[VAL_103]] : f32
285// CHECK-DAG:       %[[VAL_105:.*]] = arith.select %[[VAL_102]], %[[VAL_62]], %[[VAL_104]] : f32
286// CHECK-DAG:       %[[VAL_106:.*]] = arith.select %[[VAL_65]], %[[VAL_2]], %[[VAL_105]] : f32
287// CHECK-DAG:       %[[VAL_107:.*]] = arith.select %[[VAL_63]], %[[X]], %[[VAL_106]] : f32
288// CHECK-DAG:       return %[[VAL_107]] : f32
289// CHECK:         }
290func.func @expm1_scalar(%arg0: f32) -> f32 {
291  %0 = math.expm1 %arg0 : f32
292  return %0 : f32
293}
294
295// CHECK-LABEL:   func @expm1_vector(
296// CHECK-SAME:                       %[[VAL_0:.*]]: vector<8x8xf32>) -> vector<8x8xf32> {
297// CHECK-NOT:       exp
298// CHECK-NOT:       log
299// CHECK-NOT:       expm1
300func.func @expm1_vector(%arg0: vector<8x8xf32>) -> vector<8x8xf32> {
301  %0 = math.expm1 %arg0 : vector<8x8xf32>
302  return %0 : vector<8x8xf32>
303}
304
305// CHECK-LABEL:   func @expm1_scalable_vector(
306// CHECK-SAME:                       %{{.*}}: vector<8x[8]xf32>) -> vector<8x[8]xf32> {
307// CHECK-NOT:       vector<8x8xf32>
308// CHECK-NOT:       exp
309// CHECK-NOT:       log
310// CHECK-NOT:       expm1
311// CHECK-COUNT-127: vector<8x[8]x{{(i32)|(f32)|(i1)}}>
312// CHECK-NOT:       vector<8x8xf32>
313// CHECK-NOT:       exp
314// CHECK-NOT:       log
315// CHECK-NOT:       expm1
316func.func @expm1_scalable_vector(%arg0: vector<8x[8]xf32>) -> vector<8x[8]xf32> {
317  %0 = math.expm1 %arg0 : vector<8x[8]xf32>
318  return %0 : vector<8x[8]xf32>
319}
320
321// CHECK-LABEL:   func @log_scalar(
322// CHECK-SAME:                             %[[X:.*]]: f32) -> f32 {
323// CHECK-DAG:       %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32
324// CHECK-DAG:       %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
325// CHECK-DAG:       %[[VAL_3:.*]] = arith.constant -5.000000e-01 : f32
326// CHECK-DAG:       %[[VAL_4:.*]] = arith.constant 1.17549435E-38 : f32
327// CHECK-DAG:       %[[VAL_5:.*]] = arith.constant 0xFF800000 : f32
328// CHECK-DAG:       %[[VAL_6:.*]] = arith.constant 0x7F800000 : f32
329// CHECK-DAG:       %[[VAL_7:.*]] = arith.constant 0x7FC00000 : f32
330// CHECK-DAG:       %[[VAL_8:.*]] = arith.constant 0.707106769 : f32
331// CHECK-DAG:       %[[VAL_9:.*]] = arith.constant 0.0703768358 : f32
332// CHECK-DAG:       %[[VAL_10:.*]] = arith.constant -0.115146101 : f32
333// CHECK-DAG:       %[[VAL_11:.*]] = arith.constant 0.116769984 : f32
334// CHECK-DAG:       %[[VAL_12:.*]] = arith.constant -0.12420141 : f32
335// CHECK-DAG:       %[[VAL_13:.*]] = arith.constant 0.142493233 : f32
336// CHECK-DAG:       %[[VAL_14:.*]] = arith.constant -0.166680574 : f32
337// CHECK-DAG:       %[[VAL_15:.*]] = arith.constant 0.200007141 : f32
338// CHECK-DAG:       %[[VAL_16:.*]] = arith.constant -0.24999994 : f32
339// CHECK-DAG:       %[[VAL_17:.*]] = arith.constant 0.333333313 : f32
340// CHECK-DAG:       %[[VAL_18:.*]] = arith.constant 1.260000e+02 : f32
341// CHECK-DAG:       %[[VAL_19:.*]] = arith.constant -2139095041 : i32
342// CHECK-DAG:       %[[VAL_20:.*]] = arith.constant 1056964608 : i32
343// CHECK-DAG:       %[[VAL_21:.*]] = arith.constant 23 : i32
344// CHECK-DAG:       %[[VAL_22:.*]] = arith.constant 0.693147182 : f32
345// CHECK:           %[[VAL_23:.*]] = arith.cmpf ugt, %[[X]], %[[VAL_4]] : f32
346// CHECK:           %[[VAL_24:.*]] = arith.select %[[VAL_23]], %[[X]], %[[VAL_4]] : f32
347// CHECK-NOT:       frexp
348// CHECK:           %[[VAL_25:.*]] = arith.bitcast %[[VAL_24]] : f32 to i32
349// CHECK:           %[[VAL_26:.*]] = arith.andi %[[VAL_25]], %[[VAL_19]] : i32
350// CHECK:           %[[VAL_27:.*]] = arith.ori %[[VAL_26]], %[[VAL_20]] : i32
351// CHECK:           %[[VAL_28:.*]] = arith.bitcast %[[VAL_27]] : i32 to f32
352// CHECK:           %[[VAL_29:.*]] = arith.bitcast %[[VAL_24]] : f32 to i32
353// CHECK:           %[[VAL_30:.*]] = arith.shrui %[[VAL_29]], %[[VAL_21]] : i32
354// CHECK:           %[[VAL_31:.*]] = arith.sitofp %[[VAL_30]] : i32 to f32
355// CHECK:           %[[VAL_32:.*]] = arith.subf %[[VAL_31]], %[[VAL_18]] : f32
356// CHECK:           %[[VAL_33:.*]] = arith.cmpf olt, %[[VAL_28]], %[[VAL_8]] : f32
357// CHECK:           %[[VAL_34:.*]] = arith.select %[[VAL_33]], %[[VAL_28]], %[[VAL_1]] : f32
358// CHECK:           %[[VAL_35:.*]] = arith.subf %[[VAL_28]], %[[VAL_2]] : f32
359// CHECK:           %[[VAL_36:.*]] = arith.select %[[VAL_33]], %[[VAL_2]], %[[VAL_1]] : f32
360// CHECK:           %[[VAL_37:.*]] = arith.subf %[[VAL_32]], %[[VAL_36]] : f32
361// CHECK:           %[[VAL_38:.*]] = arith.addf %[[VAL_35]], %[[VAL_34]] : f32
362// CHECK:           %[[VAL_39:.*]] = arith.mulf %[[VAL_38]], %[[VAL_38]] : f32
363// CHECK:           %[[VAL_40:.*]] = arith.mulf %[[VAL_39]], %[[VAL_38]] : f32
364// CHECK:           %[[VAL_41:.*]] = math.fma %[[VAL_9]], %[[VAL_38]], %[[VAL_10]] : f32
365// CHECK:           %[[VAL_42:.*]] = math.fma %[[VAL_12]], %[[VAL_38]], %[[VAL_13]] : f32
366// CHECK:           %[[VAL_43:.*]] = math.fma %[[VAL_15]], %[[VAL_38]], %[[VAL_16]] : f32
367// CHECK:           %[[VAL_44:.*]] = math.fma %[[VAL_41]], %[[VAL_38]], %[[VAL_11]] : f32
368// CHECK:           %[[VAL_45:.*]] = math.fma %[[VAL_42]], %[[VAL_38]], %[[VAL_14]] : f32
369// CHECK:           %[[VAL_46:.*]] = math.fma %[[VAL_43]], %[[VAL_38]], %[[VAL_17]] : f32
370// CHECK:           %[[VAL_47:.*]] = math.fma %[[VAL_44]], %[[VAL_40]], %[[VAL_45]] : f32
371// CHECK:           %[[VAL_48:.*]] = math.fma %[[VAL_47]], %[[VAL_40]], %[[VAL_46]] : f32
372// CHECK:           %[[VAL_49:.*]] = arith.mulf %[[VAL_48]], %[[VAL_40]] : f32
373// CHECK:           %[[VAL_50:.*]] = math.fma %[[VAL_3]], %[[VAL_39]], %[[VAL_49]] : f32
374// CHECK:           %[[VAL_51:.*]] = arith.addf %[[VAL_38]], %[[VAL_50]] : f32
375// CHECK:           %[[VAL_52:.*]] = math.fma %[[VAL_37]], %[[VAL_22]], %[[VAL_51]] : f32
376// CHECK:           %[[VAL_53:.*]] = arith.cmpf ult, %[[X]], %[[VAL_1]] : f32
377// CHECK:           %[[VAL_54:.*]] = arith.cmpf oeq, %[[X]], %[[VAL_1]] : f32
378// CHECK:           %[[VAL_55:.*]] = arith.cmpf oeq, %[[X]], %[[VAL_6]] : f32
379// CHECK:           %[[VAL_56:.*]] = arith.select %[[VAL_55]], %[[VAL_6]], %[[VAL_52]] : f32
380// CHECK:           %[[VAL_57:.*]] = arith.select %[[VAL_53]], %[[VAL_7]], %[[VAL_56]] : f32
381// CHECK:           %[[VAL_58:.*]] = arith.select %[[VAL_54]], %[[VAL_5]], %[[VAL_57]] : f32
382// CHECK:           return %[[VAL_58]] : f32
383// CHECK:         }
384func.func @log_scalar(%arg0: f32) -> f32 {
385  %0 = math.log %arg0 : f32
386  return %0 : f32
387}
388
389// CHECK-LABEL:   func @log_vector(
390// CHECK-SAME:                     %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
391// CHECK:           %[[CST_LN2:.*]] = arith.constant dense<0.693147182> : vector<8xf32>
392// CHECK-COUNT-5:   select
393// CHECK:           %[[VAL_71:.*]] = arith.select
394// CHECK:           return %[[VAL_71]] : vector<8xf32>
395// CHECK:         }
396func.func @log_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
397  %0 = math.log %arg0 : vector<8xf32>
398  return %0 : vector<8xf32>
399}
400
401// CHECK-LABEL:   func @log_scalable_vector(
402// CHECK-SAME:                     %{{.*}}: vector<[8]xf32>) -> vector<[8]xf32> {
403// CHECK:           %[[CST_LN2:.*]] = arith.constant dense<0.693147182> : vector<[8]xf32>
404// CHECK-COUNT-5:   select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
405// CHECK:           %[[VAL_71:.*]] = arith.select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
406// CHECK:           return %[[VAL_71]] : vector<[8]xf32>
407// CHECK:         }
408func.func @log_scalable_vector(%arg0: vector<[8]xf32>) -> vector<[8]xf32> {
409  %0 = math.log %arg0 : vector<[8]xf32>
410  return %0 : vector<[8]xf32>
411}
412
413// CHECK-LABEL:   func @log2_scalar(
414// CHECK-SAME:                      %[[VAL_0:.*]]: f32) -> f32 {
415// CHECK:           %[[CST_LOG2E:.*]] = arith.constant 1.44269502 : f32
416// CHECK-COUNT-5:   select
417// CHECK:           %[[VAL_65:.*]] = arith.select
418// CHECK:           return %[[VAL_65]] : f32
419// CHECK:         }
420func.func @log2_scalar(%arg0: f32) -> f32 {
421  %0 = math.log2 %arg0 : f32
422  return %0 : f32
423}
424
425// CHECK-LABEL:   func @log2_vector(
426// CHECK-SAME:                      %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
427// CHECK:           %[[CST_LOG2E:.*]] = arith.constant dense<1.44269502> : vector<8xf32>
428// CHECK-COUNT-5:   select
429// CHECK:           %[[VAL_71:.*]] = arith.select
430// CHECK:           return %[[VAL_71]] : vector<8xf32>
431// CHECK:         }
432func.func @log2_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
433  %0 = math.log2 %arg0 : vector<8xf32>
434  return %0 : vector<8xf32>
435}
436
437// CHECK-LABEL:   func @log2_scalable_vector(
438// CHECK-SAME:                      %{{.*}}: vector<[8]xf32>) -> vector<[8]xf32> {
439// CHECK:           %[[CST_LOG2E:.*]] = arith.constant dense<1.44269502> : vector<[8]xf32>
440// CHECK-COUNT-5:   select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
441// CHECK:           %[[VAL_71:.*]] = arith.select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
442// CHECK:           return %[[VAL_71]] : vector<[8]xf32>
443// CHECK:         }
444func.func @log2_scalable_vector(%arg0: vector<[8]xf32>) -> vector<[8]xf32> {
445  %0 = math.log2 %arg0 : vector<[8]xf32>
446  return %0 : vector<[8]xf32>
447}
448
449// CHECK-LABEL:   func @log1p_scalar(
450// CHECK-SAME:                       %[[X:.*]]: f32) -> f32 {
451// CHECK:           %[[CST_ONE:.*]] = arith.constant 1.000000e+00 : f32
452// CHECK:           %[[U:.*]] = arith.addf %[[X]], %[[CST_ONE]] : f32
453// CHECK:           %[[U_SMALL:.*]] = arith.cmpf oeq, %[[U]], %[[CST_ONE]] : f32
454// CHECK-NOT:       log
455// CHECK-COUNT-5:   select
456// CHECK:           %[[LOG_U:.*]] = arith.select
457// CHECK:           %[[U_INF:.*]] = arith.cmpf oeq, %[[U]], %[[LOG_U]] : f32
458// CHECK:           %[[VAL_69:.*]] = arith.subf %[[U]], %[[CST_ONE]] : f32
459// CHECK:           %[[VAL_70:.*]] = arith.divf %[[LOG_U]], %[[VAL_69]] : f32
460// CHECK:           %[[LOG_LARGE:.*]] = arith.mulf %[[X]], %[[VAL_70]] : f32
461// CHECK:           %[[VAL_72:.*]] = arith.ori %[[U_SMALL]], %[[U_INF]]  : i1
462// CHECK:           %[[APPROX:.*]] = arith.select %[[VAL_72]], %[[X]], %[[LOG_LARGE]] : f32
463// CHECK:           return %[[APPROX]] : f32
464// CHECK:         }
465func.func @log1p_scalar(%arg0: f32) -> f32 {
466  %0 = math.log1p %arg0 : f32
467  return %0 : f32
468}
469
470// CHECK-LABEL:   func @log1p_vector(
471// CHECK-SAME:                       %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
472// CHECK:           %[[CST_ONE:.*]] = arith.constant dense<1.000000e+00> : vector<8xf32>
473// CHECK-COUNT-6:   select
474// CHECK:           %[[VAL_79:.*]] = arith.select
475// CHECK:           return %[[VAL_79]] : vector<8xf32>
476// CHECK:         }
477func.func @log1p_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
478  %0 = math.log1p %arg0 : vector<8xf32>
479  return %0 : vector<8xf32>
480}
481
482// CHECK-LABEL:   func @log1p_scalable_vector(
483// CHECK-SAME:                       %[[VAL_0:.*]]: vector<[8]xf32>) -> vector<[8]xf32> {
484// CHECK:           %[[CST_ONE:.*]] = arith.constant dense<1.000000e+00> : vector<[8]xf32>
485// CHECK-COUNT-6:   select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
486// CHECK:           %[[VAL_79:.*]] = arith.select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
487// CHECK:           return %[[VAL_79]] : vector<[8]xf32>
488// CHECK:         }
489func.func @log1p_scalable_vector(%arg0: vector<[8]xf32>) -> vector<[8]xf32> {
490  %0 = math.log1p %arg0 : vector<[8]xf32>
491  return %0 : vector<[8]xf32>
492}
493
494// CHECK-LABEL:   func @tanh_scalar(
495// CHECK-SAME:                      %[[VAL_0:.*]]: f32) -> f32 {
496// CHECK-DAG:       %[[VAL_1:.*]] = arith.constant -7.99881172 : f32
497// CHECK-DAG:       %[[VAL_2:.*]] = arith.constant 7.99881172 : f32
498// CHECK-DAG:       %[[VAL_3:.*]] = arith.constant 4.000000e-04 : f32
499// CHECK-DAG:       %[[VAL_4:.*]] = arith.constant 0.00489352457 : f32
500// CHECK-DAG:       %[[VAL_5:.*]] = arith.constant 6.37261954E-4 : f32
501// CHECK-DAG:       %[[VAL_6:.*]] = arith.constant 1.48572235E-5 : f32
502// CHECK-DAG:       %[[VAL_7:.*]] = arith.constant 5.12229725E-8 : f32
503// CHECK-DAG:       %[[VAL_8:.*]] = arith.constant -8.60467184E-11 : f32
504// CHECK-DAG:       %[[VAL_9:.*]] = arith.constant 2.00018794E-13 : f32
505// CHECK-DAG:       %[[VAL_10:.*]] = arith.constant -2.76076837E-16 : f32
506// CHECK-DAG:       %[[VAL_11:.*]] = arith.constant 0.00489352504 : f32
507// CHECK-DAG:       %[[VAL_12:.*]] = arith.constant 0.00226843474 : f32
508// CHECK-DAG:       %[[VAL_13:.*]] = arith.constant 1.18534706E-4 : f32
509// CHECK-DAG:       %[[VAL_14:.*]] = arith.constant 1.19825836E-6 : f32
510// CHECK:           %[[VAL_15:.*]] = arith.cmpf ult, %[[VAL_0]], %[[VAL_2]] : f32
511// CHECK:           %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_0]], %[[VAL_2]] : f32
512// CHECK:           %[[VAL_17:.*]] = arith.cmpf ugt, %[[VAL_16]], %[[VAL_1]] : f32
513// CHECK:           %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_16]], %[[VAL_1]] : f32
514// CHECK:           %[[VAL_19:.*]] = math.absf %[[VAL_0]] : f32
515// CHECK:           %[[VAL_20:.*]] = arith.cmpf olt, %[[VAL_19]], %[[VAL_3]] : f32
516// CHECK:           %[[VAL_21:.*]] = arith.mulf %[[VAL_18]], %[[VAL_18]] : f32
517// CHECK:           %[[VAL_22:.*]] = math.fma %[[VAL_21]], %[[VAL_10]], %[[VAL_9]] : f32
518// CHECK:           %[[VAL_23:.*]] = math.fma %[[VAL_21]], %[[VAL_22]], %[[VAL_8]] : f32
519// CHECK:           %[[VAL_24:.*]] = math.fma %[[VAL_21]], %[[VAL_23]], %[[VAL_7]] : f32
520// CHECK:           %[[VAL_25:.*]] = math.fma %[[VAL_21]], %[[VAL_24]], %[[VAL_6]] : f32
521// CHECK:           %[[VAL_26:.*]] = math.fma %[[VAL_21]], %[[VAL_25]], %[[VAL_5]] : f32
522// CHECK:           %[[VAL_27:.*]] = math.fma %[[VAL_21]], %[[VAL_26]], %[[VAL_4]] : f32
523// CHECK:           %[[VAL_28:.*]] = arith.mulf %[[VAL_18]], %[[VAL_27]] : f32
524// CHECK:           %[[VAL_29:.*]] = math.fma %[[VAL_21]], %[[VAL_14]], %[[VAL_13]] : f32
525// CHECK:           %[[VAL_30:.*]] = math.fma %[[VAL_21]], %[[VAL_29]], %[[VAL_12]] : f32
526// CHECK:           %[[VAL_31:.*]] = math.fma %[[VAL_21]], %[[VAL_30]], %[[VAL_11]] : f32
527// CHECK:           %[[VAL_32:.*]] = arith.divf %[[VAL_28]], %[[VAL_31]] : f32
528// CHECK:           %[[VAL_33:.*]] = arith.select %[[VAL_20]], %[[VAL_18]], %[[VAL_32]] : f32
529// CHECK:           return %[[VAL_33]] : f32
530// CHECK:         }
531func.func @tanh_scalar(%arg0: f32) -> f32 {
532  %0 = math.tanh %arg0 : f32
533  return %0 : f32
534}
535
536// CHECK-LABEL:   func @tanh_vector(
537// CHECK-SAME:                      %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
538// CHECK:           %[[VAL_1:.*]] = arith.constant dense<-7.99881172> : vector<8xf32>
539// CHECK-NOT:       tanh
540// CHECK-COUNT-2:   select
541// CHECK:           %[[VAL_33:.*]] = arith.select
542// CHECK:           return %[[VAL_33]] : vector<8xf32>
543// CHECK:         }
544func.func @tanh_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
545  %0 = math.tanh %arg0 : vector<8xf32>
546  return %0 : vector<8xf32>
547}
548
549// CHECK-LABEL:   func @tanh_scalable_vector(
550// CHECK-SAME:                      %[[VAL_0:.*]]: vector<[8]xf32>) -> vector<[8]xf32> {
551// CHECK:           %[[VAL_1:.*]] = arith.constant dense<-7.99881172> : vector<[8]xf32>
552// CHECK-NOT:       tanh
553// CHECK-COUNT-2:   select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
554// CHECK:           %[[VAL_33:.*]] = arith.select {{.*}} : vector<[8]xi1>, vector<[8]xf32>
555// CHECK:           return %[[VAL_33]] : vector<[8]xf32>
556// CHECK:         }
557func.func @tanh_scalable_vector(%arg0: vector<[8]xf32>) -> vector<[8]xf32> {
558  %0 = math.tanh %arg0 : vector<[8]xf32>
559  return %0 : vector<[8]xf32>
560}
561
562// We only approximate rsqrt for vectors and when the AVX2 option is enabled.
563// CHECK-LABEL:   func @rsqrt_scalar
564// AVX2-LABEL:    func @rsqrt_scalar
565// CHECK:           math.rsqrt
566// AVX2:            math.rsqrt
567func.func @rsqrt_scalar(%arg0: f32) -> f32 {
568  %0 = math.rsqrt %arg0 : f32
569  return %0 : f32
570}
571
572// CHECK-LABEL:   func @rsqrt_vector_8xf32
573// CHECK:           math.rsqrt
574// AVX2-LABEL:    func @rsqrt_vector_8xf32(
575// AVX2-SAME:       %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
576// AVX2:   %[[VAL_1:.*]] = arith.constant dense<0x7F800000> : vector<8xf32>
577// AVX2:   %[[VAL_2:.*]] = arith.constant dense<1.500000e+00> : vector<8xf32>
578// AVX2:   %[[VAL_3:.*]] = arith.constant dense<-5.000000e-01> : vector<8xf32>
579// AVX2:   %[[VAL_4:.*]] = arith.constant dense<1.17549435E-38> : vector<8xf32>
580// AVX2:   %[[VAL_5:.*]] = arith.mulf %[[VAL_0]], %[[VAL_3]] : vector<8xf32>
581// AVX2:   %[[VAL_6:.*]] = arith.cmpf olt, %[[VAL_0]], %[[VAL_4]] : vector<8xf32>
582// AVX2:   %[[VAL_7:.*]] = arith.cmpf oeq, %[[VAL_0]], %[[VAL_1]] : vector<8xf32>
583// AVX2:   %[[VAL_8:.*]] = arith.ori %[[VAL_6]], %[[VAL_7]] : vector<8xi1>
584// AVX2:   %[[VAL_9:.*]] = x86vector.avx.rsqrt %[[VAL_0]] : vector<8xf32>
585// AVX2:   %[[VAL_10:.*]] = arith.mulf %[[VAL_5]], %[[VAL_9]] : vector<8xf32>
586// AVX2:   %[[VAL_11:.*]] = math.fma %[[VAL_9]], %[[VAL_10]], %[[VAL_2]] : vector<8xf32>
587// AVX2:   %[[VAL_12:.*]] = arith.mulf %[[VAL_9]], %[[VAL_11]] : vector<8xf32>
588// AVX2:   %[[VAL_13:.*]] = arith.select %[[VAL_8]], %[[VAL_9]], %[[VAL_12]] : vector<8xi1>, vector<8xf32>
589// AVX2:   return %[[VAL_13]] : vector<8xf32>
590// AVX2: }
591func.func @rsqrt_vector_8xf32(%arg0: vector<8xf32>) -> vector<8xf32> {
592  %0 = math.rsqrt %arg0 : vector<8xf32>
593  return %0 : vector<8xf32>
594}
595
596// Virtual vector width is not a multiple of an AVX2 vector width.
597//
598// CHECK-LABEL:  func @rsqrt_vector_5xf32
599// CHECK:          math.rsqrt
600// AVX2-LABEL:   func @rsqrt_vector_5xf32
601// AVX2:           math.rsqrt
602func.func @rsqrt_vector_5xf32(%arg0: vector<5xf32>) -> vector<5xf32> {
603  %0 = math.rsqrt %arg0 : vector<5xf32>
604  return %0 : vector<5xf32>
605}
606
607// One dimensional virtual vector expanded and unrolled into multiple AVX2-sized
608// vectors.
609//
610// CHECK-LABEL: func @rsqrt_vector_16xf32
611// CHECK:         math.rsqrt
612// AVX2-LABEL:  func @rsqrt_vector_16xf32(
613// AVX2-SAME:     %[[ARG:.*]]: vector<16xf32>
614// AVX2-SAME:   ) -> vector<16xf32>
615// AVX2:          %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x8xf32>
616// AVX2:          %[[EXPAND:.*]] = vector.shape_cast %[[ARG]] : vector<16xf32> to vector<2x8xf32>
617// AVX2:          %[[VEC0:.*]] = vector.extract %[[EXPAND]][0]
618// AVX2:          %[[RSQRT0:.*]] = x86vector.avx.rsqrt %[[VEC0]]
619// AVX2:          %[[VEC1:.*]] = vector.extract %[[EXPAND]][1]
620// AVX2:          %[[RSQRT1:.*]] = x86vector.avx.rsqrt %[[VEC1]]
621// AVX2:          %[[RESULT0:.*]] = vector.insert %[[RSQRT0]], %[[INIT]] [0]
622// AVX2:          %[[RESULT1:.*]] = vector.insert %[[RSQRT1]], %[[RESULT0]] [1]
623// AVX2:          %[[RSQRT:.*]] = vector.shape_cast %[[RESULT1]] : vector<2x8xf32> to vector<16xf32>
624func.func @rsqrt_vector_16xf32(%arg0: vector<16xf32>) -> vector<16xf32> {
625  %0 = math.rsqrt %arg0 : vector<16xf32>
626  return %0 : vector<16xf32>
627}
628
629// Two dimensional virtual vector unrolled into multiple AVX2-sized vectors.
630//
631// CHECK-LABEL: func @rsqrt_vector_2x8xf32
632// CHECK:         math.rsqrt
633// AVX2-LABEL:  func @rsqrt_vector_2x8xf32(
634// AVX2-SAME:     %[[ARG:.*]]: vector<2x8xf32>
635// AVX2-SAME:   ) -> vector<2x8xf32>
636// AVX2:          %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x8xf32>
637// AVX2-NOT:      vector.shape_cast
638// AVX2:          %[[VEC0:.*]] = vector.extract %[[ARG]][0]
639// AVX2:          %[[RSQRT0:.*]] = x86vector.avx.rsqrt %[[VEC0]]
640// AVX2:          %[[VEC1:.*]] = vector.extract %[[ARG]][1]
641// AVX2:          %[[RSQRT1:.*]] = x86vector.avx.rsqrt %[[VEC1]]
642// AVX2:          %[[RESULT0:.*]] = vector.insert %[[RSQRT0]], %[[INIT]] [0]
643// AVX2:          %[[RESULT1:.*]] = vector.insert %[[RSQRT1]], %[[RESULT0]] [1]
644// AVX2-NOT:      vector.shape_cast
645func.func @rsqrt_vector_2x8xf32(%arg0: vector<2x8xf32>) -> vector<2x8xf32> {
646  %0 = math.rsqrt %arg0 : vector<2x8xf32>
647  return %0 : vector<2x8xf32>
648}
649
650// Two dimensional virtual vector expanded and unrolled into multiple AVX2-sized
651// vectors.
652//
653// CHECK-LABEL: func @rsqrt_vector_2x16xf32
654// CHECK:         math.rsqrt
655// AVX2-LABEL:  func @rsqrt_vector_2x16xf32(
656// AVX2-SAME:     %[[ARG:.*]]: vector<2x16xf32>
657// AVX2-SAME:   ) -> vector<2x16xf32>
658// AVX2:          %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x2x8xf32>
659// AVX2:          %[[EXPAND:.*]] = vector.shape_cast %[[ARG]] : vector<2x16xf32> to vector<2x2x8xf32>
660// AVX2:          %[[VEC00:.*]] = vector.extract %[[EXPAND]][0, 0]
661// AVX2:          %[[RSQRT00:.*]] = x86vector.avx.rsqrt %[[VEC00]]
662// AVX2:          %[[VEC01:.*]] = vector.extract %[[EXPAND]][0, 1]
663// AVX2:          %[[RSQRT01:.*]] = x86vector.avx.rsqrt %[[VEC01]]
664// AVX2:          %[[VEC10:.*]] = vector.extract %[[EXPAND]][1, 0]
665// AVX2:          %[[RSQRT10:.*]] = x86vector.avx.rsqrt %[[VEC10]]
666// AVX2:          %[[VEC11:.*]] = vector.extract %[[EXPAND]][1, 1]
667// AVX2:          %[[RSQRT11:.*]] = x86vector.avx.rsqrt %[[VEC11]]
668// AVX2:          %[[RESULT0:.*]] = vector.insert %[[RSQRT00]], %[[INIT]] [0, 0]
669// AVX2:          %[[RESULT1:.*]] = vector.insert %[[RSQRT01]], %[[RESULT0]] [0, 1]
670// AVX2:          %[[RESULT2:.*]] = vector.insert %[[RSQRT10]], %[[RESULT1]] [1, 0]
671// AVX2:          %[[RESULT3:.*]] = vector.insert %[[RSQRT11]], %[[RESULT2]] [1, 1]
672// AVX2:          %[[RSQRT:.*]] = vector.shape_cast %[[RESULT3]] : vector<2x2x8xf32> to vector<2x16xf32>
673func.func @rsqrt_vector_2x16xf32(%arg0: vector<2x16xf32>) -> vector<2x16xf32> {
674  %0 = math.rsqrt %arg0 : vector<2x16xf32>
675  return %0 : vector<2x16xf32>
676}
677
678// CHECK-LABEL: @atan_scalar
679// CHECK-SAME:      %[[VAL_0:.*]]: f32) -> f32 {
680// CHECK-DAG:       %[[VAL_1:.*]] = arith.constant 1.000000e+00 : f32
681// CHECK-DAG:       %[[VAL_2:.*]] = arith.constant 6.600000e-01 : f32
682// CHECK-DAG:       %[[VAL_3:.*]] = arith.constant 2.41421366 : f32
683// CHECK-DAG:       %[[VAL_4:.*]] = arith.constant -0.875060856 : f32
684// CHECK-DAG:       %[[VAL_5:.*]] = arith.constant -16.1575375 : f32
685// CHECK-DAG:       %[[VAL_6:.*]] = arith.constant -75.0085601 : f32
686// CHECK-DAG:       %[[VAL_7:.*]] = arith.constant -122.886665 : f32
687// CHECK-DAG:       %[[VAL_8:.*]] = arith.constant -64.8502197 : f32
688// CHECK-DAG:       %[[VAL_9:.*]] = arith.constant 24.8584652 : f32
689// CHECK-DAG:       %[[VAL_10:.*]] = arith.constant 165.027008 : f32
690// CHECK-DAG:       %[[VAL_11:.*]] = arith.constant 432.881073 : f32
691// CHECK-DAG:       %[[VAL_12:.*]] = arith.constant 485.390411 : f32
692// CHECK-DAG:       %[[VAL_13:.*]] = arith.constant 194.550659 : f32
693// CHECK-DAG:       %[[VAL_14:.*]] = arith.constant 0.785398185 : f32
694// CHECK-DAG:       %[[VAL_15:.*]] = arith.constant 1.57079637 : f32
695// CHECK-DAG:       %[[VAL_16:.*]] = math.absf %[[VAL_0]] : f32
696// CHECK-DAG:       %[[VAL_17:.*]] = arith.cmpf ogt, %[[VAL_16]], %[[VAL_2]] : f32
697// CHECK-DAG:       %[[VAL_18:.*]] = arith.addf %[[VAL_16]], %[[VAL_1]] : f32
698// CHECK-DAG:       %[[VAL_19:.*]] = arith.subf %[[VAL_16]], %[[VAL_1]] : f32
699// CHECK-DAG:       %[[VAL_20:.*]] = arith.select %[[VAL_17]], %[[VAL_19]], %[[VAL_16]] : f32
700// CHECK-DAG:       %[[VAL_21:.*]] = arith.select %[[VAL_17]], %[[VAL_18]], %[[VAL_1]] : f32
701// CHECK-DAG:       %[[VAL_22:.*]] = arith.cmpf ogt, %[[VAL_16]], %[[VAL_3]] : f32
702// CHECK-DAG:       %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_1]], %[[VAL_20]] : f32
703// CHECK-DAG:       %[[VAL_24:.*]] = arith.select %[[VAL_22]], %[[VAL_16]], %[[VAL_21]] : f32
704// CHECK-DAG:       %[[VAL_25:.*]] = arith.divf %[[VAL_23]], %[[VAL_24]] : f32
705// CHECK-DAG:       %[[VAL_26:.*]] = arith.mulf %[[VAL_25]], %[[VAL_25]] : f32
706// CHECK-DAG:       %[[VAL_27:.*]] = math.fma %[[VAL_26]], %[[VAL_4]], %[[VAL_5]] : f32
707// CHECK-DAG:       %[[VAL_28:.*]] = math.fma %[[VAL_26]], %[[VAL_27]], %[[VAL_6]] : f32
708// CHECK-DAG:       %[[VAL_29:.*]] = math.fma %[[VAL_26]], %[[VAL_28]], %[[VAL_7]] : f32
709// CHECK-DAG:       %[[VAL_30:.*]] = math.fma %[[VAL_26]], %[[VAL_29]], %[[VAL_8]] : f32
710// CHECK-DAG:       %[[VAL_31:.*]] = arith.mulf %[[VAL_30]], %[[VAL_26]] : f32
711// CHECK-DAG:       %[[VAL_32:.*]] = math.fma %[[VAL_26]], %[[VAL_9]], %[[VAL_10]] : f32
712// CHECK-DAG:       %[[VAL_33:.*]] = math.fma %[[VAL_26]], %[[VAL_32]], %[[VAL_11]] : f32
713// CHECK-DAG:       %[[VAL_34:.*]] = math.fma %[[VAL_26]], %[[VAL_33]], %[[VAL_12]] : f32
714// CHECK-DAG:       %[[VAL_35:.*]] = math.fma %[[VAL_26]], %[[VAL_34]], %[[VAL_13]] : f32
715// CHECK-DAG:       %[[VAL_36:.*]] = arith.divf %[[VAL_31]], %[[VAL_35]] : f32
716// CHECK-DAG:       %[[VAL_37:.*]] = math.fma %[[VAL_36]], %[[VAL_25]], %[[VAL_25]] : f32
717// CHECK-DAG:       %[[VAL_38:.*]] = arith.addf %[[VAL_37]], %[[VAL_14]] : f32
718// CHECK-DAG:       %[[VAL_39:.*]] = arith.select %[[VAL_17]], %[[VAL_38]], %[[VAL_37]] : f32
719// CHECK-DAG:       %[[VAL_40:.*]] = arith.subf %[[VAL_15]], %[[VAL_37]] : f32
720// CHECK-DAG:       %[[VAL_41:.*]] = arith.select %[[VAL_22]], %[[VAL_40]], %[[VAL_39]] : f32
721// CHECK-DAG:       %[[VAL_42:.*]] = math.copysign %[[VAL_41]], %[[VAL_0]] : f32
722// CHECK:           return %[[VAL_42]] : f3
723func.func @atan_scalar(%arg0: f32) -> f32 {
724  %0 = math.atan %arg0 : f32
725  return %0 : f32
726}
727
728
729// CHECK-LABEL: @atan2_scalar
730// CHECK-SAME:      %[[VAL_0:.*]]: f16,
731// CHECK-SAME:      %[[VAL_1:.*]]: f16)
732// CHECK-DAG:       %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
733// CHECK-DAG:       %[[VAL_3:.*]] = arith.constant 6.600000e-01 : f32
734// CHECK-DAG:       %[[VAL_4:.*]] = arith.constant 2.41421366 : f32
735// CHECK-DAG:       %[[VAL_5:.*]] = arith.constant -0.875060856 : f32
736// CHECK-DAG:       %[[VAL_6:.*]] = arith.constant -16.1575375 : f32
737// CHECK-DAG:       %[[VAL_7:.*]] = arith.constant -75.0085601 : f32
738// CHECK-DAG:       %[[VAL_8:.*]] = arith.constant -122.886665 : f32
739// CHECK-DAG:       %[[VAL_9:.*]] = arith.constant -64.8502197 : f32
740// CHECK-DAG:       %[[VAL_10:.*]] = arith.constant 24.8584652 : f32
741// CHECK-DAG:       %[[VAL_11:.*]] = arith.constant 165.027008 : f32
742// CHECK-DAG:       %[[VAL_12:.*]] = arith.constant 432.881073 : f32
743// CHECK-DAG:       %[[VAL_13:.*]] = arith.constant 485.390411 : f32
744// CHECK-DAG:       %[[VAL_14:.*]] = arith.constant 194.550659 : f32
745// CHECK-DAG:       %[[VAL_15:.*]] = arith.constant 0.785398185 : f32
746// CHECK-DAG:       %[[VAL_16:.*]] = arith.constant 1.57079637 : f32
747// CHECK-DAG:       %[[VAL_17:.*]] = arith.constant 0.000000e+00 : f32
748// CHECK-DAG:       %[[VAL_18:.*]] = arith.constant 3.14159274 : f32
749// CHECK-DAG:       %[[VAL_19:.*]] = arith.constant -1.57079637 : f32
750// CHECK-DAG:       %[[VAL_20:.*]] = arith.constant 0x7FC00000 : f32
751// CHECK-DAG:       %[[VAL_21:.*]] = arith.extf %[[VAL_0]] : f16 to f32
752// CHECK-DAG:       %[[VAL_22:.*]] = arith.extf %[[VAL_1]] : f16 to f32
753// CHECK-DAG:       %[[VAL_23:.*]] = arith.divf %[[VAL_21]], %[[VAL_22]] : f32
754// CHECK-DAG:       %[[VAL_24:.*]] = math.absf %[[VAL_23]] : f32
755// CHECK-DAG:       %[[VAL_25:.*]] = arith.cmpf ogt, %[[VAL_24]], %[[VAL_3]] : f32
756// CHECK-DAG:       %[[VAL_26:.*]] = arith.addf %[[VAL_24]], %[[VAL_2]] : f32
757// CHECK-DAG:       %[[VAL_27:.*]] = arith.subf %[[VAL_24]], %[[VAL_2]] : f32
758// CHECK-DAG:       %[[VAL_28:.*]] = arith.select %[[VAL_25]], %[[VAL_27]], %[[VAL_24]] : f32
759// CHECK-DAG:       %[[VAL_29:.*]] = arith.select %[[VAL_25]], %[[VAL_26]], %[[VAL_2]] : f32
760// CHECK-DAG:       %[[VAL_30:.*]] = arith.cmpf ogt, %[[VAL_24]], %[[VAL_4]] : f32
761// CHECK-DAG:       %[[VAL_31:.*]] = arith.select %[[VAL_30]], %[[VAL_2]], %[[VAL_28]] : f32
762// CHECK-DAG:       %[[VAL_32:.*]] = arith.select %[[VAL_30]], %[[VAL_24]], %[[VAL_29]] : f32
763// CHECK-DAG:       %[[VAL_33:.*]] = arith.divf %[[VAL_31]], %[[VAL_32]] : f32
764// CHECK-DAG:       %[[VAL_34:.*]] = arith.mulf %[[VAL_33]], %[[VAL_33]] : f32
765// CHECK-DAG:       %[[VAL_35:.*]] = math.fma %[[VAL_34]], %[[VAL_5]], %[[VAL_6]] : f32
766// CHECK-DAG:       %[[VAL_36:.*]] = math.fma %[[VAL_34]], %[[VAL_35]], %[[VAL_7]] : f32
767// CHECK-DAG:       %[[VAL_37:.*]] = math.fma %[[VAL_34]], %[[VAL_36]], %[[VAL_8]] : f32
768// CHECK-DAG:       %[[VAL_38:.*]] = math.fma %[[VAL_34]], %[[VAL_37]], %[[VAL_9]] : f32
769// CHECK-DAG:       %[[VAL_39:.*]] = arith.mulf %[[VAL_38]], %[[VAL_34]] : f32
770// CHECK-DAG:       %[[VAL_40:.*]] = math.fma %[[VAL_34]], %[[VAL_10]], %[[VAL_11]] : f32
771// CHECK-DAG:       %[[VAL_41:.*]] = math.fma %[[VAL_34]], %[[VAL_40]], %[[VAL_12]] : f32
772// CHECK-DAG:       %[[VAL_42:.*]] = math.fma %[[VAL_34]], %[[VAL_41]], %[[VAL_13]] : f32
773// CHECK-DAG:       %[[VAL_43:.*]] = math.fma %[[VAL_34]], %[[VAL_42]], %[[VAL_14]] : f32
774// CHECK-DAG:       %[[VAL_44:.*]] = arith.divf %[[VAL_39]], %[[VAL_43]] : f32
775// CHECK-DAG:       %[[VAL_45:.*]] = math.fma %[[VAL_44]], %[[VAL_33]], %[[VAL_33]] : f32
776// CHECK-DAG:       %[[VAL_46:.*]] = arith.addf %[[VAL_45]], %[[VAL_15]] : f32
777// CHECK-DAG:       %[[VAL_47:.*]] = arith.select %[[VAL_25]], %[[VAL_46]], %[[VAL_45]] : f32
778// CHECK-DAG:       %[[VAL_48:.*]] = arith.subf %[[VAL_16]], %[[VAL_45]] : f32
779// CHECK-DAG:       %[[VAL_49:.*]] = arith.select %[[VAL_30]], %[[VAL_48]], %[[VAL_47]] : f32
780// CHECK-DAG:       %[[VAL_50:.*]] = math.copysign %[[VAL_49]], %[[VAL_23]] : f32
781// CHECK-DAG:       %[[VAL_51:.*]] = arith.addf %[[VAL_50]], %[[VAL_18]] : f32
782// CHECK-DAG:       %[[VAL_52:.*]] = arith.subf %[[VAL_50]], %[[VAL_18]] : f32
783// CHECK-DAG:       %[[VAL_53:.*]] = arith.cmpf ogt, %[[VAL_50]], %[[VAL_17]] : f32
784// CHECK-DAG:       %[[VAL_54:.*]] = arith.select %[[VAL_53]], %[[VAL_52]], %[[VAL_51]] : f32
785// CHECK-DAG:       %[[VAL_55:.*]] = arith.cmpf ogt, %[[VAL_22]], %[[VAL_17]] : f32
786// CHECK-DAG:       %[[VAL_56:.*]] = arith.select %[[VAL_55]], %[[VAL_50]], %[[VAL_54]] : f32
787// CHECK-DAG:       %[[VAL_57:.*]] = arith.cmpf oeq, %[[VAL_22]], %[[VAL_17]] : f32
788// CHECK-DAG:       %[[VAL_58:.*]] = arith.cmpf ogt, %[[VAL_21]], %[[VAL_17]] : f32
789// CHECK-DAG:       %[[VAL_59:.*]] = arith.andi %[[VAL_57]], %[[VAL_58]] : i1
790// CHECK-DAG:       %[[VAL_60:.*]] = arith.select %[[VAL_59]], %[[VAL_16]], %[[VAL_56]] : f32
791// CHECK-DAG:       %[[VAL_61:.*]] = arith.cmpf olt, %[[VAL_21]], %[[VAL_17]] : f32
792// CHECK-DAG:       %[[VAL_62:.*]] = arith.andi %[[VAL_57]], %[[VAL_61]] : i1
793// CHECK-DAG:       %[[VAL_63:.*]] = arith.select %[[VAL_62]], %[[VAL_19]], %[[VAL_60]] : f32
794// CHECK-DAG:       %[[VAL_64:.*]] = arith.cmpf oeq, %[[VAL_21]], %[[VAL_17]] : f32
795// CHECK-DAG:       %[[VAL_65:.*]] = arith.andi %[[VAL_57]], %[[VAL_64]] : i1
796// CHECK-DAG:       %[[VAL_66:.*]] = arith.select %[[VAL_65]], %[[VAL_20]], %[[VAL_63]] : f32
797// CHECK-DAG:       %[[VAL_67:.*]] = arith.truncf %[[VAL_66]] : f32 to f16
798// CHECK:           return %[[VAL_67]] : f1
799func.func @atan2_scalar(%arg0: f16, %arg1: f16) -> f16 {
800  %0 = math.atan2 %arg0, %arg1 : f16
801  return %0 : f16
802}
803
804// CHECK-LABEL: @cbrt_vector
805// CHECK-SAME: %[[ARG0:.+]]: vector<4xf32>
806
807// CHECK: %[[TWO_INT:.+]] = arith.constant dense<2>
808// CHECK: %[[FOUR_INT:.+]] = arith.constant dense<4>
809// CHECK: %[[EIGHT_INT:.+]] = arith.constant dense<8>
810// CHECK: %[[MAGIC:.+]] = arith.constant dense<709965728>
811// CHECK: %[[THIRD_FP:.+]] = arith.constant dense<0.333333343> : vector<4xf32>
812// CHECK: %[[TWO_FP:.+]] = arith.constant dense<2.000000e+00> : vector<4xf32>
813// CHECK: %[[ZERO_FP:.+]] = arith.constant dense<0.000000e+00> : vector<4xf32>
814
815// CHECK: %[[ABS:.+]] = math.absf %[[ARG0]] : vector<4xf32>
816
817// Perform the initial approximation:
818// CHECK: %[[CAST:.+]] = arith.bitcast %[[ABS]] : vector<4xf32> to vector<4xi32>
819// CHECK: %[[SH_TWO:.+]] = arith.shrsi %[[CAST]], %[[TWO_INT]]
820// CHECK: %[[SH_FOUR:.+]] = arith.shrsi %[[CAST]], %[[FOUR_INT]]
821// CHECK: %[[APPROX0:.+]] = arith.addi %[[SH_TWO]], %[[SH_FOUR]]
822// CHECK: %[[SH_FOUR:.+]] = arith.shrsi %[[APPROX0]], %[[FOUR_INT]]
823// CHECK: %[[APPROX1:.+]] = arith.addi %[[APPROX0]], %[[SH_FOUR]]
824// CHECK: %[[SH_EIGHT:.+]] = arith.shrsi %[[APPROX1]], %[[EIGHT_INT]]
825// CHECK: %[[APPROX2:.+]] = arith.addi %[[APPROX1]], %[[SH_EIGHT]]
826// CHECK: %[[FIX:.+]] = arith.addi %[[APPROX2]], %[[MAGIC]]
827// CHECK: %[[BCAST:.+]] = arith.bitcast %[[FIX]]
828
829// First Newton Step:
830// CHECK: %[[SQR:.+]] = arith.mulf %[[BCAST]], %[[BCAST]]
831// CHECK: %[[DOUBLE:.+]] = arith.mulf %[[BCAST]], %[[TWO_FP]]
832// CHECK: %[[DIV:.+]] = arith.divf %[[ABS]], %[[SQR]]
833// CHECK: %[[ADD:.+]] = arith.addf %[[DOUBLE]], %[[DIV]]
834// CHECK: %[[APPROX3:.+]] = arith.mulf %[[ADD]], %[[THIRD_FP]]
835
836// Second Newton Step:
837// CHECK: %[[SQR:.+]] = arith.mulf %[[APPROX3]], %[[APPROX3]]
838// CHECK: %[[DOUBLE:.+]] = arith.mulf %[[APPROX3]], %[[TWO_FP]]
839// CHECK: %[[DIV:.+]] = arith.divf %[[ABS]], %[[SQR]]
840// CHECK: %[[ADD:.+]] = arith.addf %[[DOUBLE]], %[[DIV]]
841// CHECK: %[[APPROX4:.+]] = arith.mulf %[[ADD]], %[[THIRD_FP]]
842
843// Check for zero special case and copy the sign:
844// CHECK: %[[CMP:.+]] = arith.cmpf oeq, %[[ABS]], %[[ZERO_FP]]
845// CHECK: %[[SEL:.+]] = arith.select %[[CMP]], %[[ZERO_FP]], %[[APPROX4]]
846// CHECK: %[[SIGN:.+]] = math.copysign %[[SEL]], %[[ARG0]]
847// CHECK: return %[[SIGN]]
848
849func.func @cbrt_vector(%arg0: vector<4xf32>) -> vector<4xf32> {
850  %0 = "math.cbrt"(%arg0) : (vector<4xf32>) -> vector<4xf32>
851  func.return %0 : vector<4xf32>
852}
853
854
855// CHECK-LABEL: @math_f16
856func.func @math_f16(%arg0 : vector<4xf16>) -> vector<4xf16> {
857
858  // CHECK-NOT: math.atan
859  %0 = "math.atan"(%arg0) : (vector<4xf16>) -> vector<4xf16>
860
861  // CHECK-NOT: math.atan2
862  %1 = "math.atan2"(%0, %arg0) : (vector<4xf16>, vector<4xf16>) -> vector<4xf16>
863
864  // CHECK-NOT: math.tanh
865  %2 = "math.tanh"(%1) : (vector<4xf16>) -> vector<4xf16>
866
867  // CHECK-NOT: math.log
868  %3 = "math.log"(%2) : (vector<4xf16>) -> vector<4xf16>
869
870  // CHECK-NOT: math.log2
871  %4 = "math.log2"(%3) : (vector<4xf16>) -> vector<4xf16>
872
873  // CHECK-NOT: math.log1p
874  %5 = "math.log1p"(%4) : (vector<4xf16>) -> vector<4xf16>
875
876  // CHECK-NOT: math.erf
877  %6 = "math.erf"(%5) : (vector<4xf16>) -> vector<4xf16>
878
879  // CHECK-NOT: math.exp
880  %7 = "math.exp"(%6) : (vector<4xf16>) -> vector<4xf16>
881
882  // CHECK-NOT: math.expm1
883  %8 = "math.expm1"(%7) : (vector<4xf16>) -> vector<4xf16>
884
885  // CHECK-NOT: math.cbrt
886  %9 = "math.cbrt"(%8) : (vector<4xf16>) -> vector<4xf16>
887
888  // CHECK-NOT: math.sin
889  %10 = "math.sin"(%9) : (vector<4xf16>) -> vector<4xf16>
890
891  // CHECK-NOT: math.cos
892  %11 = "math.cos"(%10) : (vector<4xf16>) -> vector<4xf16>
893
894  return %11 : vector<4xf16>
895}
896
897// CHECK-LABEL: @math_zero_rank
898func.func @math_zero_rank(%arg0 : vector<f16>) -> vector<f16> {
899
900  // CHECK-NOT: math.atan
901  %0 = "math.atan"(%arg0) : (vector<f16>) -> vector<f16>
902
903  // CHECK-NOT: math.atan2
904  %1 = "math.atan2"(%0, %arg0) : (vector<f16>, vector<f16>) -> vector<f16>
905
906  // CHECK-NOT: math.tanh
907  %2 = "math.tanh"(%1) : (vector<f16>) -> vector<f16>
908
909  // CHECK-NOT: math.log
910  %3 = "math.log"(%2) : (vector<f16>) -> vector<f16>
911
912  // CHECK-NOT: math.log2
913  %4 = "math.log2"(%3) : (vector<f16>) -> vector<f16>
914
915  // CHECK-NOT: math.log1p
916  %5 = "math.log1p"(%4) : (vector<f16>) -> vector<f16>
917
918  // CHECK-NOT: math.erf
919  %6 = "math.erf"(%5) : (vector<f16>) -> vector<f16>
920
921  // CHECK-NOT: math.exp
922  %7 = "math.exp"(%6) : (vector<f16>) -> vector<f16>
923
924  // CHECK-NOT: math.expm1
925  %8 = "math.expm1"(%7) : (vector<f16>) -> vector<f16>
926
927  // CHECK-NOT: math.cbrt
928  %9 = "math.cbrt"(%8) : (vector<f16>) -> vector<f16>
929
930  // CHECK-NOT: math.sin
931  %10 = "math.sin"(%9) : (vector<f16>) -> vector<f16>
932
933  // CHECK-NOT: math.cos
934  %11 = "math.cos"(%10) : (vector<f16>) -> vector<f16>
935
936  return %11 : vector<f16>
937}
938
939// AVX2-LABEL: @rsqrt_f16
940func.func @rsqrt_f16(%arg0 : vector<2x8xf16>) -> vector<2x8xf16> {
941  // AVX2-NOT: math.rsqrt
942  %0 = "math.rsqrt"(%arg0) : (vector<2x8xf16>) -> vector<2x8xf16>
943  return %0 : vector<2x8xf16>
944}
945