xref: /llvm-project/mlir/test/Conversion/MathToLLVM/math-to-llvm.mlir (revision 78890904c41cc4221839dafb7ae906971a9db51a)
1// RUN: mlir-opt %s -split-input-file -pass-pipeline="builtin.module(func.func(convert-math-to-llvm))" | FileCheck %s
2
3// Same below, but using the `ConvertToLLVMPatternInterface` entry point
4// and the generic `convert-to-llvm` pass.
5// RUN: mlir-opt --convert-to-llvm="filter-dialects=math" --split-input-file %s | FileCheck %s
6
7// CHECK-LABEL: @ops
8func.func @ops(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32, %arg4: f64) {
9  // CHECK: = llvm.intr.exp(%{{.*}}) : (f32) -> f32
10  %0 = math.exp %arg0 : f32
11  // CHECK: = llvm.intr.exp2(%{{.*}}) : (f32) -> f32
12  %1 = math.exp2 %arg0 : f32
13  // CHECK: = llvm.intr.sqrt(%{{.*}}) : (f32) -> f32
14  %2 = math.sqrt %arg0 : f32
15  // CHECK: = llvm.intr.sqrt(%{{.*}}) : (f64) -> f64
16  %3 = math.sqrt %arg4 : f64
17  func.return
18}
19
20// -----
21
22func.func @absi(%arg0: i32) -> i32 {
23  // CHECK: = "llvm.intr.abs"(%{{.*}}) <{is_int_min_poison = false}> : (i32) -> i32
24  %0 = math.absi %arg0 : i32
25  return %0 : i32
26}
27
28// -----
29
30// CHECK-LABEL: func @log1p(
31// CHECK-SAME: f32
32func.func @log1p(%arg0 : f32) {
33  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f32) : f32
34  // CHECK: %[[ADD:.*]] = llvm.fadd %[[ONE]], %arg0 : f32
35  // CHECK: %[[LOG:.*]] = llvm.intr.log(%[[ADD]]) : (f32) -> f32
36  %0 = math.log1p %arg0 : f32
37  func.return
38}
39
40// -----
41
42// CHECK-LABEL: func @log1p_fmf(
43// CHECK-SAME: f32
44func.func @log1p_fmf(%arg0 : f32) {
45  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f32) : f32
46  // CHECK: %[[ADD:.*]] = llvm.fadd %[[ONE]], %arg0 {fastmathFlags = #llvm.fastmath<fast>} : f32
47  // CHECK: %[[LOG:.*]] = llvm.intr.log(%[[ADD]]) {fastmathFlags = #llvm.fastmath<fast>} : (f32) -> f32
48  %0 = math.log1p %arg0 fastmath<fast> : f32
49  func.return
50}
51
52// -----
53
54// CHECK-LABEL: func @log1p_2dvector(
55func.func @log1p_2dvector(%arg0 : vector<4x3xf32>) {
56  // CHECK: %[[EXTRACT:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.array<4 x vector<3xf32>>
57  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<3xf32>) : vector<3xf32>
58  // CHECK: %[[ADD:.*]] = llvm.fadd %[[ONE]], %[[EXTRACT]] : vector<3xf32>
59  // CHECK: %[[LOG:.*]] = llvm.intr.log(%[[ADD]]) : (vector<3xf32>) -> vector<3xf32>
60  // CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[LOG]], %{{.*}}[0] : !llvm.array<4 x vector<3xf32>>
61  %0 = math.log1p %arg0 : vector<4x3xf32>
62  func.return
63}
64
65// -----
66
67// CHECK-LABEL: func @log1p_2dvector_fmf(
68func.func @log1p_2dvector_fmf(%arg0 : vector<4x3xf32>) {
69  // CHECK: %[[EXTRACT:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.array<4 x vector<3xf32>>
70  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<3xf32>) : vector<3xf32>
71  // CHECK: %[[ADD:.*]] = llvm.fadd %[[ONE]], %[[EXTRACT]] {fastmathFlags = #llvm.fastmath<fast>} : vector<3xf32>
72  // CHECK: %[[LOG:.*]] = llvm.intr.log(%[[ADD]]) {fastmathFlags = #llvm.fastmath<fast>} : (vector<3xf32>) -> vector<3xf32>
73  // CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[LOG]], %{{.*}}[0] : !llvm.array<4 x vector<3xf32>>
74  %0 = math.log1p %arg0 fastmath<fast> : vector<4x3xf32>
75  func.return
76}
77
78// -----
79
80// CHECK-LABEL: func @log1p_scalable_vector(
81// CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
82func.func @log1p_scalable_vector(%arg0 : vector<[4]xf32>) -> vector<[4]xf32> {
83  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<[4]xf32>) : vector<[4]xf32>
84  // CHECK: %[[ADD:.*]] = llvm.fadd %[[ONE]], %[[VEC]]  : vector<[4]xf32>
85  // CHECK: %[[LOG:.*]] = llvm.intr.log(%[[ADD]])  : (vector<[4]xf32>) -> vector<[4]xf32>
86  %0 = math.log1p %arg0 : vector<[4]xf32>
87  func.return %0 : vector<[4]xf32>
88}
89
90// -----
91
92// CHECK-LABEL: func @expm1(
93// CHECK-SAME: f32
94func.func @expm1(%arg0 : f32) {
95  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f32) : f32
96  // CHECK: %[[EXP:.*]] = llvm.intr.exp(%arg0) : (f32) -> f32
97  // CHECK: %[[SUB:.*]] = llvm.fsub %[[EXP]], %[[ONE]] : f32
98  %0 = math.expm1 %arg0 : f32
99  func.return
100}
101
102// -----
103
104// CHECK-LABEL: func @expm1_fmf(
105// CHECK-SAME: f32
106func.func @expm1_fmf(%arg0 : f32) {
107  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f32) : f32
108  // CHECK: %[[EXP:.*]] = llvm.intr.exp(%arg0) {fastmathFlags = #llvm.fastmath<fast>} : (f32) -> f32
109  // CHECK: %[[SUB:.*]] = llvm.fsub %[[EXP]], %[[ONE]] {fastmathFlags = #llvm.fastmath<fast>} : f32
110  %0 = math.expm1 %arg0 fastmath<fast> : f32
111  func.return
112}
113
114// -----
115
116// CHECK-LABEL: func @expm1_vector(
117// CHECK-SAME: vector<4xf32>
118func.func @expm1_vector(%arg0 : vector<4xf32>) {
119  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<4xf32>) : vector<4xf32>
120  // CHECK: %[[EXP:.*]] = llvm.intr.exp(%arg0) : (vector<4xf32>) -> vector<4xf32>
121  // CHECK: %[[SUB:.*]] = llvm.fsub %[[EXP]], %[[ONE]] : vector<4xf32>
122  %0 = math.expm1 %arg0 : vector<4xf32>
123  func.return
124}
125
126// -----
127
128// CHECK-LABEL: func @expm1_scalable_vector(
129// CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
130func.func @expm1_scalable_vector(%arg0 : vector<[4]xf32>) -> vector<[4]xf32> {
131  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<[4]xf32>) : vector<[4]xf32>
132  // CHECK: %[[EXP:.*]] = llvm.intr.exp(%[[VEC]])  : (vector<[4]xf32>) -> vector<[4]xf32>
133  // CHECK: %[[SUB:.*]] = llvm.fsub %[[EXP]], %[[ONE]] : vector<[4]xf32>
134  %0 = math.expm1 %arg0 : vector<[4]xf32>
135  func.return %0 : vector<[4]xf32>
136}
137
138// -----
139
140// CHECK-LABEL: func @expm1_vector_fmf(
141// CHECK-SAME: vector<4xf32>
142func.func @expm1_vector_fmf(%arg0 : vector<4xf32>) {
143  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<4xf32>) : vector<4xf32>
144  // CHECK: %[[EXP:.*]] = llvm.intr.exp(%arg0) {fastmathFlags = #llvm.fastmath<fast>} : (vector<4xf32>) -> vector<4xf32>
145  // CHECK: %[[SUB:.*]] = llvm.fsub %[[EXP]], %[[ONE]] {fastmathFlags = #llvm.fastmath<fast>} : vector<4xf32>
146  %0 = math.expm1 %arg0 fastmath<fast> : vector<4xf32>
147  func.return
148}
149
150// -----
151
152// CHECK-LABEL: func @rsqrt(
153// CHECK-SAME: f32
154func.func @rsqrt(%arg0 : f32) {
155  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f32) : f32
156  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%arg0) : (f32) -> f32
157  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] : f32
158  %0 = math.rsqrt %arg0 : f32
159  func.return
160}
161
162// -----
163
164// CHECK-LABEL: func @sine(
165// CHECK-SAME: f32
166func.func @sine(%arg0 : f32) {
167  // CHECK: llvm.intr.sin(%arg0) : (f32) -> f32
168  %0 = math.sin %arg0 : f32
169  func.return
170}
171
172// -----
173
174// CHECK-LABEL: func @ctlz(
175// CHECK-SAME: i32
176func.func @ctlz(%arg0 : i32) {
177  // CHECK: "llvm.intr.ctlz"(%arg0) <{is_zero_poison = false}> : (i32) -> i32
178  %0 = math.ctlz %arg0 : i32
179  func.return
180}
181
182// -----
183
184// CHECK-LABEL: func @cttz(
185// CHECK-SAME: i32
186func.func @cttz(%arg0 : i32) {
187  // CHECK: "llvm.intr.cttz"(%arg0) <{is_zero_poison = false}> : (i32) -> i32
188  %0 = math.cttz %arg0 : i32
189  func.return
190}
191
192// -----
193
194// CHECK-LABEL: func @cttz_vec(
195// CHECK-SAME: i32
196func.func @cttz_vec(%arg0 : vector<4xi32>) {
197  // CHECK: "llvm.intr.cttz"(%arg0) <{is_zero_poison = false}> : (vector<4xi32>) -> vector<4xi32>
198  %0 = math.cttz %arg0 : vector<4xi32>
199  func.return
200}
201
202// -----
203
204// CHECK-LABEL: func @cttz_scalable_vec(
205// CHECK-SAME: %[[VEC:.*]]: vector<[4]xi32>
206func.func @cttz_scalable_vec(%arg0 : vector<[4]xi32>) -> vector<[4]xi32> {
207  // CHECK: "llvm.intr.cttz"(%[[VEC]]) <{is_zero_poison = false}> : (vector<[4]xi32>) -> vector<[4]xi32>
208  %0 = math.cttz %arg0 : vector<[4]xi32>
209  func.return %0 : vector<[4]xi32>
210}
211
212// -----
213
214// CHECK-LABEL: func @ctpop(
215// CHECK-SAME: i32
216func.func @ctpop(%arg0 : i32) {
217  // CHECK: llvm.intr.ctpop(%arg0) : (i32) -> i32
218  %0 = math.ctpop %arg0 : i32
219  func.return
220}
221
222// -----
223
224// CHECK-LABEL: func @ctpop_vector(
225// CHECK-SAME: vector<3xi32>
226func.func @ctpop_vector(%arg0 : vector<3xi32>) {
227  // CHECK: llvm.intr.ctpop(%arg0) : (vector<3xi32>) -> vector<3xi32>
228  %0 = math.ctpop %arg0 : vector<3xi32>
229  func.return
230}
231
232// -----
233
234// CHECK-LABEL: func @ctpop_scalable_vector(
235// CHECK-SAME: %[[VEC:.*]]: vector<[4]xi32>
236func.func @ctpop_scalable_vector(%arg0 : vector<[4]xi32>) -> vector<[4]xi32> {
237  // CHECK: llvm.intr.ctpop(%[[VEC]]) : (vector<[4]xi32>) -> vector<[4]xi32>
238  %0 = math.ctpop %arg0 : vector<[4]xi32>
239  func.return %0 : vector<[4]xi32>
240}
241
242// -----
243
244// CHECK-LABEL: func @rsqrt_double(
245// CHECK-SAME: f64
246func.func @rsqrt_double(%arg0 : f64) {
247  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f64) : f64
248  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%arg0) : (f64) -> f64
249  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] : f64
250  %0 = math.rsqrt %arg0 : f64
251  func.return
252}
253
254// -----
255
256// CHECK-LABEL: func @rsqrt_double_fmf(
257// CHECK-SAME: f64
258func.func @rsqrt_double_fmf(%arg0 : f64) {
259  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(1.000000e+00 : f64) : f64
260  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%arg0) {fastmathFlags = #llvm.fastmath<fast>} : (f64) -> f64
261  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] {fastmathFlags = #llvm.fastmath<fast>} : f64
262  %0 = math.rsqrt %arg0 fastmath<fast> : f64
263  func.return
264}
265
266// -----
267
268// CHECK-LABEL: func @rsqrt_vector(
269// CHECK-SAME: vector<4xf32>
270func.func @rsqrt_vector(%arg0 : vector<4xf32>) {
271  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<4xf32>) : vector<4xf32>
272  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%arg0) : (vector<4xf32>) -> vector<4xf32>
273  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] : vector<4xf32>
274  %0 = math.rsqrt %arg0 : vector<4xf32>
275  func.return
276}
277
278// -----
279
280// CHECK-LABEL: func @rsqrt_scalable_vector(
281// CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
282func.func @rsqrt_scalable_vector(%arg0 : vector<[4]xf32>) ->  vector<[4]xf32>{
283  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<[4]xf32>) : vector<[4]xf32>
284  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%[[VEC]]) : (vector<[4]xf32>) -> vector<[4]xf32>
285  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] : vector<[4]xf32>
286  %0 = math.rsqrt %arg0 : vector<[4]xf32>
287  func.return  %0 : vector<[4]xf32>
288}
289
290// -----
291
292// CHECK-LABEL: func @rsqrt_vector_fmf(
293// CHECK-SAME: vector<4xf32>
294func.func @rsqrt_vector_fmf(%arg0 : vector<4xf32>) {
295  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<4xf32>) : vector<4xf32>
296  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%arg0) {fastmathFlags = #llvm.fastmath<fast>} : (vector<4xf32>) -> vector<4xf32>
297  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] {fastmathFlags = #llvm.fastmath<fast>} : vector<4xf32>
298  %0 = math.rsqrt %arg0 fastmath<fast> : vector<4xf32>
299  func.return
300}
301
302// -----
303
304// CHECK-LABEL: func @rsqrt_scalable_vector_fmf(
305// CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
306func.func @rsqrt_scalable_vector_fmf(%arg0 : vector<[4]xf32>) -> vector<[4]xf32> {
307  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<[4]xf32>) : vector<[4]xf32>
308  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%[[VEC]]) {fastmathFlags = #llvm.fastmath<fast>} : (vector<[4]xf32>) -> vector<[4]xf32>
309  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] {fastmathFlags = #llvm.fastmath<fast>} : vector<[4]xf32>
310  %0 = math.rsqrt %arg0 fastmath<fast> : vector<[4]xf32>
311  func.return %0 : vector<[4]xf32>
312}
313
314// -----
315
316// CHECK-LABEL: func @rsqrt_multidim_vector(
317func.func @rsqrt_multidim_vector(%arg0 : vector<4x3xf32>) {
318  // CHECK: %[[EXTRACT:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.array<4 x vector<3xf32>>
319  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<3xf32>) : vector<3xf32>
320  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%[[EXTRACT]]) : (vector<3xf32>) -> vector<3xf32>
321  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] : vector<3xf32>
322  // CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[DIV]], %{{.*}}[0] : !llvm.array<4 x vector<3xf32>>
323  %0 = math.rsqrt %arg0 : vector<4x3xf32>
324  func.return
325}
326
327// -----
328
329// CHECK-LABEL: func @rsqrt_multidim_scalable_vector(
330func.func @rsqrt_multidim_scalable_vector(%arg0 : vector<4x[4]xf32>) -> vector<4x[4]xf32> {
331  // CHECK: %[[EXTRACT:.*]] = llvm.extractvalue %{{.*}}[0] : !llvm.array<4 x vector<[4]xf32>>
332  // CHECK: %[[ONE:.*]] = llvm.mlir.constant(dense<1.000000e+00> : vector<[4]xf32>) : vector<[4]xf32>
333  // CHECK: %[[SQRT:.*]] = llvm.intr.sqrt(%[[EXTRACT]]) : (vector<[4]xf32>) -> vector<[4]xf32>
334  // CHECK: %[[DIV:.*]] = llvm.fdiv %[[ONE]], %[[SQRT]] : vector<[4]xf32>
335  // CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[DIV]], %{{.*}}[0] : !llvm.array<4 x vector<[4]xf32>>
336  %0 = math.rsqrt %arg0 : vector<4x[4]xf32>
337  func.return %0 : vector<4x[4]xf32>
338}
339
340// -----
341
342// CHECK-LABEL: func @fpowi(
343// CHECK-SAME: f64
344func.func @fpowi(%arg0 : f64, %arg1 : i32) {
345  // CHECK: llvm.intr.powi(%arg0, %arg1) : (f64, i32) -> f64
346  %0 = math.fpowi %arg0, %arg1 : f64, i32
347  func.return
348}
349
350
351// -----
352
353// CHECK-LABEL: func @powf(
354// CHECK-SAME: f64
355func.func @powf(%arg0 : f64) {
356  // CHECK: %[[POWF:.*]] = llvm.intr.pow(%arg0, %arg0) : (f64, f64) -> f64
357  %0 = math.powf %arg0, %arg0 : f64
358  func.return
359}
360
361// -----
362
363// CHECK-LABEL: func @round(
364// CHECK-SAME: f32
365func.func @round(%arg0 : f32) {
366  // CHECK: llvm.intr.round(%arg0) : (f32) -> f32
367  %0 = math.round %arg0 : f32
368  func.return
369}
370
371// -----
372
373// CHECK-LABEL: func @roundeven(
374// CHECK-SAME: f32
375func.func @roundeven(%arg0 : f32) {
376  // CHECK: llvm.intr.roundeven(%arg0) : (f32) -> f32
377  %0 = math.roundeven %arg0 : f32
378  func.return
379}
380
381// -----
382
383// CHECK-LABEL: func @trunc(
384// CHECK-SAME: f32
385func.func @trunc(%arg0 : f32) {
386  // CHECK: llvm.intr.trunc(%arg0) : (f32) -> f32
387  %0 = math.trunc %arg0 : f32
388  func.return
389}
390
391// -----
392
393// CHECK-LABEL: func @fastmath(
394// CHECK-SAME: f32
395func.func @fastmath(%arg0 : f32, %arg1 : vector<4xf32>) {
396  // CHECK: llvm.intr.trunc(%arg0) {fastmathFlags = #llvm.fastmath<fast>} : (f32) -> f32
397  %0 = math.trunc %arg0 fastmath<fast> : f32
398  // CHECK: llvm.intr.pow(%arg0, %arg0) {fastmathFlags = #llvm.fastmath<afn>} : (f32, f32) -> f32
399  %1 = math.powf %arg0, %arg0 fastmath<afn> : f32
400  // CHECK: llvm.intr.sqrt(%arg0) : (f32) -> f32
401  %2 = math.sqrt %arg0 fastmath<none> : f32
402  // CHECK: llvm.intr.fma(%arg0, %arg0, %arg0) {fastmathFlags = #llvm.fastmath<fast>} : (f32, f32, f32) -> f32
403  %3 = math.fma %arg0, %arg0, %arg0 fastmath<reassoc,nnan,ninf,nsz,arcp,contract,afn> : f32
404  func.return
405}
406