$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
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 = [{
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;
};
DivISOpLowering,
DivIUOpLowering,
ExpOpLowering,
+ LogOpLowering,
+ Log10OpLowering,
+ Log2OpLowering,
FPExtLowering,
FPTruncLowering,
FuncOpConversion,
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