Skip to content
This repository has been archived by the owner on Apr 23, 2021. It is now read-only.

Added LLVM ops and lowering phases from standard dialect. #300

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions include/mlir/Dialect/LLVMIR/LLVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -662,29 +662,40 @@ def LLVM_ConstantOp
// operations and intrinsics. However, we systematically prefix them with
// "intr." to avoid potential name clashes.

def LLVM_FMulAddOp : LLVM_Op<"intr.fmuladd", [NoSideEffect]>,
Arguments<(ins LLVM_Type:$a, LLVM_Type:$b, LLVM_Type:$c)>,
Results<(outs LLVM_Type:$res)> {
let llvmBuilder = [{
llvm::Module *module = builder.GetInsertBlock()->getModule();
llvm::Function *fn = llvm::Intrinsic::getDeclaration(
module, llvm::Intrinsic::fmuladd,
{$a->getType(), $b->getType(), $c->getType()});
$res = builder.CreateCall(fn, {$a, $b, $c});
}];
class LLVM_UnaryIntrinsicOp<string func, list<OpTrait> traits = []> :
LLVM_OneResultOp<"intr." # func,
!listconcat([NoSideEffect, SameOperandsAndResultType], traits)>,
Arguments<(ins LLVM_Type:$in)>,
LLVM_Builder<"$res = builder.CreateCall(llvm::Intrinsic::getDeclaration("
"builder.GetInsertBlock()->getModule(), llvm::Intrinsic::" # func # ","
"{$in->getType()}), {$in});"> {
}

def LLVM_ExpOp : LLVM_Op<"intr.exp", [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::exp, {$in->getType()});
$res = builder.CreateCall(fn, {$in});
}];
class LLVM_BinaryIntrinsicOp<string func, list<OpTrait> traits = []> :
LLVM_OneResultOp<"intr." # func,
!listconcat([NoSideEffect, SameOperandsAndResultType], traits)>,
Arguments<(ins LLVM_Type:$a, LLVM_Type:$b)>,
LLVM_Builder<"$res = builder.CreateCall(llvm::Intrinsic::getDeclaration("
"builder.GetInsertBlock()->getModule(), llvm::Intrinsic::" # func # ","
"{$a->getType(), $b->getType()}), {$a, $b});"> {
}

class LLVM_TernaryIntrinsicOp<string func, list<OpTrait> traits = []> :
LLVM_OneResultOp<"intr." # func,
!listconcat([NoSideEffect, SameOperandsAndResultType], traits)>,
Arguments<(ins LLVM_Type:$a, LLVM_Type:$b, LLVM_Type:$c)>,
LLVM_Builder<"$res = builder.CreateCall(llvm::Intrinsic::getDeclaration("
"builder.GetInsertBlock()->getModule(), llvm::Intrinsic::" # func # ","
"{$a->getType(), $b->getType(), $c->getType()}), {$a, $b, $c});"> {
}

def LLVM_ExpOp : LLVM_UnaryIntrinsicOp<"exp">;
def LLVM_FAbsOp : LLVM_UnaryIntrinsicOp<"fabs">;
def LLVM_FCeilOp : LLVM_UnaryIntrinsicOp<"ceil">;
def LLVM_CosOp : LLVM_UnaryIntrinsicOp<"cos">;
def LLVM_CopySignOp : LLVM_BinaryIntrinsicOp<"copysign">;
def LLVM_FMulAddOp : LLVM_TernaryIntrinsicOp<"fmuladd">;

def LLVM_LogOp : LLVM_Op<"intr.log", [NoSideEffect]>,
Arguments<(ins LLVM_Type:$in)>,
Results<(outs LLVM_Type:$res)> {
Expand Down
20 changes: 20 additions & 0 deletions lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,15 @@ using BinaryOpLLVMOpLowering = NaryOpLLVMOpLowering<SourceOp, TargetOp, 2>;

// Specific lowerings.
// FIXME: this should be tablegen'ed.
struct AbsFOpLowering : public UnaryOpLLVMOpLowering<AbsFOp, LLVM::FAbsOp> {
using Super::Super;
};
struct CeilFOpLowering : public UnaryOpLLVMOpLowering<CeilFOp, LLVM::FCeilOp> {
using Super::Super;
};
struct CosOpLowering : public UnaryOpLLVMOpLowering<CosOp, LLVM::CosOp> {
using Super::Super;
};
struct ExpOpLowering : public UnaryOpLLVMOpLowering<ExpOp, LLVM::ExpOp> {
using Super::Super;
};
Expand All @@ -821,6 +830,9 @@ struct Log10OpLowering : public UnaryOpLLVMOpLowering<Log10Op, LLVM::Log10Op> {
struct Log2OpLowering : public UnaryOpLLVMOpLowering<Log2Op, LLVM::Log2Op> {
using Super::Super;
};
struct NegFOpLowering : public UnaryOpLLVMOpLowering<NegFOp, LLVM::FNegOp> {
using Super::Super;
};
struct AddIOpLowering : public BinaryOpLLVMOpLowering<AddIOp, LLVM::AddOp> {
using Super::Super;
};
Expand Down Expand Up @@ -866,6 +878,9 @@ struct DivFOpLowering : public BinaryOpLLVMOpLowering<DivFOp, LLVM::FDivOp> {
struct RemFOpLowering : public BinaryOpLLVMOpLowering<RemFOp, LLVM::FRemOp> {
using Super::Super;
};
struct CopySignOpLowering : public BinaryOpLLVMOpLowering<CopySignOp, LLVM::CopySignOp> {
using Super::Super;
};
struct SelectOpLowering
: public OneToOneLLVMOpLowering<SelectOp, LLVM::SelectOp> {
using Super::Super;
Expand Down Expand Up @@ -2048,15 +2063,19 @@ void mlir::populateStdToLLVMConversionPatterns(
// FIXME: this should be tablegen'ed
// clang-format off
patterns.insert<
AbsFOpLowering,
AddFOpLowering,
AddIOpLowering,
AndOpLowering,
BranchOpLowering,
CallIndirectOpLowering,
CallOpLowering,
CeilFOpLowering,
CmpFOpLowering,
CmpIOpLowering,
CondBranchOpLowering,
CopySignOpLowering,
CosOpLowering,
ConstLLVMOpLowering,
DimOpLowering,
DivFOpLowering,
Expand All @@ -2074,6 +2093,7 @@ void mlir::populateStdToLLVMConversionPatterns(
MemRefCastOpLowering,
MulFOpLowering,
MulIOpLowering,
NegFOpLowering,
OrOpLowering,
RemFOpLowering,
RemISOpLowering,
Expand Down
42 changes: 42 additions & 0 deletions test/Target/llvmir-intrinsics.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,42 @@ llvm.func @log2_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) {
llvm.return
}

// CHECK-LABEL: @fabs_test
llvm.func @fabs_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) {
// CHECK: call float @llvm.fabs.f32
"llvm.intr.fabs"(%arg0) : (!llvm.float) -> !llvm.float
// CHECK: call <8 x float> @llvm.fabs.v8f32
"llvm.intr.fabs"(%arg1) : (!llvm<"<8 x float>">) -> !llvm<"<8 x float>">
llvm.return
}

// CHECK-LABEL: @ceil_test
llvm.func @ceil_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) {
// CHECK: call float @llvm.ceil.f32
"llvm.intr.ceil"(%arg0) : (!llvm.float) -> !llvm.float
// CHECK: call <8 x float> @llvm.ceil.v8f32
"llvm.intr.ceil"(%arg1) : (!llvm<"<8 x float>">) -> !llvm<"<8 x float>">
llvm.return
}

// CHECK-LABEL: @cos_test
llvm.func @cos_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x float>">) {
// CHECK: call float @llvm.cos.f32
"llvm.intr.cos"(%arg0) : (!llvm.float) -> !llvm.float
// CHECK: call <8 x float> @llvm.cos.v8f32
"llvm.intr.cos"(%arg1) : (!llvm<"<8 x float>">) -> !llvm<"<8 x float>">
llvm.return
}

dfki-jugr marked this conversation as resolved.
Show resolved Hide resolved
// CHECK-LABEL: @copysign_test
llvm.func @copysign_test(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm<"<8 x float>">, %arg3: !llvm<"<8 x float>">) {
// CHECK: call float @llvm.copysign.f32
"llvm.intr.copysign"(%arg0, %arg1) : (!llvm.float, !llvm.float) -> !llvm.float
// CHECK: call <8 x float> @llvm.copysign.v8f32
"llvm.intr.copysign"(%arg2, %arg3) : (!llvm<"<8 x float>">, !llvm<"<8 x float>">) -> !llvm<"<8 x float>">
dfki-jugr marked this conversation as resolved.
Show resolved Hide resolved
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
Expand All @@ -56,3 +92,9 @@ llvm.func @log2_test(%arg0: !llvm.float, %arg1: !llvm<"<8 x 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
// CHECK: declare float @llvm.fabs.f32(float)
// CHECK: declare <8 x float> @llvm.fabs.v8f32(<8 x float>) #0
// CHECK: declare float @llvm.ceil.f32(float)
// CHECK: declare <8 x float> @llvm.ceil.v8f32(<8 x float>) #0
// CHECK: declare float @llvm.cos.f32(float)
// CHECK: declare <8 x float> @llvm.cos.v8f32(<8 x float>) #0