diff --git a/mlir/include/mlir/Dialect/Arithmetic/IR/ArithmeticOps.td b/mlir/include/mlir/Dialect/Arithmetic/IR/ArithmeticOps.td --- a/mlir/include/mlir/Dialect/Arithmetic/IR/ArithmeticOps.td +++ b/mlir/include/mlir/Dialect/Arithmetic/IR/ArithmeticOps.td @@ -594,7 +594,7 @@ // AddFOp //===----------------------------------------------------------------------===// -def Arith_AddFOp : Arith_FloatBinaryOp<"addf"> { +def Arith_AddFOp : Arith_FloatBinaryOp<"addf", [Commutative]> { let summary = "floating point addition operation"; let description = [{ The `addf` operation takes two operands and returns one result, each of @@ -627,6 +627,28 @@ def Arith_SubFOp : Arith_FloatBinaryOp<"subf"> { let summary = "floating point subtraction operation"; + let description = [{ + The `subf` operation takes two operands and returns one result, each of + these is required to be the same type. This type may be a floating point + scalar type, a vector whose element type is a floating point type, or a + floating point tensor. + + Example: + + ```mlir + // Scalar subtraction. + %a = arith.subf %b, %c : f64 + + // SIMD vector subtraction, e.g. for Intel SSE. + %f = arith.subf %g, %h : vector<4xf32> + + // Tensor subtraction. + %x = arith.subf %y, %z : tensor<4x?xbf16> + ``` + + TODO: In the distant future, this will accept optional attributes for fast + math, contraction, rounding mode, and other controls. + }]; let hasFolder = 1; } @@ -723,7 +745,7 @@ // MulFOp //===----------------------------------------------------------------------===// -def Arith_MulFOp : Arith_FloatBinaryOp<"mulf"> { +def Arith_MulFOp : Arith_FloatBinaryOp<"mulf", [Commutative]> { let summary = "floating point multiplication operation"; let description = [{ The `mulf` operation takes two operands and returns one result, each of diff --git a/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp b/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp --- a/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp +++ b/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp @@ -580,10 +580,6 @@ if (matchPattern(getRhs(), m_NegZeroFloat())) return getLhs(); - // addf(-0, x) -> x - if (matchPattern(getLhs(), m_NegZeroFloat())) - return getRhs(); - return constFoldBinaryOp( operands, [](const APFloat &a, const APFloat &b) { return a + b; }); } diff --git a/mlir/test/Dialect/Arithmetic/canonicalize.mlir b/mlir/test/Dialect/Arithmetic/canonicalize.mlir --- a/mlir/test/Dialect/Arithmetic/canonicalize.mlir +++ b/mlir/test/Dialect/Arithmetic/canonicalize.mlir @@ -658,7 +658,7 @@ %c0 = arith.constant 0.0 : f32 %c-0 = arith.constant -0.0 : f32 %c1 = arith.constant 1.0 : f32 - %0 = arith.addf %arg0, %c0 : f32 + %0 = arith.addf %c0, %arg0 : f32 %1 = arith.addf %arg0, %c-0 : f32 %2 = arith.addf %c-0, %arg0 : f32 %3 = arith.addf %c1, %c1 : f32 @@ -685,15 +685,18 @@ // ----- // CHECK-LABEL: @test_mulf( -func @test_mulf(%arg0 : f32) -> (f32, f32, f32) { - // CHECK-NEXT: %[[C4:.+]] = arith.constant 4.0 - // CHECK-NEXT: return %arg0, %arg0, %[[C4]] +func @test_mulf(%arg0 : f32) -> (f32, f32, f32, f32) { + // CHECK-DAG: %[[C2:.+]] = arith.constant 2.0 + // CHECK-DAG: %[[C4:.+]] = arith.constant 4.0 + // CHECK-NEXT: %[[X:.+]] = arith.mulf %arg0, %[[C2]] + // CHECK-NEXT: return %[[X]], %arg0, %arg0, %[[C4]] %c1 = arith.constant 1.0 : f32 %c2 = arith.constant 2.0 : f32 - %0 = arith.mulf %arg0, %c1 : f32 - %1 = arith.mulf %c1, %arg0 : f32 - %2 = arith.mulf %c2, %c2 : f32 - return %0, %1, %2 : f32, f32, f32 + %0 = arith.mulf %c2, %arg0 : f32 + %1 = arith.mulf %arg0, %c1 : f32 + %2 = arith.mulf %c1, %arg0 : f32 + %3 = arith.mulf %c2, %c2 : f32 + return %0, %1, %2, %3 : f32, f32, f32, f32 } // -----