1// RUN: mlir-opt %s -convert-math-to-libm -canonicalize | FileCheck %s
2
3// CHECK-DAG: @atan(f64) -> f64
4// CHECK-DAG: @atanf(f32) -> f32
5// CHECK-DAG: @erf(f64) -> f64
6// CHECK-DAG: @erff(f32) -> f32
7// CHECK-DAG: @expm1(f64) -> f64
8// CHECK-DAG: @expm1f(f32) -> f32
9// CHECK-DAG: @atan2(f64, f64) -> f64
10// CHECK-DAG: @atan2f(f32, f32) -> f32
11// CHECK-DAG: @tan(f64) -> f64
12// CHECK-DAG: @tanf(f32) -> f32
13// CHECK-DAG: @tanh(f64) -> f64
14// CHECK-DAG: @tanhf(f32) -> f32
15// CHECK-DAG: @round(f64) -> f64
16// CHECK-DAG: @roundf(f32) -> f32
17// CHECK-DAG: @cos(f64) -> f64
18// CHECK-DAG: @cosf(f32) -> f32
19// CHECK-DAG: @sin(f64) -> f64
20// CHECK-DAG: @sinf(f32) -> f32
21
22// CHECK-LABEL: func @atan_caller
23// CHECK-SAME: %[[FLOAT:.*]]: f32
24// CHECK-SAME: %[[DOUBLE:.*]]: f64
25// CHECK-SAME: %[[HALF:.*]]: f16
26// CHECK-SAME: %[[BFLOAT:.*]]: bf16
27func.func @atan_caller(%float: f32, %double: f64, %half: f16, %bfloat: bf16) -> (f32, f64, f16, bf16)  {
28  // CHECK: %[[FLOAT_RESULT:.*]] = call @atanf(%[[FLOAT]]) : (f32) -> f32
29  %float_result = math.atan %float : f32
30  // CHECK: %[[DOUBLE_RESULT:.*]] = call @atan(%[[DOUBLE]]) : (f64) -> f64
31  %double_result = math.atan %double : f64
32  // CHECK: %[[HALF_PROMOTED:.*]] = arith.extf %[[HALF]] : f16 to f32
33  // CHECK: %[[HALF_CALL:.*]] = call @atanf(%[[HALF_PROMOTED]]) : (f32) -> f32
34  // CHECK: %[[HALF_RESULT:.*]] = arith.truncf %[[HALF_CALL]] : f32 to f16
35  %half_result = math.atan %half : f16
36  // CHECK: %[[BFLOAT_PROMOTED:.*]] = arith.extf %[[BFLOAT]] : bf16 to f32
37  // CHECK: %[[BFLOAT_CALL:.*]] = call @atanf(%[[BFLOAT_PROMOTED]]) : (f32) -> f32
38  // CHECK: %[[BFLOAT_RESULT:.*]] = arith.truncf %[[BFLOAT_CALL]] : f32 to bf16
39  %bfloat_result = math.atan %bfloat : bf16
40  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]], %[[HALF_RESULT]], %[[BFLOAT_RESULT]]
41  return %float_result, %double_result, %half_result, %bfloat_result : f32, f64, f16, bf16
42}
43
44// CHECK-LABEL:   func @atan_vec_caller(
45// CHECK-SAME:                           %[[VAL_0:.*]]: vector<2xf32>,
46// CHECK-SAME:                           %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
47// CHECK-DAG:       %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
48// CHECK-DAG:       %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
49// CHECK:           %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : vector<2xf32>
50// CHECK:           %[[OUT0_F32:.*]] = call @atanf(%[[IN0_F32]]) : (f32) -> f32
51// CHECK:           %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
52// CHECK:           %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : vector<2xf32>
53// CHECK:           %[[OUT1_F32:.*]] = call @atanf(%[[IN1_F32]]) : (f32) -> f32
54// CHECK:           %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
55// CHECK:           %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : vector<2xf64>
56// CHECK:           %[[OUT0_F64:.*]] = call @atan(%[[IN0_F64]]) : (f64) -> f64
57// CHECK:           %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
58// CHECK:           %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : vector<2xf64>
59// CHECK:           %[[OUT1_F64:.*]] = call @atan(%[[IN1_F64]]) : (f64) -> f64
60// CHECK:           %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
61// CHECK:           return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
62// CHECK:         }
63func.func @atan_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
64  %float_result = math.atan %float : vector<2xf32>
65  %double_result = math.atan %double : vector<2xf64>
66  return %float_result, %double_result : vector<2xf32>, vector<2xf64>
67}
68
69// CHECK-LABEL: func @tanh_caller
70// CHECK-SAME: %[[FLOAT:.*]]: f32
71// CHECK-SAME: %[[DOUBLE:.*]]: f64
72func.func @tanh_caller(%float: f32, %double: f64) -> (f32, f64)  {
73  // CHECK-DAG: %[[FLOAT_RESULT:.*]] = call @tanhf(%[[FLOAT]]) : (f32) -> f32
74  %float_result = math.tanh %float : f32
75  // CHECK-DAG: %[[DOUBLE_RESULT:.*]] = call @tanh(%[[DOUBLE]]) : (f64) -> f64
76  %double_result = math.tanh %double : f64
77  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]]
78  return %float_result, %double_result : f32, f64
79}
80
81// CHECK-LABEL: func @atan2_caller
82// CHECK-SAME: %[[FLOAT:.*]]: f32
83// CHECK-SAME: %[[DOUBLE:.*]]: f64
84// CHECK-SAME: %[[HALF:.*]]: f16
85// CHECK-SAME: %[[BFLOAT:.*]]: bf16
86func.func @atan2_caller(%float: f32, %double: f64, %half: f16, %bfloat: bf16) -> (f32, f64, f16, bf16) {
87  // CHECK: %[[FLOAT_RESULT:.*]] = call @atan2f(%[[FLOAT]], %[[FLOAT]]) : (f32, f32) -> f32
88  %float_result = math.atan2 %float, %float : f32
89  // CHECK: %[[DOUBLE_RESULT:.*]] = call @atan2(%[[DOUBLE]], %[[DOUBLE]]) : (f64, f64) -> f64
90  %double_result = math.atan2 %double, %double : f64
91  // CHECK: %[[HALF_PROMOTED1:.*]] = arith.extf %[[HALF]] : f16 to f32
92  // CHECK: %[[HALF_PROMOTED2:.*]] = arith.extf %[[HALF]] : f16 to f32
93  // CHECK: %[[HALF_CALL:.*]] = call @atan2f(%[[HALF_PROMOTED1]], %[[HALF_PROMOTED2]]) : (f32, f32) -> f32
94  // CHECK: %[[HALF_RESULT:.*]] = arith.truncf %[[HALF_CALL]] : f32 to f16
95  %half_result = math.atan2 %half, %half : f16
96  // CHECK: %[[BFLOAT_PROMOTED1:.*]] = arith.extf %[[BFLOAT]] : bf16 to f32
97  // CHECK: %[[BFLOAT_PROMOTED2:.*]] = arith.extf %[[BFLOAT]] : bf16 to f32
98  // CHECK: %[[BFLOAT_CALL:.*]] = call @atan2f(%[[BFLOAT_PROMOTED1]], %[[BFLOAT_PROMOTED2]]) : (f32, f32) -> f32
99  // CHECK: %[[BFLOAT_RESULT:.*]] = arith.truncf %[[BFLOAT_CALL]] : f32 to bf16
100  %bfloat_result = math.atan2 %bfloat, %bfloat : bf16
101  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]], %[[HALF_RESULT]], %[[BFLOAT_RESULT]]
102  return %float_result, %double_result, %half_result, %bfloat_result : f32, f64, f16, bf16
103}
104
105// CHECK-LABEL: func @erf_caller
106// CHECK-SAME: %[[FLOAT:.*]]: f32
107// CHECK-SAME: %[[DOUBLE:.*]]: f64
108func.func @erf_caller(%float: f32, %double: f64) -> (f32, f64)  {
109  // CHECK-DAG: %[[FLOAT_RESULT:.*]] = call @erff(%[[FLOAT]]) : (f32) -> f32
110  %float_result = math.erf %float : f32
111  // CHECK-DAG: %[[DOUBLE_RESULT:.*]] = call @erf(%[[DOUBLE]]) : (f64) -> f64
112  %double_result = math.erf %double : f64
113  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]]
114  return %float_result, %double_result : f32, f64
115}
116
117// CHECK-LABEL:   func @erf_vec_caller(
118// CHECK-SAME:                           %[[VAL_0:.*]]: vector<2xf32>,
119// CHECK-SAME:                           %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
120func.func @erf_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
121  // CHECK-DAG:       %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
122  // CHECK-DAG:       %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
123  // CHECK:           %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : vector<2xf32>
124  // CHECK:           %[[OUT0_F32:.*]] = call @erff(%[[IN0_F32]]) : (f32) -> f32
125  // CHECK:           %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
126  // CHECK:           %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : vector<2xf32>
127  // CHECK:           %[[OUT1_F32:.*]] = call @erff(%[[IN1_F32]]) : (f32) -> f32
128  // CHECK:           %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
129  %float_result = math.erf %float : vector<2xf32>
130  // CHECK:           %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : vector<2xf64>
131  // CHECK:           %[[OUT0_F64:.*]] = call @erf(%[[IN0_F64]]) : (f64) -> f64
132  // CHECK:           %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
133  // CHECK:           %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : vector<2xf64>
134  // CHECK:           %[[OUT1_F64:.*]] = call @erf(%[[IN1_F64]]) : (f64) -> f64
135  // CHECK:           %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
136  %double_result = math.erf %double : vector<2xf64>
137  // CHECK:           return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
138  return %float_result, %double_result : vector<2xf32>, vector<2xf64>
139}
140
141// CHECK-LABEL: func @expm1_caller
142// CHECK-SAME: %[[FLOAT:.*]]: f32
143// CHECK-SAME: %[[DOUBLE:.*]]: f64
144func.func @expm1_caller(%float: f32, %double: f64) -> (f32, f64) {
145  // CHECK-DAG: %[[FLOAT_RESULT:.*]] = call @expm1f(%[[FLOAT]]) : (f32) -> f32
146  %float_result = math.expm1 %float : f32
147  // CHECK-DAG: %[[DOUBLE_RESULT:.*]] = call @expm1(%[[DOUBLE]]) : (f64) -> f64
148  %double_result = math.expm1 %double : f64
149  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]]
150  return %float_result, %double_result : f32, f64
151}
152
153func.func @expm1_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
154  %float_result = math.expm1 %float : vector<2xf32>
155  %double_result = math.expm1 %double : vector<2xf64>
156  return %float_result, %double_result : vector<2xf32>, vector<2xf64>
157}
158// CHECK-LABEL:   func @expm1_vec_caller(
159// CHECK-SAME:                           %[[VAL_0:.*]]: vector<2xf32>,
160// CHECK-SAME:                           %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
161// CHECK-DAG:       %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
162// CHECK-DAG:       %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
163// CHECK:           %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : vector<2xf32>
164// CHECK:           %[[OUT0_F32:.*]] = call @expm1f(%[[IN0_F32]]) : (f32) -> f32
165// CHECK:           %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
166// CHECK:           %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : vector<2xf32>
167// CHECK:           %[[OUT1_F32:.*]] = call @expm1f(%[[IN1_F32]]) : (f32) -> f32
168// CHECK:           %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
169// CHECK:           %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : vector<2xf64>
170// CHECK:           %[[OUT0_F64:.*]] = call @expm1(%[[IN0_F64]]) : (f64) -> f64
171// CHECK:           %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
172// CHECK:           %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : vector<2xf64>
173// CHECK:           %[[OUT1_F64:.*]] = call @expm1(%[[IN1_F64]]) : (f64) -> f64
174// CHECK:           %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
175// CHECK:           return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
176// CHECK:         }
177
178func.func @expm1_multidim_vec_caller(%float: vector<2x2xf32>) -> (vector<2x2xf32>) {
179  %result = math.expm1 %float : vector<2x2xf32>
180  return %result : vector<2x2xf32>
181}
182// CHECK-LABEL:   func @expm1_multidim_vec_caller(
183// CHECK-SAME:                           %[[VAL:.*]]: vector<2x2xf32>
184// CHECK-DAG:       %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2x2xf32>
185// CHECK:           %[[IN0_0_F32:.*]] = vector.extract %[[VAL]][0, 0] : vector<2x2xf32>
186// CHECK:           %[[OUT0_0_F32:.*]] = call @expm1f(%[[IN0_0_F32]]) : (f32) -> f32
187// CHECK:           %[[VAL_1:.*]] = vector.insert %[[OUT0_0_F32]], %[[CVF]] [0, 0] : f32 into vector<2x2xf32>
188// CHECK:           %[[IN0_1_F32:.*]] = vector.extract %[[VAL]][0, 1] : vector<2x2xf32>
189// CHECK:           %[[OUT0_1_F32:.*]] = call @expm1f(%[[IN0_1_F32]]) : (f32) -> f32
190// CHECK:           %[[VAL_2:.*]] = vector.insert %[[OUT0_1_F32]], %[[VAL_1]] [0, 1] : f32 into vector<2x2xf32>
191// CHECK:           %[[IN1_0_F32:.*]] = vector.extract %[[VAL]][1, 0] : vector<2x2xf32>
192// CHECK:           %[[OUT1_0_F32:.*]] = call @expm1f(%[[IN1_0_F32]]) : (f32) -> f32
193// CHECK:           %[[VAL_3:.*]] = vector.insert %[[OUT1_0_F32]], %[[VAL_2]] [1, 0] : f32 into vector<2x2xf32>
194// CHECK:           %[[IN1_1_F32:.*]] = vector.extract %[[VAL]][1, 1] : vector<2x2xf32>
195// CHECK:           %[[OUT1_1_F32:.*]] = call @expm1f(%[[IN1_1_F32]]) : (f32) -> f32
196// CHECK:           %[[VAL_4:.*]] = vector.insert %[[OUT1_1_F32]], %[[VAL_3]] [1, 1] : f32 into vector<2x2xf32>
197// CHECK:           return %[[VAL_4]] : vector<2x2xf32>
198// CHECK:         }
199
200// CHECK-LABEL: func @round_caller
201// CHECK-SAME: %[[FLOAT:.*]]: f32
202// CHECK-SAME: %[[DOUBLE:.*]]: f64
203func.func @round_caller(%float: f32, %double: f64) -> (f32, f64) {
204  // CHECK-DAG: %[[FLOAT_RESULT:.*]] = call @roundf(%[[FLOAT]]) : (f32) -> f32
205  %float_result = math.round %float : f32
206  // CHECK-DAG: %[[DOUBLE_RESULT:.*]] = call @round(%[[DOUBLE]]) : (f64) -> f64
207  %double_result = math.round %double : f64
208  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]]
209  return %float_result, %double_result : f32, f64
210}
211
212// CHECK-LABEL: func @cos_caller
213// CHECK-SAME: %[[FLOAT:.*]]: f32
214// CHECK-SAME: %[[DOUBLE:.*]]: f64
215func.func @cos_caller(%float: f32, %double: f64) -> (f32, f64)  {
216  // CHECK-DAG: %[[FLOAT_RESULT:.*]] = call @cosf(%[[FLOAT]]) : (f32) -> f32
217  %float_result = math.cos %float : f32
218  // CHECK-DAG: %[[DOUBLE_RESULT:.*]] = call @cos(%[[DOUBLE]]) : (f64) -> f64
219  %double_result = math.cos %double : f64
220  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]]
221  return %float_result, %double_result : f32, f64
222}
223
224// CHECK-LABEL: func @sin_caller
225// CHECK-SAME: %[[FLOAT:.*]]: f32
226// CHECK-SAME: %[[DOUBLE:.*]]: f64
227func.func @sin_caller(%float: f32, %double: f64) -> (f32, f64)  {
228  // CHECK-DAG: %[[FLOAT_RESULT:.*]] = call @sinf(%[[FLOAT]]) : (f32) -> f32
229  %float_result = math.sin %float : f32
230  // CHECK-DAG: %[[DOUBLE_RESULT:.*]] = call @sin(%[[DOUBLE]]) : (f64) -> f64
231  %double_result = math.sin %double : f64
232  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]]
233  return %float_result, %double_result : f32, f64
234}
235
236// CHECK-LABEL:   func @round_vec_caller(
237// CHECK-SAME:                           %[[VAL_0:.*]]: vector<2xf32>,
238// CHECK-SAME:                           %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
239func.func @round_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
240  // CHECK-DAG:       %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
241  // CHECK-DAG:       %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
242  // CHECK:           %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : vector<2xf32>
243  // CHECK:           %[[OUT0_F32:.*]] = call @roundf(%[[IN0_F32]]) : (f32) -> f32
244  // CHECK:           %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
245  // CHECK:           %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : vector<2xf32>
246  // CHECK:           %[[OUT1_F32:.*]] = call @roundf(%[[IN1_F32]]) : (f32) -> f32
247  // CHECK:           %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
248  %float_result = math.round %float : vector<2xf32>
249  // CHECK:           %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : vector<2xf64>
250  // CHECK:           %[[OUT0_F64:.*]] = call @round(%[[IN0_F64]]) : (f64) -> f64
251  // CHECK:           %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
252  // CHECK:           %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : vector<2xf64>
253  // CHECK:           %[[OUT1_F64:.*]] = call @round(%[[IN1_F64]]) : (f64) -> f64
254  // CHECK:           %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
255  %double_result = math.round %double : vector<2xf64>
256  // CHECK:           return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
257  return %float_result, %double_result : vector<2xf32>, vector<2xf64>
258}
259
260// CHECK-LABEL: func @tan_caller
261// CHECK-SAME: %[[FLOAT:.*]]: f32
262// CHECK-SAME: %[[DOUBLE:.*]]: f64
263// CHECK-SAME: %[[HALF:.*]]: f16
264// CHECK-SAME: %[[BFLOAT:.*]]: bf16
265func.func @tan_caller(%float: f32, %double: f64, %half: f16, %bfloat: bf16) -> (f32, f64, f16, bf16)  {
266  // CHECK: %[[FLOAT_RESULT:.*]] = call @tanf(%[[FLOAT]]) : (f32) -> f32
267  %float_result = math.tan %float : f32
268  // CHECK: %[[DOUBLE_RESULT:.*]] = call @tan(%[[DOUBLE]]) : (f64) -> f64
269  %double_result = math.tan %double : f64
270  // CHECK: %[[HALF_PROMOTED:.*]] = arith.extf %[[HALF]] : f16 to f32
271  // CHECK: %[[HALF_CALL:.*]] = call @tanf(%[[HALF_PROMOTED]]) : (f32) -> f32
272  // CHECK: %[[HALF_RESULT:.*]] = arith.truncf %[[HALF_CALL]] : f32 to f16
273  %half_result = math.tan %half : f16
274  // CHECK: %[[BFLOAT_PROMOTED:.*]] = arith.extf %[[BFLOAT]] : bf16 to f32
275  // CHECK: %[[BFLOAT_CALL:.*]] = call @tanf(%[[BFLOAT_PROMOTED]]) : (f32) -> f32
276  // CHECK: %[[BFLOAT_RESULT:.*]] = arith.truncf %[[BFLOAT_CALL]] : f32 to bf16
277  %bfloat_result = math.tan %bfloat : bf16
278  // CHECK: return %[[FLOAT_RESULT]], %[[DOUBLE_RESULT]], %[[HALF_RESULT]], %[[BFLOAT_RESULT]]
279  return %float_result, %double_result, %half_result, %bfloat_result : f32, f64, f16, bf16
280}
281
282// CHECK-LABEL:   func @tan_vec_caller(
283// CHECK-SAME:                           %[[VAL_0:.*]]: vector<2xf32>,
284// CHECK-SAME:                           %[[VAL_1:.*]]: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
285// CHECK-DAG:       %[[CVF:.*]] = arith.constant dense<0.000000e+00> : vector<2xf32>
286// CHECK-DAG:       %[[CVD:.*]] = arith.constant dense<0.000000e+00> : vector<2xf64>
287// CHECK:           %[[IN0_F32:.*]] = vector.extract %[[VAL_0]][0] : vector<2xf32>
288// CHECK:           %[[OUT0_F32:.*]] = call @tanf(%[[IN0_F32]]) : (f32) -> f32
289// CHECK:           %[[VAL_8:.*]] = vector.insert %[[OUT0_F32]], %[[CVF]] [0] : f32 into vector<2xf32>
290// CHECK:           %[[IN1_F32:.*]] = vector.extract %[[VAL_0]][1] : vector<2xf32>
291// CHECK:           %[[OUT1_F32:.*]] = call @tanf(%[[IN1_F32]]) : (f32) -> f32
292// CHECK:           %[[VAL_11:.*]] = vector.insert %[[OUT1_F32]], %[[VAL_8]] [1] : f32 into vector<2xf32>
293// CHECK:           %[[IN0_F64:.*]] = vector.extract %[[VAL_1]][0] : vector<2xf64>
294// CHECK:           %[[OUT0_F64:.*]] = call @tan(%[[IN0_F64]]) : (f64) -> f64
295// CHECK:           %[[VAL_14:.*]] = vector.insert %[[OUT0_F64]], %[[CVD]] [0] : f64 into vector<2xf64>
296// CHECK:           %[[IN1_F64:.*]] = vector.extract %[[VAL_1]][1] : vector<2xf64>
297// CHECK:           %[[OUT1_F64:.*]] = call @tan(%[[IN1_F64]]) : (f64) -> f64
298// CHECK:           %[[VAL_17:.*]] = vector.insert %[[OUT1_F64]], %[[VAL_14]] [1] : f64 into vector<2xf64>
299// CHECK:           return %[[VAL_11]], %[[VAL_17]] : vector<2xf32>, vector<2xf64>
300// CHECK:         }
301func.func @tan_vec_caller(%float: vector<2xf32>, %double: vector<2xf64>) -> (vector<2xf32>, vector<2xf64>) {
302  %float_result = math.tan %float : vector<2xf32>
303  %double_result = math.tan %double : vector<2xf64>
304  return %float_result, %double_result : vector<2xf32>, vector<2xf64>
305}
306