diff --git a/include/NeuraDialect/NeuraOps.td b/include/NeuraDialect/NeuraOps.td index 06866449..d15bafc0 100644 --- a/include/NeuraDialect/NeuraOps.td +++ b/include/NeuraDialect/NeuraOps.td @@ -31,6 +31,16 @@ def Neura_FAddOp : Op { let traits = [SameOperandsAndResultElementType]; } +// Defines a floating-point substraction operation. +def Neura_FSubOp: Op { + let summary = "Floating substraction operation"; + let opName = "fsub"; + let arguments = (ins AnyFloat:$lhs, AnyFloat:$rhs); + let results = (outs AnyFloat:$result); + // let assemblyFormat = "$lhs `,` $rhs attr-dict `:` type($result)"; + let traits = [SameOperandsAndResultElementType]; +} + // Defines a floating-point multiplication operation. def Neura_FMulOp : Op { let summary = "Floating multiplication operation"; diff --git a/lib/Conversion/LlvmToNeura/LlvmToNeuraPatterns.td b/lib/Conversion/LlvmToNeura/LlvmToNeuraPatterns.td index 7daf5b08..6004cf96 100644 --- a/lib/Conversion/LlvmToNeura/LlvmToNeuraPatterns.td +++ b/lib/Conversion/LlvmToNeura/LlvmToNeuraPatterns.td @@ -3,11 +3,17 @@ include "mlir/IR/PatternBase.td" include "mlir/Dialect/LLVMIR/LLVMOps.td" include "NeuraDialect/NeuraOps.td" +// Floating point binary operations. def : Pat< (LLVM_FAddOp $lhs, $rhs, $_fastmath), (Neura_FAddOp $lhs, $rhs) >; +def : Pat< + (LLVM_FSubOp $lhs, $rhs, $_fastmath), + (Neura_FSubOp $lhs, $rhs) +>; + def : Pat< (LLVM_ConstantOp $value), (Neura_ConstantOp $value) diff --git a/test/neura/interpreter/interpreter.mlir b/test/neura/interpreter/interpreter.mlir index b9efeb87..c5e163e7 100644 --- a/test/neura/interpreter/interpreter.mlir +++ b/test/neura/interpreter/interpreter.mlir @@ -10,4 +10,14 @@ module { return %2 : f32 // CHECK: 11.0 } + + func.func @test_sub() -> f32 { + %arg0 = arith.constant 9.0 : f32 + %cst = arith.constant 2.0 : f32 + %0 = "neura.mov"(%arg0) : (f32) -> f32 + %1 = "neura.mov"(%cst) : (f32) -> f32 + %2 = "neura.fsub"(%0, %1) : (f32, f32) -> f32 + return %2 : f32 + // CHECK: 7.0 + } } diff --git a/test/neura/interpreter/lower_and_interpret_subf.mlir b/test/neura/interpreter/lower_and_interpret_subf.mlir new file mode 100644 index 00000000..47475f70 --- /dev/null +++ b/test/neura/interpreter/lower_and_interpret_subf.mlir @@ -0,0 +1,41 @@ +// RUN: mlir-opt %s \ +// RUN: --convert-scf-to-cf \ +// RUN: --convert-math-to-llvm \ +// RUN: --convert-arith-to-llvm \ +// RUN: --convert-func-to-llvm \ +// RUN: --convert-cf-to-llvm \ +// RUN: --reconcile-unrealized-casts \ +// RUN: -o %t-lowered-to-llvm.mlir + +// RUN: mlir-translate -mlir-to-llvmir \ +// RUN: %t-lowered-to-llvm.mlir \ +// RUN: -o %t-lower_and_interpreter.ll + +// RUN: llc %t-lower_and_interpreter.ll \ +// RUN: -filetype=obj -o %t-out.o + +// RUN: clang++ main.cpp %t-out.o \ +// RUN: -o %t-out.bin + +// RUN: %t-out.bin > %t-dumped_output.txt + +// RUN: mlir-neura-opt --lower-arith-to-neura --insert-mov %s \ +// RUN: -o %t-neura.mlir + +// RUN: neura-interpreter %t-neura.mlir >> %t-dumped_output.txt +// RUN: FileCheck %s < %t-dumped_output.txt + +// RUN: FileCheck %s -check-prefix=GOLDEN < %t-dumped_output.txt +// GOLDEN: 7.0 + +module { + func.func @test() -> f32 attributes { llvm.emit_c_interface }{ + %arg0 = arith.constant 9.0 : f32 + %cst = arith.constant 2.0 : f32 + %0 = arith.subf %arg0, %cst : f32 + // CHECK: Golden output: [[OUTPUT:[0-9]+\.[0-9]+]] + // CHECK: [neura-interpreter] Output: [[OUTPUT]] + return %0 : f32 + } +} + diff --git a/test/neura/llvm_sub.mlir b/test/neura/llvm_sub.mlir new file mode 100644 index 00000000..0003cc34 --- /dev/null +++ b/test/neura/llvm_sub.mlir @@ -0,0 +1,10 @@ +// RUN: mlir-neura-opt --assign-accelerator --lower-llvm-to-neura --insert-mov %s | FileCheck %s + +func.func @test(%a: f32) -> f32 { + %b = llvm.mlir.constant(2.0 : f32) : f32 + %res = llvm.fsub %a, %b : f32 + // CHECK: [[LHS:%.*]] = "neura.mov"(%{{.*}}) : (f32) -> f32 + // CHECK: [[RHS:%.*]] = "neura.mov"(%{{.*}}) : (f32) -> f32 + // CHECK: [[RES:%.*]] = "neura.fsub"([[LHS]], [[RHS]]) + return %res : f32 +} \ No newline at end of file diff --git a/tools/neura-interpreter/neura-interpreter.cpp b/tools/neura-interpreter/neura-interpreter.cpp index 972e442c..c12b58d0 100644 --- a/tools/neura-interpreter/neura-interpreter.cpp +++ b/tools/neura-interpreter/neura-interpreter.cpp @@ -73,6 +73,10 @@ int main(int argc, char **argv) { float lhs = valueMap[faddOp.getLhs()]; float rhs = valueMap[faddOp.getRhs()]; valueMap[faddOp.getResult()] = lhs + rhs; + } else if (auto fsubOp = dyn_cast(op)) { + float lhs = valueMap[fsubOp.getLhs()]; + float rhs = valueMap[fsubOp.getRhs()]; + valueMap[fsubOp.getResult()] = lhs - rhs; } else if (auto retOp = dyn_cast(op)) { float result = valueMap[retOp.getOperand(0)]; llvm::outs() << "[neura-interpreter] Output: " << llvm::format("%.6f", result) << "\n";