1 // RUN: mlir-opt %s -split-input-file -pass-pipeline="builtin.module(func.func(convert-math-to-llvm))" | FileCheck %s
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
8 func.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
22 func.func @absi(%arg0: i32) -> i32 {
23 // CHECK: = "llvm.intr.abs"(%{{.*}}) <{is_int_min_poison = false}> : (i32) -> i32
24 %0 = math.absi %arg0 : i32
30 // CHECK-LABEL: func @log1p(
32 func.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
42 // CHECK-LABEL: func @log1p_fmf(
44 func.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
54 // CHECK-LABEL: func @log1p_2dvector(
55 func.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>
67 // CHECK-LABEL: func @log1p_2dvector_fmf(
68 func.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>
80 // CHECK-LABEL: func @log1p_scalable_vector(
81 // CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
82 func.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>
92 // CHECK-LABEL: func @expm1(
94 func.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
104 // CHECK-LABEL: func @expm1_fmf(
106 func.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
116 // CHECK-LABEL: func @expm1_vector(
117 // CHECK-SAME: vector<4xf32>
118 func.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>
128 // CHECK-LABEL: func @expm1_scalable_vector(
129 // CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
130 func.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>
140 // CHECK-LABEL: func @expm1_vector_fmf(
141 // CHECK-SAME: vector<4xf32>
142 func.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>
152 // CHECK-LABEL: func @rsqrt(
154 func.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
164 // CHECK-LABEL: func @sine(
166 func.func @sine(%arg0 : f32) {
167 // CHECK: llvm.intr.sin(%arg0) : (f32) -> f32
168 %0 = math.sin %arg0 : f32
174 // CHECK-LABEL: func @ctlz(
176 func.func @ctlz(%arg0 : i32) {
177 // CHECK: "llvm.intr.ctlz"(%arg0) <{is_zero_poison = false}> : (i32) -> i32
178 %0 = math.ctlz %arg0 : i32
184 // CHECK-LABEL: func @cttz(
186 func.func @cttz(%arg0 : i32) {
187 // CHECK: "llvm.intr.cttz"(%arg0) <{is_zero_poison = false}> : (i32) -> i32
188 %0 = math.cttz %arg0 : i32
194 // CHECK-LABEL: func @cttz_vec(
196 func.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>
204 // CHECK-LABEL: func @cttz_scalable_vec(
205 // CHECK-SAME: %[[VEC:.*]]: vector<[4]xi32>
206 func.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>
214 // CHECK-LABEL: func @ctpop(
216 func.func @ctpop(%arg0 : i32) {
217 // CHECK: llvm.intr.ctpop(%arg0) : (i32) -> i32
218 %0 = math.ctpop %arg0 : i32
224 // CHECK-LABEL: func @ctpop_vector(
225 // CHECK-SAME: vector<3xi32>
226 func.func @ctpop_vector(%arg0 : vector<3xi32>) {
227 // CHECK: llvm.intr.ctpop(%arg0) : (vector<3xi32>) -> vector<3xi32>
228 %0 = math.ctpop %arg0 : vector<3xi32>
234 // CHECK-LABEL: func @ctpop_scalable_vector(
235 // CHECK-SAME: %[[VEC:.*]]: vector<[4]xi32>
236 func.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>
244 // CHECK-LABEL: func @rsqrt_double(
246 func.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
256 // CHECK-LABEL: func @rsqrt_double_fmf(
258 func.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
268 // CHECK-LABEL: func @rsqrt_vector(
269 // CHECK-SAME: vector<4xf32>
270 func.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>
280 // CHECK-LABEL: func @rsqrt_scalable_vector(
281 // CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
282 func.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>
292 // CHECK-LABEL: func @rsqrt_vector_fmf(
293 // CHECK-SAME: vector<4xf32>
294 func.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>
304 // CHECK-LABEL: func @rsqrt_scalable_vector_fmf(
305 // CHECK-SAME: %[[VEC:.*]]: vector<[4]xf32>
306 func.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>
316 // CHECK-LABEL: func @rsqrt_multidim_vector(
317 func.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>
329 // CHECK-LABEL: func @rsqrt_multidim_scalable_vector(
330 func.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>
342 // CHECK-LABEL: func @fpowi(
344 func.func @fpowi(%arg0 : f64, %arg1 : i32) {
345 // CHECK: llvm.intr.powi(%arg0, %arg1) : (f64, i32) -> f64
346 %0 = math.fpowi %arg0, %arg1 : f64, i32
353 // CHECK-LABEL: func @powf(
355 func.func @powf(%arg0 : f64) {
356 // CHECK: %[[POWF:.*]] = llvm.intr.pow(%arg0, %arg0) : (f64, f64) -> f64
357 %0 = math.powf %arg0, %arg0 : f64
363 // CHECK-LABEL: func @round(
365 func.func @round(%arg0 : f32) {
366 // CHECK: llvm.intr.round(%arg0) : (f32) -> f32
367 %0 = math.round %arg0 : f32
373 // CHECK-LABEL: func @roundeven(
375 func.func @roundeven(%arg0 : f32) {
376 // CHECK: llvm.intr.roundeven(%arg0) : (f32) -> f32
377 %0 = math.roundeven %arg0 : f32
383 // CHECK-LABEL: func @trunc(
385 func.func @trunc(%arg0 : f32) {
386 // CHECK: llvm.intr.trunc(%arg0) : (f32) -> f32
387 %0 = math.trunc %arg0 : f32
393 // CHECK-LABEL: func @fastmath(
395 func.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