diff options
| -rw-r--r-- | mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 34 | ||||
| -rw-r--r-- | mlir/include/mlir/Dialect/StandardOps/Ops.td | 12 | ||||
| -rw-r--r-- | mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp | 12 | ||||
| -rw-r--r-- | mlir/test/Target/llvmir-intrinsics.mlir | 33 |
4 files changed, 91 insertions, 0 deletions
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 166cc5c4f9f..a7119147fc5 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -684,4 +684,38 @@ def LLVM_ExpOp : LLVM_Op<"intr.exp", [NoSideEffect]>, $res = builder.CreateCall(fn, {$in}); }]; } + +def LLVM_LogOp : LLVM_Op<"intr.log", [NoSideEffect]>, + Arguments<(ins LLVM_Type:$in)>, + Results<(outs LLVM_Type:$res)> { + let llvmBuilder = [{ + llvm::Module *module = builder.GetInsertBlock()->getModule(); + llvm::Function *fn = llvm::Intrinsic::getDeclaration( + module, llvm::Intrinsic::log, {$in->getType()}); + $res = builder.CreateCall(fn, {$in}); + }]; +} + +def LLVM_Log10Op : LLVM_Op<"intr.log10", [NoSideEffect]>, + Arguments<(ins LLVM_Type:$in)>, + Results<(outs LLVM_Type:$res)> { + let llvmBuilder = [{ + llvm::Module *module = builder.GetInsertBlock()->getModule(); + llvm::Function *fn = llvm::Intrinsic::getDeclaration( + module, llvm::Intrinsic::log10, {$in->getType()}); + $res = builder.CreateCall(fn, {$in}); + }]; +} + +def LLVM_Log2Op : LLVM_Op<"intr.log2", [NoSideEffect]>, + Arguments<(ins LLVM_Type:$in)>, + Results<(outs LLVM_Type:$res)> { + let llvmBuilder = [{ + llvm::Module *module = builder.GetInsertBlock()->getModule(); + llvm::Function *fn = llvm::Intrinsic::getDeclaration( + module, llvm::Intrinsic::log2, {$in->getType()}); + $res = builder.CreateCall(fn, {$in}); + }]; +} + #endif // LLVMIR_OPS diff --git a/mlir/include/mlir/Dialect/StandardOps/Ops.td b/mlir/include/mlir/Dialect/StandardOps/Ops.td index c67e3452f37..8e21a8bbbc1 100644 --- a/mlir/include/mlir/Dialect/StandardOps/Ops.td +++ b/mlir/include/mlir/Dialect/StandardOps/Ops.td @@ -837,6 +837,18 @@ def LoadOp : Std_Op<"load"> { let hasCanonicalizer = 1; } +def LogOp : FloatUnaryOp<"log"> { + let summary = "base-e logarithm of the specified value"; +} + +def Log10Op : FloatUnaryOp<"log10"> { + let summary = "base-10 logarithm of the specified value"; +} + +def Log2Op : FloatUnaryOp<"log2"> { + let summary = "base-2 logarithm of the specified value"; +} + def MemRefCastOp : CastOp<"memref_cast"> { let summary = "memref cast operation"; let description = [{ diff --git a/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp index 794683eb4d4..933c0cf48d1 100644 --- a/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp +++ b/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp @@ -812,6 +812,15 @@ using BinaryOpLLVMOpLowering = NaryOpLLVMOpLowering<SourceOp, TargetOp, 2>; struct ExpOpLowering : public UnaryOpLLVMOpLowering<ExpOp, LLVM::ExpOp> { using Super::Super; }; +struct LogOpLowering : public UnaryOpLLVMOpLowering<LogOp, LLVM::LogOp> { + using Super::Super; +}; +struct Log10OpLowering : public UnaryOpLLVMOpLowering<Log10Op, LLVM::Log10Op> { + using Super::Super; +}; +struct Log2OpLowering : public UnaryOpLLVMOpLowering<Log2Op, LLVM::Log2Op> { + using Super::Super; +}; struct AddIOpLowering : public BinaryOpLLVMOpLowering<AddIOp, LLVM::AddOp> { using Super::Super; }; @@ -2004,6 +2013,9 @@ void mlir::populateStdToLLVMConversionPatterns( DivISOpLowering, DivIUOpLowering, ExpOpLowering, + LogOpLowering, + Log10OpLowering, + Log2OpLowering, FPExtLowering, FPTruncLowering, FuncOpConversion, diff --git a/mlir/test/Target/llvmir-intrinsics.mlir b/mlir/test/Target/llvmir-intrinsics.mlir index bc08a04e8a8..2a85569546f 100644 --- a/mlir/test/Target/llvmir-intrinsics.mlir +++ b/mlir/test/Target/llvmir-intrinsics.mlir @@ -18,8 +18,41 @@ llvm.func @exp_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) { llvm.return } +// CHECK-LABEL: @log_test +llvm.func @log_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) { + // CHECK: call float @llvm.log.f32 + "llvm.intr.log"(%arg0) : (!llvm.float) -> !llvm.float + // CHECK: call <8 x float> @llvm.log.v8f32 + "llvm.intr.log"(%arg1) : (!llvm<"<8 x float>">) -> !llvm<"<8 x float>"> + llvm.return +} + +// CHECK-LABEL: @log10_test +llvm.func @log10_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) { + // CHECK: call float @llvm.log10.f32 + "llvm.intr.log10"(%arg0) : (!llvm.float) -> !llvm.float + // CHECK: call <8 x float> @llvm.log10.v8f32 + "llvm.intr.log10"(%arg1) : (!llvm<"<8 x float>">) -> !llvm<"<8 x float>"> + llvm.return +} + +// CHECK-LABEL: @log2_test +llvm.func @log2_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) { + // CHECK: call float @llvm.log2.f32 + "llvm.intr.log2"(%arg0) : (!llvm.float) -> !llvm.float + // CHECK: call <8 x float> @llvm.log2.v8f32 + "llvm.intr.log2"(%arg1) : (!llvm<"<8 x float>">) -> !llvm<"<8 x float>"> + llvm.return +} + // Check that intrinsics are declared with appropriate types. // CHECK: declare float @llvm.fmuladd.f32.f32.f32(float, float, float) // CHECK: declare <8 x float> @llvm.fmuladd.v8f32.v8f32.v8f32(<8 x float>, <8 x float>, <8 x float>) #0 // CHECK: declare float @llvm.exp.f32(float) // CHECK: declare <8 x float> @llvm.exp.v8f32(<8 x float>) #0 +// CHECK: declare float @llvm.log.f32(float) +// CHECK: declare <8 x float> @llvm.log.v8f32(<8 x float>) #0 +// CHECK: declare float @llvm.log10.f32(float) +// CHECK: declare <8 x float> @llvm.log10.v8f32(<8 x float>) #0 +// CHECK: declare float @llvm.log2.f32(float) +// CHECK: declare <8 x float> @llvm.log2.v8f32(<8 x float>) #0 |

