[Mlir-commits] [mlir] adf795d - [mlir][arith] Fold `and(a, and(a, b))` to `and(a, b)`
Ivan Butygin
llvmlistbot at llvm.org
Wed Nov 16 13:59:11 PST 2022
Author: Ivan Butygin
Date: 2022-11-16T22:57:41+01:00
New Revision: adf795dc7ce7d96220f2fc327286cd41bdaefe25
URL: https://github.com/llvm/llvm-project/commit/adf795dc7ce7d96220f2fc327286cd41bdaefe25
DIFF: https://github.com/llvm/llvm-project/commit/adf795dc7ce7d96220f2fc327286cd41bdaefe25.diff
LOG: [mlir][arith] Fold `and(a, and(a, b))` to `and(a, b)`
Differential Revision: https://reviews.llvm.org/D137647
Added:
Modified:
mlir/lib/Dialect/Arith/IR/ArithOps.cpp
mlir/test/Dialect/Arith/canonicalize.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index eaf8b31a11a14..9730e5834cef0 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -612,6 +612,23 @@ OpFoldResult arith::RemSIOp::fold(ArrayRef<Attribute> operands) {
// AndIOp
//===----------------------------------------------------------------------===//
+/// Fold `and(a, and(a, b))` to `and(a, b)`
+static Value foldAndIofAndI(arith::AndIOp op) {
+ for (bool reversePrev : {false, true}) {
+ auto prev = (reversePrev ? op.getRhs() : op.getLhs())
+ .getDefiningOp<arith::AndIOp>();
+ if (!prev)
+ continue;
+
+ Value other = (reversePrev ? op.getLhs() : op.getRhs());
+ if (other != prev.getLhs() && other != prev.getRhs())
+ continue;
+
+ return prev.getResult();
+ }
+ return {};
+}
+
OpFoldResult arith::AndIOp::fold(ArrayRef<Attribute> operands) {
/// and(x, 0) -> 0
if (matchPattern(getRhs(), m_Zero()))
@@ -631,6 +648,10 @@ OpFoldResult arith::AndIOp::fold(ArrayRef<Attribute> operands) {
intValue.isAllOnes())
return IntegerAttr::get(getType(), 0);
+ /// and(a, and(a, b)) -> and(a, b)
+ if (Value result = foldAndIofAndI(*this))
+ return result;
+
return constFoldBinaryOp<IntegerAttr>(
operands, [](APInt a, const APInt &b) { return std::move(a) & b; });
}
diff --git a/mlir/test/Dialect/Arith/canonicalize.mlir b/mlir/test/Dialect/Arith/canonicalize.mlir
index 336324ef4eec9..0ab4931d35a75 100644
--- a/mlir/test/Dialect/Arith/canonicalize.mlir
+++ b/mlir/test/Dialect/Arith/canonicalize.mlir
@@ -1682,3 +1682,45 @@ func.func @xorxor3(%a : i32, %b : i32) -> i32 {
}
// -----
+
+/// and(a, and(a, b)) -> and(a, b)
+
+// CHECK-LABEL: @andand0
+// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)
+// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
+// CHECK: return %[[RES]]
+func.func @andand0(%a : i32, %b : i32) -> i32 {
+ %c = arith.andi %a, %b : i32
+ %res = arith.andi %a, %c : i32
+ return %res : i32
+}
+
+// CHECK-LABEL: @andand1
+// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)
+// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
+// CHECK: return %[[RES]]
+func.func @andand1(%a : i32, %b : i32) -> i32 {
+ %c = arith.andi %a, %b : i32
+ %res = arith.andi %c, %a : i32
+ return %res : i32
+}
+
+// CHECK-LABEL: @andand2
+// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)
+// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
+// CHECK: return %[[RES]]
+func.func @andand2(%a : i32, %b : i32) -> i32 {
+ %c = arith.andi %a, %b : i32
+ %res = arith.andi %b, %c : i32
+ return %res : i32
+}
+
+// CHECK-LABEL: @andand3
+// CHECK-SAME: (%[[A:.*]]: i32, %[[B:.*]]: i32)
+// CHECK: %[[RES:.*]] = arith.andi %[[A]], %[[B]] : i32
+// CHECK: return %[[RES]]
+func.func @andand3(%a : i32, %b : i32) -> i32 {
+ %c = arith.andi %a, %b : i32
+ %res = arith.andi %c, %b : i32
+ return %res : i32
+}
More information about the Mlir-commits
mailing list