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