diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td --- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td +++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td @@ -1101,6 +1101,8 @@ ); let builders = [Tosa_UnaryOpQuantInfoBuilder]; + + let hasFolder = 1; } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp --- a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp +++ b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp @@ -1017,3 +1017,13 @@ return {}; } + +OpFoldResult tosa::NegateOp::fold(FoldAdaptor adaptor) { + auto input = getInput1(); + // Element-wise negate(negate(x)) = x + if (auto op = input.getDefiningOp()) { + return op.getInput1(); + } + + return {}; +} diff --git a/mlir/test/Dialect/Tosa/canonicalize.mlir b/mlir/test/Dialect/Tosa/canonicalize.mlir --- a/mlir/test/Dialect/Tosa/canonicalize.mlir +++ b/mlir/test/Dialect/Tosa/canonicalize.mlir @@ -525,3 +525,14 @@ %1 = "tosa.exp"(%0) : (tensor) -> tensor return %1 : tensor } + +// ----- + +// CHECK-LABEL: @fold_negate_negate +func.func @fold_negate_negate(%arg0: tensor) -> tensor { + // CHECK: return %arg{{.*}} : tensor + %0 = "tosa.negate"(%arg0) : (tensor) -> tensor + %1 = "tosa.negate"(%0) : (tensor) -> tensor + return %1 : tensor +} +