Skip to content

Commit 35c0ab7

Browse files
committed
[MLIR] Simplify select to a not
Given a select that returns the logical negation of the condition, replace it with a not of the condition. Differential Revision: https://reviews.llvm.org/D104966
1 parent e5d8cfb commit 35c0ab7

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

mlir/include/mlir/Dialect/StandardOps/IR/Ops.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,7 @@ def SelectOp : Std_Op<"select", [NoSideEffect,
14541454
Value getFalseValue() { return false_value(); }
14551455
}];
14561456

1457+
let hasCanonicalizer = 1;
14571458
let hasFolder = 1;
14581459
}
14591460

mlir/lib/Dialect/StandardOps/IR/Ops.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,37 @@ static LogicalResult verify(ReturnOp op) {
14961496
// SelectOp
14971497
//===----------------------------------------------------------------------===//
14981498

1499+
// Transforms a select to a not, where relevant.
1500+
//
1501+
// select %arg, %false, %true
1502+
//
1503+
// becomes
1504+
//
1505+
// xor %arg, %true
1506+
struct SelectToNot : public OpRewritePattern<SelectOp> {
1507+
using OpRewritePattern<SelectOp>::OpRewritePattern;
1508+
1509+
LogicalResult matchAndRewrite(SelectOp op,
1510+
PatternRewriter &rewriter) const override {
1511+
if (!matchPattern(op.getTrueValue(), m_Zero()))
1512+
return failure();
1513+
1514+
if (!matchPattern(op.getFalseValue(), m_One()))
1515+
return failure();
1516+
1517+
if (!op.getType().isInteger(1))
1518+
return failure();
1519+
1520+
rewriter.replaceOpWithNewOp<XOrOp>(op, op.condition(), op.getFalseValue());
1521+
return success();
1522+
}
1523+
};
1524+
1525+
void SelectOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
1526+
MLIRContext *context) {
1527+
results.insert<SelectToNot>(context);
1528+
}
1529+
14991530
OpFoldResult SelectOp::fold(ArrayRef<Attribute> operands) {
15001531
auto trueVal = getTrueValue();
15011532
auto falseVal = getFalseValue();

mlir/test/Dialect/Standard/canonicalize.mlir

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,15 @@ func @branchCondProp(%arg0: i1) {
319319
^exit:
320320
return
321321
}
322+
323+
// -----
324+
325+
// CHECK-LABEL: @selToNot
326+
// CHECK: %[[trueval:.+]] = constant true
327+
// CHECK: %{{.+}} = xor %arg0, %[[trueval]] : i1
328+
func @selToNot(%arg0: i1) -> i1 {
329+
%true = constant true
330+
%false = constant false
331+
%res = select %arg0, %false, %true : i1
332+
return %res : i1
333+
}

0 commit comments

Comments
 (0)