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 @exp_scalar(
98// CHECK-SAME:                     %[[VAL_0:.*]]: f32) -> f32 {
99// CHECK-DAG:           %[[VAL_1:.*]] = arith.constant 0.693147182 : f32
100// CHECK-DAG:           %[[VAL_2:.*]] = arith.constant 1.44269502 : f32
101// CHECK-DAG:           %[[VAL_3:.*]] = arith.constant 1.000000e+00 : f32
102// CHECK-DAG:           %[[VAL_4:.*]] = arith.constant 0.499705136 : f32
103// CHECK-DAG:           %[[VAL_5:.*]] = arith.constant 0.168738902 : f32
104// CHECK-DAG:           %[[VAL_6:.*]] = arith.constant 0.0366896503 : f32
105// CHECK-DAG:           %[[VAL_7:.*]] = arith.constant 1.314350e-02 : f32
106// CHECK-DAG:           %[[VAL_8:.*]] = arith.constant 23 : i32
107// CHECK-DAG:           %[[VAL_9:.*]] = arith.constant 0.000000e+00 : f32
108// CHECK-DAG:           %[[VAL_10:.*]] = arith.constant 0x7F800000 : f32
109// CHECK-DAG:           %[[VAL_11:.*]] = arith.constant 0xFF800000 : f32
110// CHECK-DAG:           %[[VAL_12:.*]] = arith.constant 1.17549435E-38 : f32
111// CHECK-DAG:           %[[VAL_13:.*]] = arith.constant 127 : i32
112// CHECK-DAG:           %[[VAL_14:.*]] = arith.constant -127 : i32
113// CHECK:           %[[IS_NAN:.*]] = arith.cmpf uno, %[[VAL_0]], %[[VAL_0]] : f32
114// CHECK:           %[[VAL_15:.*]] = arith.mulf %[[VAL_0]], %[[VAL_2]] : f32
115// CHECK:           %[[VAL_16:.*]] = math.floor %[[VAL_15]] : f32
116// CHECK:           %[[VAL_17:.*]] = arith.mulf %[[VAL_16]], %[[VAL_1]] : f32
117// CHECK:           %[[VAL_18:.*]] = arith.subf %[[VAL_0]], %[[VAL_17]] : f32
118// CHECK:           %[[VAL_19:.*]] = arith.mulf %[[VAL_18]], %[[VAL_18]] : f32
119// CHECK:           %[[VAL_20:.*]] = arith.mulf %[[VAL_19]], %[[VAL_19]] : f32
120// CHECK:           %[[VAL_21:.*]] = math.fma %[[VAL_3]], %[[VAL_18]], %[[VAL_3]] : f32
121// CHECK:           %[[VAL_22:.*]] = math.fma %[[VAL_5]], %[[VAL_18]], %[[VAL_4]] : f32
122// CHECK:           %[[VAL_23:.*]] = math.fma %[[VAL_7]], %[[VAL_18]], %[[VAL_6]] : f32
123// CHECK:           %[[VAL_24:.*]] = math.fma %[[VAL_22]], %[[VAL_19]], %[[VAL_21]] : f32
124// CHECK:           %[[VAL_25:.*]] = math.fma %[[VAL_23]], %[[VAL_20]], %[[VAL_24]] : f32
125// CHECK:           %[[VAL_26:.*]] = arith.fptosi %[[VAL_16]] : f32 to i32
126// CHECK:           %[[VAL_27:.*]] = arith.addi %[[VAL_26]], %[[VAL_13]] : i32
127// CHECK:           %[[VAL_28:.*]] = arith.shli %[[VAL_27]], %[[VAL_8]] : i32
128// CHECK:           %[[VAL_29:.*]] = arith.bitcast %[[VAL_28]] : i32 to f32
129// CHECK:           %[[VAL_30:.*]] = arith.mulf %[[VAL_25]], %[[VAL_29]] : f32
130// CHECK:           %[[VAL_31:.*]] = arith.cmpi sle, %[[VAL_26]], %[[VAL_13]] : i32
131// CHECK:           %[[VAL_32:.*]] = arith.cmpi sge, %[[VAL_26]], %[[VAL_14]] : i32
132// CHECK:           %[[VAL_33:.*]] = arith.cmpf oeq, %[[VAL_0]], %[[VAL_11]] : f32
133// CHECK:           %[[VAL_34:.*]] = arith.cmpf oeq, %[[VAL_0]], %[[VAL_10]] : f32
134// CHECK:           %[[VAL_35:.*]] = arith.cmpf ogt, %[[VAL_0]], %[[VAL_9]] : f32
135// CHECK:           %[[VAL_36:.*]] = arith.andi %[[VAL_31]], %[[VAL_32]] : i1
136// CHECK:           %[[VAL_37:.*]] = arith.select %[[VAL_35]], %[[VAL_10]], %[[VAL_12]] : f32
137// CHECK:           %[[VAL_38:.*]] = arith.select %[[VAL_36]], %[[VAL_30]], %[[VAL_37]] : f32
138// CHECK:           %[[VAL_39:.*]] = arith.select %[[VAL_34]], %[[VAL_10]], %[[VAL_38]] : f32
139// CHECK:           %[[VAL_40:.*]] = arith.select %[[VAL_33]], %[[VAL_9]], %[[VAL_39]] : f32
140// CHECK:           %[[VAL_41:.*]] = arith.select %[[IS_NAN]], %[[VAL_0]], %[[VAL_40]] : f32
141// CHECK:           return %[[VAL_41]] : f32
142func.func @exp_scalar(%arg0: f32) -> f32 {
143  %0 = math.exp %arg0 : f32
144  return %0 : f32
145}
146
147// CHECK-LABEL:   func @exp_vector(
148// CHECK-SAME:                     %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
149// CHECK:           %[[VAL_1:.*]] = arith.constant dense<0.693147182> : vector<8xf32>
150// CHECK-NOT:       exp
151// CHECK-COUNT-4:   select
152// CHECK:           %[[VAL_40:.*]] = arith.select
153// CHECK:           return %[[VAL_40]] : vector<8xf32>
154func.func @exp_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
155  %0 = math.exp %arg0 : vector<8xf32>
156  return %0 : vector<8xf32>
157}
158
159// CHECK-LABEL:   func @expm1_scalar(
160// CHECK-SAME:                       %[[X:.*]]: f32) -> f32 {
161// CHECK-DAG:           %[[CST_MINUSONE:.*]] = arith.constant -1.000000e+00 : f32
162// CHECK-DAG:           %[[CST_LOG2E:.*]] = arith.constant 1.44269502 : f32
163// CHECK-DAG:           %[[CST_ONE:.*]] = arith.constant 1.000000e+00 : f32
164// CHECK:           %[[BEGIN_EXP_X:.*]] = arith.mulf %[[X]], %[[CST_LOG2E]] : f32
165// CHECK-NOT:       exp
166// CHECK-COUNT-4:   select
167// CHECK:           %[[EXP_X:.*]] = arith.select
168// CHECK:           %[[IS_ONE_OR_NAN:.*]] = arith.cmpf ueq, %[[EXP_X]], %[[CST_ONE]] : f32
169// CHECK:           %[[VAL_59:.*]] = arith.subf %[[EXP_X]], %[[CST_ONE]] : f32
170// CHECK:           %[[VAL_60:.*]] = arith.cmpf oeq, %[[VAL_59]], %[[CST_MINUSONE]] : f32
171// CHECK-NOT:       log
172// CHECK-COUNT-5:   select
173// CHECK:           %[[LOG_U:.*]] = arith.select
174// CHECK:           %[[VAL_104:.*]] = arith.cmpf oeq, %[[LOG_U]], %[[EXP_X]] : f32
175// CHECK:           %[[VAL_105:.*]] = arith.divf %[[X]], %[[LOG_U]] : f32
176// CHECK:           %[[VAL_106:.*]] = arith.mulf %[[VAL_59]], %[[VAL_105]] : f32
177// CHECK:           %[[VAL_107:.*]] = arith.select %[[VAL_104]], %[[EXP_X]], %[[VAL_106]] : f32
178// CHECK:           %[[VAL_108:.*]] = arith.select %[[VAL_60]], %[[CST_MINUSONE]], %[[VAL_107]] : f32
179// CHECK:           %[[VAL_109:.*]] = arith.select %[[IS_ONE_OR_NAN]], %[[X]], %[[VAL_108]] : f32
180// CHECK:           return %[[VAL_109]] : f32
181// CHECK:         }
182func.func @expm1_scalar(%arg0: f32) -> f32 {
183  %0 = math.expm1 %arg0 : f32
184  return %0 : f32
185}
186
187// CHECK-LABEL:   func @expm1_vector(
188// CHECK-SAME:                       %[[VAL_0:.*]]: vector<8x8xf32>) -> vector<8x8xf32> {
189// CHECK:           %[[VAL_1:.*]] = arith.constant dense<-1.000000e+00> : vector<8x8xf32>
190// CHECK-NOT:       exp
191// CHECK-COUNT-5:   select
192// CHECK-NOT:       log
193// CHECK-COUNT-5:   select
194// CHECK-NOT:       expm1
195// CHECK-COUNT-3:   select
196// CHECK:           %[[VAL_115:.*]] = arith.select
197// CHECK:           return %[[VAL_115]] : vector<8x8xf32>
198// CHECK:         }
199func.func @expm1_vector(%arg0: vector<8x8xf32>) -> vector<8x8xf32> {
200  %0 = math.expm1 %arg0 : vector<8x8xf32>
201  return %0 : vector<8x8xf32>
202}
203
204// CHECK-LABEL:   func @log_scalar(
205// CHECK-SAME:                             %[[X:.*]]: f32) -> f32 {
206// CHECK:           %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32
207// CHECK:           %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32
208// CHECK:           %[[VAL_3:.*]] = arith.constant -5.000000e-01 : f32
209// CHECK:           %[[VAL_4:.*]] = arith.constant 1.17549435E-38 : f32
210// CHECK:           %[[VAL_5:.*]] = arith.constant 0xFF800000 : f32
211// CHECK:           %[[VAL_6:.*]] = arith.constant 0x7F800000 : f32
212// CHECK:           %[[VAL_7:.*]] = arith.constant 0x7FC00000 : f32
213// CHECK:           %[[VAL_8:.*]] = arith.constant 0.707106769 : f32
214// CHECK:           %[[VAL_9:.*]] = arith.constant 0.0703768358 : f32
215// CHECK:           %[[VAL_10:.*]] = arith.constant -0.115146101 : f32
216// CHECK:           %[[VAL_11:.*]] = arith.constant 0.116769984 : f32
217// CHECK:           %[[VAL_12:.*]] = arith.constant -0.12420141 : f32
218// CHECK:           %[[VAL_13:.*]] = arith.constant 0.142493233 : f32
219// CHECK:           %[[VAL_14:.*]] = arith.constant -0.166680574 : f32
220// CHECK:           %[[VAL_15:.*]] = arith.constant 0.200007141 : f32
221// CHECK:           %[[VAL_16:.*]] = arith.constant -0.24999994 : f32
222// CHECK:           %[[VAL_17:.*]] = arith.constant 0.333333313 : f32
223// CHECK:           %[[VAL_18:.*]] = arith.constant 1.260000e+02 : f32
224// CHECK:           %[[VAL_19:.*]] = arith.constant -2139095041 : i32
225// CHECK:           %[[VAL_20:.*]] = arith.constant 1056964608 : i32
226// CHECK:           %[[VAL_21:.*]] = arith.constant 23 : i32
227// CHECK:           %[[VAL_22:.*]] = arith.constant 0.693147182 : f32
228// CHECK:           %[[VAL_23:.*]] = arith.cmpf ugt, %[[X]], %[[VAL_4]] : f32
229// CHECK:           %[[VAL_24:.*]] = arith.select %[[VAL_23]], %[[X]], %[[VAL_4]] : f32
230// CHECK-NOT:       frexp
231// CHECK:           %[[VAL_25:.*]] = arith.bitcast %[[VAL_24]] : f32 to i32
232// CHECK:           %[[VAL_26:.*]] = arith.andi %[[VAL_25]], %[[VAL_19]] : i32
233// CHECK:           %[[VAL_27:.*]] = arith.ori %[[VAL_26]], %[[VAL_20]] : i32
234// CHECK:           %[[VAL_28:.*]] = arith.bitcast %[[VAL_27]] : i32 to f32
235// CHECK:           %[[VAL_29:.*]] = arith.bitcast %[[VAL_24]] : f32 to i32
236// CHECK:           %[[VAL_30:.*]] = arith.shrui %[[VAL_29]], %[[VAL_21]] : i32
237// CHECK:           %[[VAL_31:.*]] = arith.sitofp %[[VAL_30]] : i32 to f32
238// CHECK:           %[[VAL_32:.*]] = arith.subf %[[VAL_31]], %[[VAL_18]] : f32
239// CHECK:           %[[VAL_33:.*]] = arith.cmpf olt, %[[VAL_28]], %[[VAL_8]] : f32
240// CHECK:           %[[VAL_34:.*]] = arith.select %[[VAL_33]], %[[VAL_28]], %[[VAL_1]] : f32
241// CHECK:           %[[VAL_35:.*]] = arith.subf %[[VAL_28]], %[[VAL_2]] : f32
242// CHECK:           %[[VAL_36:.*]] = arith.select %[[VAL_33]], %[[VAL_2]], %[[VAL_1]] : f32
243// CHECK:           %[[VAL_37:.*]] = arith.subf %[[VAL_32]], %[[VAL_36]] : f32
244// CHECK:           %[[VAL_38:.*]] = arith.addf %[[VAL_35]], %[[VAL_34]] : f32
245// CHECK:           %[[VAL_39:.*]] = arith.mulf %[[VAL_38]], %[[VAL_38]] : f32
246// CHECK:           %[[VAL_40:.*]] = arith.mulf %[[VAL_39]], %[[VAL_38]] : f32
247// CHECK:           %[[VAL_41:.*]] = math.fma %[[VAL_9]], %[[VAL_38]], %[[VAL_10]] : f32
248// CHECK:           %[[VAL_42:.*]] = math.fma %[[VAL_12]], %[[VAL_38]], %[[VAL_13]] : f32
249// CHECK:           %[[VAL_43:.*]] = math.fma %[[VAL_15]], %[[VAL_38]], %[[VAL_16]] : f32
250// CHECK:           %[[VAL_44:.*]] = math.fma %[[VAL_41]], %[[VAL_38]], %[[VAL_11]] : f32
251// CHECK:           %[[VAL_45:.*]] = math.fma %[[VAL_42]], %[[VAL_38]], %[[VAL_14]] : f32
252// CHECK:           %[[VAL_46:.*]] = math.fma %[[VAL_43]], %[[VAL_38]], %[[VAL_17]] : f32
253// CHECK:           %[[VAL_47:.*]] = math.fma %[[VAL_44]], %[[VAL_40]], %[[VAL_45]] : f32
254// CHECK:           %[[VAL_48:.*]] = math.fma %[[VAL_47]], %[[VAL_40]], %[[VAL_46]] : f32
255// CHECK:           %[[VAL_49:.*]] = arith.mulf %[[VAL_48]], %[[VAL_40]] : f32
256// CHECK:           %[[VAL_50:.*]] = math.fma %[[VAL_3]], %[[VAL_39]], %[[VAL_49]] : f32
257// CHECK:           %[[VAL_51:.*]] = arith.addf %[[VAL_38]], %[[VAL_50]] : f32
258// CHECK:           %[[VAL_52:.*]] = math.fma %[[VAL_37]], %[[VAL_22]], %[[VAL_51]] : f32
259// CHECK:           %[[VAL_53:.*]] = arith.cmpf ult, %[[X]], %[[VAL_1]] : f32
260// CHECK:           %[[VAL_54:.*]] = arith.cmpf oeq, %[[X]], %[[VAL_1]] : f32
261// CHECK:           %[[VAL_55:.*]] = arith.cmpf oeq, %[[X]], %[[VAL_6]] : f32
262// CHECK:           %[[VAL_56:.*]] = arith.select %[[VAL_55]], %[[VAL_6]], %[[VAL_52]] : f32
263// CHECK:           %[[VAL_57:.*]] = arith.select %[[VAL_53]], %[[VAL_7]], %[[VAL_56]] : f32
264// CHECK:           %[[VAL_58:.*]] = arith.select %[[VAL_54]], %[[VAL_5]], %[[VAL_57]] : f32
265// CHECK:           return %[[VAL_58]] : f32
266// CHECK:         }
267func.func @log_scalar(%arg0: f32) -> f32 {
268  %0 = math.log %arg0 : f32
269  return %0 : f32
270}
271
272// CHECK-LABEL:   func @log_vector(
273// CHECK-SAME:                     %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
274// CHECK:           %[[CST_LN2:.*]] = arith.constant dense<0.693147182> : vector<8xf32>
275// CHECK-COUNT-5:   select
276// CHECK:           %[[VAL_71:.*]] = arith.select
277// CHECK:           return %[[VAL_71]] : vector<8xf32>
278// CHECK:         }
279func.func @log_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
280  %0 = math.log %arg0 : vector<8xf32>
281  return %0 : vector<8xf32>
282}
283
284// CHECK-LABEL:   func @log2_scalar(
285// CHECK-SAME:                      %[[VAL_0:.*]]: f32) -> f32 {
286// CHECK:           %[[CST_LOG2E:.*]] = arith.constant 1.44269502 : f32
287// CHECK-COUNT-5:   select
288// CHECK:           %[[VAL_65:.*]] = arith.select
289// CHECK:           return %[[VAL_65]] : f32
290// CHECK:         }
291func.func @log2_scalar(%arg0: f32) -> f32 {
292  %0 = math.log2 %arg0 : f32
293  return %0 : f32
294}
295
296// CHECK-LABEL:   func @log2_vector(
297// CHECK-SAME:                      %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
298// CHECK:           %[[CST_LOG2E:.*]] = arith.constant dense<1.44269502> : vector<8xf32>
299// CHECK-COUNT-5:   select
300// CHECK:           %[[VAL_71:.*]] = arith.select
301// CHECK:           return %[[VAL_71]] : vector<8xf32>
302// CHECK:         }
303func.func @log2_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
304  %0 = math.log2 %arg0 : vector<8xf32>
305  return %0 : vector<8xf32>
306}
307
308// CHECK-LABEL:   func @log1p_scalar(
309// CHECK-SAME:                       %[[X:.*]]: f32) -> f32 {
310// CHECK:           %[[CST_ONE:.*]] = arith.constant 1.000000e+00 : f32
311// CHECK:           %[[U:.*]] = arith.addf %[[X]], %[[CST_ONE]] : f32
312// CHECK:           %[[U_SMALL:.*]] = arith.cmpf oeq, %[[U]], %[[CST_ONE]] : f32
313// CHECK-NOT:       log
314// CHECK-COUNT-5:   select
315// CHECK:           %[[LOG_U:.*]] = arith.select
316// CHECK:           %[[U_INF:.*]] = arith.cmpf oeq, %[[U]], %[[LOG_U]] : f32
317// CHECK:           %[[VAL_69:.*]] = arith.subf %[[U]], %[[CST_ONE]] : f32
318// CHECK:           %[[VAL_70:.*]] = arith.divf %[[LOG_U]], %[[VAL_69]] : f32
319// CHECK:           %[[LOG_LARGE:.*]] = arith.mulf %[[X]], %[[VAL_70]] : f32
320// CHECK:           %[[VAL_72:.*]] = arith.ori %[[U_SMALL]], %[[U_INF]]  : i1
321// CHECK:           %[[APPROX:.*]] = arith.select %[[VAL_72]], %[[X]], %[[LOG_LARGE]] : f32
322// CHECK:           return %[[APPROX]] : f32
323// CHECK:         }
324func.func @log1p_scalar(%arg0: f32) -> f32 {
325  %0 = math.log1p %arg0 : f32
326  return %0 : f32
327}
328
329// CHECK-LABEL:   func @log1p_vector(
330// CHECK-SAME:                       %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
331// CHECK:           %[[CST_ONE:.*]] = arith.constant dense<1.000000e+00> : vector<8xf32>
332// CHECK-COUNT-6:   select
333// CHECK:           %[[VAL_79:.*]] = arith.select
334// CHECK:           return %[[VAL_79]] : vector<8xf32>
335// CHECK:         }
336func.func @log1p_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
337  %0 = math.log1p %arg0 : vector<8xf32>
338  return %0 : vector<8xf32>
339}
340
341
342// CHECK-LABEL:   func @tanh_scalar(
343// CHECK-SAME:                      %[[VAL_0:.*]]: f32) -> f32 {
344// CHECK:           %[[VAL_1:.*]] = arith.constant -7.99881172 : f32
345// CHECK:           %[[VAL_2:.*]] = arith.constant 7.99881172 : f32
346// CHECK:           %[[VAL_3:.*]] = arith.constant 4.000000e-04 : f32
347// CHECK:           %[[VAL_4:.*]] = arith.constant 0.00489352457 : f32
348// CHECK:           %[[VAL_5:.*]] = arith.constant 6.37261954E-4 : f32
349// CHECK:           %[[VAL_6:.*]] = arith.constant 1.48572235E-5 : f32
350// CHECK:           %[[VAL_7:.*]] = arith.constant 5.12229725E-8 : f32
351// CHECK:           %[[VAL_8:.*]] = arith.constant -8.60467184E-11 : f32
352// CHECK:           %[[VAL_9:.*]] = arith.constant 2.00018794E-13 : f32
353// CHECK:           %[[VAL_10:.*]] = arith.constant -2.76076837E-16 : f32
354// CHECK:           %[[VAL_11:.*]] = arith.constant 0.00489352504 : f32
355// CHECK:           %[[VAL_12:.*]] = arith.constant 0.00226843474 : f32
356// CHECK:           %[[VAL_13:.*]] = arith.constant 1.18534706E-4 : f32
357// CHECK:           %[[VAL_14:.*]] = arith.constant 1.19825836E-6 : f32
358// CHECK:           %[[VAL_15:.*]] = arith.cmpf ult, %[[VAL_0]], %[[VAL_2]] : f32
359// CHECK:           %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_0]], %[[VAL_2]] : f32
360// CHECK:           %[[VAL_17:.*]] = arith.cmpf ugt, %[[VAL_16]], %[[VAL_1]] : f32
361// CHECK:           %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_16]], %[[VAL_1]] : f32
362// CHECK:           %[[VAL_19:.*]] = math.abs %[[VAL_0]] : f32
363// CHECK:           %[[VAL_20:.*]] = arith.cmpf olt, %[[VAL_19]], %[[VAL_3]] : f32
364// CHECK:           %[[VAL_21:.*]] = arith.mulf %[[VAL_18]], %[[VAL_18]] : f32
365// CHECK:           %[[VAL_22:.*]] = math.fma %[[VAL_21]], %[[VAL_10]], %[[VAL_9]] : f32
366// CHECK:           %[[VAL_23:.*]] = math.fma %[[VAL_21]], %[[VAL_22]], %[[VAL_8]] : f32
367// CHECK:           %[[VAL_24:.*]] = math.fma %[[VAL_21]], %[[VAL_23]], %[[VAL_7]] : f32
368// CHECK:           %[[VAL_25:.*]] = math.fma %[[VAL_21]], %[[VAL_24]], %[[VAL_6]] : f32
369// CHECK:           %[[VAL_26:.*]] = math.fma %[[VAL_21]], %[[VAL_25]], %[[VAL_5]] : f32
370// CHECK:           %[[VAL_27:.*]] = math.fma %[[VAL_21]], %[[VAL_26]], %[[VAL_4]] : f32
371// CHECK:           %[[VAL_28:.*]] = arith.mulf %[[VAL_18]], %[[VAL_27]] : f32
372// CHECK:           %[[VAL_29:.*]] = math.fma %[[VAL_21]], %[[VAL_14]], %[[VAL_13]] : f32
373// CHECK:           %[[VAL_30:.*]] = math.fma %[[VAL_21]], %[[VAL_29]], %[[VAL_12]] : f32
374// CHECK:           %[[VAL_31:.*]] = math.fma %[[VAL_21]], %[[VAL_30]], %[[VAL_11]] : f32
375// CHECK:           %[[VAL_32:.*]] = arith.divf %[[VAL_28]], %[[VAL_31]] : f32
376// CHECK:           %[[VAL_33:.*]] = arith.select %[[VAL_20]], %[[VAL_18]], %[[VAL_32]] : f32
377// CHECK:           return %[[VAL_33]] : f32
378// CHECK:         }
379func.func @tanh_scalar(%arg0: f32) -> f32 {
380  %0 = math.tanh %arg0 : f32
381  return %0 : f32
382}
383
384// CHECK-LABEL:   func @tanh_vector(
385// CHECK-SAME:                      %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
386// CHECK:           %[[VAL_1:.*]] = arith.constant dense<-7.99881172> : vector<8xf32>
387// CHECK-NOT:       tanh
388// CHECK-COUNT-2:   select
389// CHECK:           %[[VAL_33:.*]] = arith.select
390// CHECK:           return %[[VAL_33]] : vector<8xf32>
391// CHECK:         }
392func.func @tanh_vector(%arg0: vector<8xf32>) -> vector<8xf32> {
393  %0 = math.tanh %arg0 : vector<8xf32>
394  return %0 : vector<8xf32>
395}
396
397// We only approximate rsqrt for vectors and when the AVX2 option is enabled.
398// CHECK-LABEL:   func @rsqrt_scalar
399// AVX2-LABEL:    func @rsqrt_scalar
400// CHECK:           math.rsqrt
401// AVX2:            math.rsqrt
402func.func @rsqrt_scalar(%arg0: f32) -> f32 {
403  %0 = math.rsqrt %arg0 : f32
404  return %0 : f32
405}
406
407// CHECK-LABEL:   func @rsqrt_vector_8xf32
408// CHECK:           math.rsqrt
409// AVX2-LABEL:    func @rsqrt_vector_8xf32(
410// AVX2-SAME:       %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> {
411// AVX2:   %[[VAL_1:.*]] = arith.constant dense<0x7F800000> : vector<8xf32>
412// AVX2:   %[[VAL_2:.*]] = arith.constant dense<1.500000e+00> : vector<8xf32>
413// AVX2:   %[[VAL_3:.*]] = arith.constant dense<-5.000000e-01> : vector<8xf32>
414// AVX2:   %[[VAL_4:.*]] = arith.constant dense<1.17549435E-38> : vector<8xf32>
415// AVX2:   %[[VAL_5:.*]] = arith.mulf %[[VAL_0]], %[[VAL_3]] : vector<8xf32>
416// AVX2:   %[[VAL_6:.*]] = arith.cmpf olt, %[[VAL_0]], %[[VAL_4]] : vector<8xf32>
417// AVX2:   %[[VAL_7:.*]] = arith.cmpf oeq, %[[VAL_0]], %[[VAL_1]] : vector<8xf32>
418// AVX2:   %[[VAL_8:.*]] = arith.ori %[[VAL_6]], %[[VAL_7]] : vector<8xi1>
419// AVX2:   %[[VAL_9:.*]] = x86vector.avx.rsqrt %[[VAL_0]] : vector<8xf32>
420// AVX2:   %[[VAL_10:.*]] = arith.mulf %[[VAL_5]], %[[VAL_9]] : vector<8xf32>
421// AVX2:   %[[VAL_11:.*]] = math.fma %[[VAL_9]], %[[VAL_10]], %[[VAL_2]] : vector<8xf32>
422// AVX2:   %[[VAL_12:.*]] = arith.mulf %[[VAL_9]], %[[VAL_11]] : vector<8xf32>
423// AVX2:   %[[VAL_13:.*]] = arith.select %[[VAL_8]], %[[VAL_9]], %[[VAL_12]] : vector<8xi1>, vector<8xf32>
424// AVX2:   return %[[VAL_13]] : vector<8xf32>
425// AVX2: }
426func.func @rsqrt_vector_8xf32(%arg0: vector<8xf32>) -> vector<8xf32> {
427  %0 = math.rsqrt %arg0 : vector<8xf32>
428  return %0 : vector<8xf32>
429}
430
431// Virtual vector width is not a multiple of an AVX2 vector width.
432//
433// CHECK-LABEL:  func @rsqrt_vector_5xf32
434// CHECK:          math.rsqrt
435// AVX2-LABEL:   func @rsqrt_vector_5xf32
436// AVX2:           math.rsqrt
437func.func @rsqrt_vector_5xf32(%arg0: vector<5xf32>) -> vector<5xf32> {
438  %0 = math.rsqrt %arg0 : vector<5xf32>
439  return %0 : vector<5xf32>
440}
441
442// One dimensional virtual vector expanded and unrolled into multiple AVX2-sized
443// vectors.
444//
445// CHECK-LABEL: func @rsqrt_vector_16xf32
446// CHECK:         math.rsqrt
447// AVX2-LABEL:  func @rsqrt_vector_16xf32(
448// AVX2-SAME:     %[[ARG:.*]]: vector<16xf32>
449// AVX2-SAME:   ) -> vector<16xf32>
450// AVX2:          %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x8xf32>
451// AVX2:          %[[EXPAND:.*]] = vector.shape_cast %[[ARG]] : vector<16xf32> to vector<2x8xf32>
452// AVX2:          %[[VEC0:.*]] = vector.extract %[[EXPAND]][0]
453// AVX2:          %[[RSQRT0:.*]] = x86vector.avx.rsqrt %[[VEC0]]
454// AVX2:          %[[VEC1:.*]] = vector.extract %[[EXPAND]][1]
455// AVX2:          %[[RSQRT1:.*]] = x86vector.avx.rsqrt %[[VEC1]]
456// AVX2:          %[[RESULT0:.*]] = vector.insert %[[RSQRT0]], %[[INIT]] [0]
457// AVX2:          %[[RESULT1:.*]] = vector.insert %[[RSQRT1]], %[[RESULT0]] [1]
458// AVX2:          %[[RSQRT:.*]] = vector.shape_cast %[[RESULT1]] : vector<2x8xf32> to vector<16xf32>
459func.func @rsqrt_vector_16xf32(%arg0: vector<16xf32>) -> vector<16xf32> {
460  %0 = math.rsqrt %arg0 : vector<16xf32>
461  return %0 : vector<16xf32>
462}
463
464// Two dimensional virtual vector unrolled into multiple AVX2-sized vectors.
465//
466// CHECK-LABEL: func @rsqrt_vector_2x8xf32
467// CHECK:         math.rsqrt
468// AVX2-LABEL:  func @rsqrt_vector_2x8xf32(
469// AVX2-SAME:     %[[ARG:.*]]: vector<2x8xf32>
470// AVX2-SAME:   ) -> vector<2x8xf32>
471// AVX2:          %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x8xf32>
472// AVX2-NOT:      vector.shape_cast
473// AVX2:          %[[VEC0:.*]] = vector.extract %[[ARG]][0]
474// AVX2:          %[[RSQRT0:.*]] = x86vector.avx.rsqrt %[[VEC0]]
475// AVX2:          %[[VEC1:.*]] = vector.extract %[[ARG]][1]
476// AVX2:          %[[RSQRT1:.*]] = x86vector.avx.rsqrt %[[VEC1]]
477// AVX2:          %[[RESULT0:.*]] = vector.insert %[[RSQRT0]], %[[INIT]] [0]
478// AVX2:          %[[RESULT1:.*]] = vector.insert %[[RSQRT1]], %[[RESULT0]] [1]
479// AVX2-NOT:      vector.shape_cast
480func.func @rsqrt_vector_2x8xf32(%arg0: vector<2x8xf32>) -> vector<2x8xf32> {
481  %0 = math.rsqrt %arg0 : vector<2x8xf32>
482  return %0 : vector<2x8xf32>
483}
484
485// Two dimensional virtual vector expanded and unrolled into multiple AVX2-sized
486// vectors.
487//
488// CHECK-LABEL: func @rsqrt_vector_2x16xf32
489// CHECK:         math.rsqrt
490// AVX2-LABEL:  func @rsqrt_vector_2x16xf32(
491// AVX2-SAME:     %[[ARG:.*]]: vector<2x16xf32>
492// AVX2-SAME:   ) -> vector<2x16xf32>
493// AVX2:          %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x2x8xf32>
494// AVX2:          %[[EXPAND:.*]] = vector.shape_cast %[[ARG]] : vector<2x16xf32> to vector<2x2x8xf32>
495// AVX2:          %[[VEC00:.*]] = vector.extract %[[EXPAND]][0, 0]
496// AVX2:          %[[RSQRT00:.*]] = x86vector.avx.rsqrt %[[VEC00]]
497// AVX2:          %[[VEC01:.*]] = vector.extract %[[EXPAND]][0, 1]
498// AVX2:          %[[RSQRT01:.*]] = x86vector.avx.rsqrt %[[VEC01]]
499// AVX2:          %[[VEC10:.*]] = vector.extract %[[EXPAND]][1, 0]
500// AVX2:          %[[RSQRT10:.*]] = x86vector.avx.rsqrt %[[VEC10]]
501// AVX2:          %[[VEC11:.*]] = vector.extract %[[EXPAND]][1, 1]
502// AVX2:          %[[RSQRT11:.*]] = x86vector.avx.rsqrt %[[VEC11]]
503// AVX2:          %[[RESULT0:.*]] = vector.insert %[[RSQRT00]], %[[INIT]] [0, 0]
504// AVX2:          %[[RESULT1:.*]] = vector.insert %[[RSQRT01]], %[[RESULT0]] [0, 1]
505// AVX2:          %[[RESULT2:.*]] = vector.insert %[[RSQRT10]], %[[RESULT1]] [1, 0]
506// AVX2:          %[[RESULT3:.*]] = vector.insert %[[RSQRT11]], %[[RESULT2]] [1, 1]
507// AVX2:          %[[RSQRT:.*]] = vector.shape_cast %[[RESULT3]] : vector<2x2x8xf32> to vector<2x16xf32>
508func.func @rsqrt_vector_2x16xf32(%arg0: vector<2x16xf32>) -> vector<2x16xf32> {
509  %0 = math.rsqrt %arg0 : vector<2x16xf32>
510  return %0 : vector<2x16xf32>
511}
512
513// CHECK-LABEL: @atan_scalar
514// CHECK-DAG:  %[[ONE:.+]] = arith.constant 1.000000e+00
515// CHECK-DAG:  %[[N1:.+]] = arith.constant 0.144182831
516// CHECK-DAG:  %[[N2:.+]] = arith.constant -0.349992335
517// CHECK-DAG:  %[[N3:.+]] = arith.constant -0.0106783099
518// CHECK-DAG:  %[[N4:.+]] = arith.constant 1.00209987
519// CHECK-DAG:  %[[HALF_PI:.+]] = arith.constant 1.57079637
520// CHECK-DAG:  %[[ABS:.+]] = math.abs %arg0
521// CHECK-DAG:  %[[DIV:.+]] = arith.divf %cst, %[[ABS]]
522// CHECK-DAG:  %[[CMP:.+]] = arith.cmpf olt, %[[ABS]], %[[DIV]]
523// CHECK-DAG:  %[[SEL:.+]] = arith.select %[[CMP]], %[[ABS]], %[[DIV]]
524// CHECK-DAG:  %[[P0:.+]] = math.fma %[[SEL]], %[[N1]], %[[N2]]
525// CHECK-DAG:  %[[P1:.+]] = math.fma %[[SEL]], %[[P0]], %[[N3]]
526// CHECK-DAG:  %[[P2:.+]] = math.fma %[[SEL]], %[[P1]], %[[N4]]
527// CHECK-DAG:  %[[P3:.+]] = arith.mulf %[[SEL]], %[[P2]]
528// CHECK-DAG:  %[[SUB:.+]] = arith.subf %[[HALF_PI]], %[[P3]]
529// CHECK-DAG:  %[[EST:.+]] = arith.select %[[CMP]], %[[P3]], %[[SUB]]
530// CHECK-DAG:  %[[RES:.+]] = math.copysign %[[EST]], %arg0
531// CHECK:  return %[[RES]]
532func.func @atan_scalar(%arg0: f32) -> f32 {
533  %0 = math.atan %arg0 : f32
534  return %0 : f32
535}
536
537
538// CHECK-LABEL: @atan2_scalar
539
540// ATan approximation:
541// CHECK-DAG:  %[[ONE:.+]] = arith.constant 1.000000e+00
542// CHECK-DAG:  %[[N1:.+]] = arith.constant 0.144182831
543// CHECK-DAG:  %[[N2:.+]] = arith.constant -0.349992335
544// CHECK-DAG:  %[[N3:.+]] = arith.constant -0.0106783099
545// CHECK-DAG:  %[[N4:.+]] = arith.constant 1.00209987
546// CHECK-DAG:  %[[HALF_PI:.+]] = arith.constant 1.57079637
547// CHECK-DAG:  %[[ARG0:.+]] = arith.extf %arg0 : f16 to f32
548// CHECK-DAG:  %[[ARG1:.+]] = arith.extf %arg1 : f16 to f32
549// CHECK-DAG:  %[[RATIO:.+]] = arith.divf %[[ARG0]], %[[ARG1]]
550// CHECK-DAG:  %[[ABS:.+]] = math.abs %[[RATIO]]
551// CHECK-DAG:  %[[DIV:.+]] = arith.divf %cst, %[[ABS]]
552// CHECK-DAG:  %[[CMP:.+]] = arith.cmpf olt, %[[ABS]], %[[DIV]]
553// CHECK-DAG:  %[[SEL:.+]] = arith.select %[[CMP]], %[[ABS]], %[[DIV]]
554// CHECK-DAG:  %[[P0:.+]] = math.fma %[[SEL]], %[[N1]], %[[N2]]
555// CHECK-DAG:  %[[P1:.+]] = math.fma %[[SEL]], %[[P0]], %[[N3]]
556// CHECK-DAG:  %[[P2:.+]] = math.fma %[[SEL]], %[[P1]], %[[N4]]
557// CHECK-DAG:  %[[P3:.+]] = arith.mulf %[[SEL]], %[[P2]]
558// CHECK-DAG:  %[[SUB:.+]] = arith.subf %[[HALF_PI]], %[[P3]]
559// CHECK-DAG:  %[[EST:.+]] = arith.select %[[CMP]], %[[P3]], %[[SUB]]
560// CHECK-DAG:  %[[ATAN:.+]] = math.copysign %[[EST]], %[[RATIO]]
561
562// Handle the case of x < 0:
563// CHECK-DAG: %[[ZERO:.+]] = arith.constant 0.000000e+00
564// CHECK-DAG: %[[PI:.+]] = arith.constant 3.14159274
565// CHECK-DAG: %[[ADD_PI:.+]] = arith.addf %[[ATAN]], %[[PI]]
566// CHECK-DAG: %[[SUB_PI:.+]] = arith.subf %[[ATAN]], %[[PI]]
567// CHECK-DAG: %[[CMP_ATAN:.+]] = arith.cmpf ogt, %[[ATAN]], %[[ZERO]]
568// CHECK-DAG: %[[ATAN_ADJUST:.+]] = arith.select %[[CMP_ATAN]], %[[SUB_PI]], %[[ADD_PI]]
569// CHECK-DAG: %[[X_NEG:.+]] = arith.cmpf ogt, %[[ARG1]], %[[ZERO]]
570// CHECK-DAG: %[[ATAN_EST:.+]] = arith.select %[[X_NEG]], %[[ATAN]], %[[ATAN_ADJUST]]
571
572// Handle PI / 2 edge case:
573// CHECK-DAG: %[[X_ZERO:.+]] = arith.cmpf oeq, %[[ARG1]], %[[ZERO]]
574// CHECK-DAG: %[[Y_POS:.+]] = arith.cmpf ogt, %[[ARG0]], %[[ZERO]]
575// CHECK-DAG: %[[IS_HALF_PI:.+]] = arith.andi %[[X_ZERO]], %[[Y_POS]]
576// CHECK-DAG: %[[EDGE1:.+]] = arith.select %[[IS_HALF_PI]], %[[HALF_PI]], %[[ATAN_EST]]
577
578// Handle -PI / 2 edge case:
579// CHECK-DAG: %[[NEG_HALF_PI:.+]] = arith.constant -1.57079637
580// CHECK-DAG: %[[Y_NEG:.+]] = arith.cmpf olt, %[[ARG0]], %[[ZERO]]
581// CHECK-DAG: %[[IS_NEG_HALF_PI:.+]] = arith.andi %[[X_ZERO]], %[[Y_NEG]]
582// CHECK-DAG: %[[EDGE2:.+]] = arith.select %[[IS_NEG_HALF_PI]], %[[NEG_HALF_PI]], %[[EDGE1]]
583
584// Handle Nan edgecase:
585// CHECK-DAG: %[[Y_ZERO:.+]] = arith.cmpf oeq, %[[ARG0]], %[[ZERO]]
586// CHECK-DAG: %[[X_Y_ZERO:.+]] = arith.andi %[[X_ZERO]], %[[Y_ZERO]]
587// CHECK-DAG: %[[NAN:.+]] = arith.constant 0x7FC00000
588// CHECK-DAG: %[[EDGE3:.+]] = arith.select %[[X_Y_ZERO]], %[[NAN]], %[[EDGE2]]
589// CHECK: %[[RET:.+]] = arith.truncf %[[EDGE3]]
590// CHECK: return %[[RET]]
591
592func.func @atan2_scalar(%arg0: f16, %arg1: f16) -> f16 {
593  %0 = math.atan2 %arg0, %arg1 : f16
594  return %0 : f16
595}
596
597