From b0e515c9a00c25b6606d784fea6feca1e8705891 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Markus=20B=C3=B6ck?= Date: Wed, 24 Aug 2022 13:09:46 +0200 Subject: [PATCH] [mlir][arith] Fold `andi x, not(x)` to zero A bitwise and with the bitwise negate of itself is always 0, regardless of the integer type. This patch adds detection of such a pattern in `arith.andi`s `fold` method. Differential Revision: https://reviews.llvm.org/D131860 --- mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp | 10 +++++++++ mlir/test/Dialect/Arithmetic/canonicalize.mlir | 27 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp b/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp index 8546a37..11e64ff 100644 --- a/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp +++ b/mlir/lib/Dialect/Arithmetic/IR/ArithmeticOps.cpp @@ -574,6 +574,16 @@ OpFoldResult arith::AndIOp::fold(ArrayRef operands) { APInt intValue; if (matchPattern(getRhs(), m_ConstantInt(&intValue)) && intValue.isAllOnes()) return getLhs(); + /// and(x, not(x)) -> 0 + if (matchPattern(getRhs(), m_Op(matchers::m_Val(getLhs()), + m_ConstantInt(&intValue))) && + intValue.isAllOnes()) + return IntegerAttr::get(getType(), 0); + /// and(not(x), x) -> 0 + if (matchPattern(getLhs(), m_Op(matchers::m_Val(getRhs()), + m_ConstantInt(&intValue))) && + intValue.isAllOnes()) + return IntegerAttr::get(getType(), 0); return constFoldBinaryOp( operands, [](APInt a, const APInt &b) { return std::move(a) & b; }); diff --git a/mlir/test/Dialect/Arithmetic/canonicalize.mlir b/mlir/test/Dialect/Arithmetic/canonicalize.mlir index f99a070..a1ab1be 100644 --- a/mlir/test/Dialect/Arithmetic/canonicalize.mlir +++ b/mlir/test/Dialect/Arithmetic/canonicalize.mlir @@ -1532,3 +1532,30 @@ func.func @test_remf_vec() -> (vector<4xf32>) { %0 = arith.remf %v1, %v2 : vector<4xf32> return %0 : vector<4xf32> } + +// ----- + +// CHECK-LABEL: @test_andi_not_fold_rhs( +// CHECK-SAME: %[[ARG0:[[:alnum:]]+]] +// CHECK: %[[C:.*]] = arith.constant 0 : index +// CHECK: return %[[C]] + +func.func @test_andi_not_fold_rhs(%arg0 : index) -> index { + %0 = arith.constant -1 : index + %1 = arith.xori %arg0, %0 : index + %2 = arith.andi %arg0, %1 : index + return %2 : index +} + + +// CHECK-LABEL: @test_andi_not_fold_lhs( +// CHECK-SAME: %[[ARG0:[[:alnum:]]+]] +// CHECK: %[[C:.*]] = arith.constant 0 : index +// CHECK: return %[[C]] + +func.func @test_andi_not_fold_lhs(%arg0 : index) -> index { + %0 = arith.constant -1 : index + %1 = arith.xori %arg0, %0 : index + %2 = arith.andi %1, %arg0 : index + return %2 : index +} -- 2.7.4