Skip to content

Commit

Permalink
LLVM dialect: introduce fmuladd intrinsic as operation
Browse files Browse the repository at this point in the history
This operation is important to achieve decent performance in computational
kernels.  In LLVM, it is implemented as an intrinsic (through function
declaration and function call).  Thanks to MLIR's extendable set of operations,
it does not have to differentiate between built-ins and intrinsics, so fmuladd
is introduced as a general type-polymorphic operation.  Custom printing and
parsing will be added later.

PiperOrigin-RevId: 263106305
  • Loading branch information
ftynse authored and tensorflower-gardener committed Aug 13, 2019
1 parent 88de8b2 commit 5f0a843
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
17 changes: 17 additions & 0 deletions mlir/include/mlir/LLVMIR/LLVMOps.td
Expand Up @@ -498,4 +498,21 @@ def LLVM_ConstantOp
let printer = [{ printConstantOp(p, *this); }];
}

// Operations that correspond to LLVM intrinsics. With MLIR operation set being
// extendable, there is no reason to introduce a hard boundary between "core"
// operations and intrinsics.

def LLVM_fmuladd : LLVM_Op<"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});
}];
}


#endif // LLVMIR_OPS
15 changes: 15 additions & 0 deletions mlir/test/Target/llvmir-intrinsics.mlir
@@ -0,0 +1,15 @@
// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s

// CHECK-LABEL: @intrinsics
func @intrinsics(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm<"<8 x float>">) {
// CHECK: call float @llvm.fmuladd.f32.f32.f32
"llvm.fmuladd"(%arg0, %arg1, %arg0) : (!llvm.float, !llvm.float, !llvm.float) -> !llvm.float
// CHECK: call <8 x float> @llvm.fmuladd.v8f32.v8f32.v8f32
"llvm.fmuladd"(%arg2, %arg2, %arg2) : (!llvm<"<8 x float>">, !llvm<"<8 x float>">, !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

0 comments on commit 5f0a843

Please sign in to comment.