From 5011b8896dfa63881161f7824357666e7d3af654 Mon Sep 17 00:00:00 2001 From: Ivan Butygin Date: Wed, 17 May 2023 20:22:27 +0200 Subject: [PATCH] [mlir][arith] Fold `or(x, xor(x, 1))` -> `1` Differential Revision: https://reviews.llvm.org/D150808 --- mlir/lib/Dialect/Arith/IR/ArithOps.cpp | 12 ++++++ mlir/test/Dialect/Arith/canonicalize.mlir | 66 +++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp index a583544..d0d83c2 100644 --- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp +++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp @@ -812,6 +812,18 @@ OpFoldResult arith::OrIOp::fold(FoldAdaptor adaptor) { if (rhsAttr.getValue().isAllOnes()) return rhsAttr; + APInt intValue; + /// or(x, xor(x, 1)) -> 1 + if (matchPattern(getRhs(), m_Op(matchers::m_Val(getLhs()), + m_ConstantInt(&intValue))) && + intValue.isAllOnes()) + return getRhs().getDefiningOp().getRhs(); + /// or(xor(x, 1), x) -> 1 + if (matchPattern(getLhs(), m_Op(matchers::m_Val(getRhs()), + m_ConstantInt(&intValue))) && + intValue.isAllOnes()) + return getLhs().getDefiningOp().getRhs(); + return constFoldBinaryOp( adaptor.getOperands(), [](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 14589b2..dd32e5b 100644 --- a/mlir/test/Dialect/Arith/canonicalize.mlir +++ b/mlir/test/Dialect/Arith/canonicalize.mlir @@ -2477,3 +2477,69 @@ func.func @foldShrsi0(%x : i64) -> i64 { %r = arith.shrsi %x, %c0 : i64 return %r : i64 } + +// CHECK-LABEL: @foldOrXor1 +// CHECK-SAME: (%[[ARG:.*]]: i1) +// CHECK: %[[ONE:.*]] = arith.constant true +// CHECK: return %[[ONE]] +func.func @foldOrXor1(%arg0: i1) -> i1 { + %0 = arith.constant true + %1 = arith.xori %arg0, %0 : i1 + %2 = arith.ori %arg0, %1 : i1 + return %2 : i1 +} + +// CHECK-LABEL: @foldOrXor2 +// CHECK-SAME: (%[[ARG:.*]]: i1) +// CHECK: %[[ONE:.*]] = arith.constant true +// CHECK: return %[[ONE]] +func.func @foldOrXor2(%arg0: i1) -> i1 { + %0 = arith.constant true + %1 = arith.xori %0, %arg0 : i1 + %2 = arith.ori %arg0, %1 : i1 + return %2 : i1 +} + +// CHECK-LABEL: @foldOrXor3 +// CHECK-SAME: (%[[ARG:.*]]: i1) +// CHECK: %[[ONE:.*]] = arith.constant true +// CHECK: return %[[ONE]] +func.func @foldOrXor3(%arg0: i1) -> i1 { + %0 = arith.constant true + %1 = arith.xori %arg0, %0 : i1 + %2 = arith.ori %1, %arg0 : i1 + return %2 : i1 +} + +// CHECK-LABEL: @foldOrXor4 +// CHECK-SAME: (%[[ARG:.*]]: i1) +// CHECK: %[[ONE:.*]] = arith.constant true +// CHECK: return %[[ONE]] +func.func @foldOrXor4(%arg0: i1) -> i1 { + %0 = arith.constant true + %1 = arith.xori %0, %arg0 : i1 + %2 = arith.ori %1, %arg0 : i1 + return %2 : i1 +} + +// CHECK-LABEL: @foldOrXor5 +// CHECK-SAME: (%[[ARG:.*]]: i32) +// CHECK: %[[ONE:.*]] = arith.constant -1 +// CHECK: return %[[ONE]] +func.func @foldOrXor5(%arg0: i32) -> i32 { + %0 = arith.constant -1 : i32 + %1 = arith.xori %arg0, %0 : i32 + %2 = arith.ori %arg0, %1 : i32 + return %2 : i32 +} + +// CHECK-LABEL: @foldOrXor6 +// CHECK-SAME: (%[[ARG:.*]]: index) +// CHECK: %[[ONE:.*]] = arith.constant -1 +// CHECK: return %[[ONE]] +func.func @foldOrXor6(%arg0: index) -> index { + %0 = arith.constant -1 : index + %1 = arith.xori %arg0, %0 : index + %2 = arith.ori %arg0, %1 : index + return %2 : index +} -- 2.7.4