[mlir][arith] Fold select with poison

If either of the operands of `select` is fully poisoned we can simply return the other.
This PR implements this optimization inside the `fold` method.

Note that this patch is the first to add a dependency on the UB dialect within Arith. Given this was inevitable (and part of the motivation) it should be fine I believe.

Differential Revision: https://reviews.llvm.org/D158986
This commit is contained in:
Markus Böck
2023-08-28 16:07:59 +02:00
parent b667e9c23d
commit bbf0733030
3 changed files with 26 additions and 0 deletions

View File

@@ -13,6 +13,7 @@
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/CommonFolders.h"
#include "mlir/Dialect/UB/IR/UBOps.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributeInterfaces.h"
#include "mlir/IR/BuiltinAttributes.h"
@@ -2194,6 +2195,13 @@ OpFoldResult arith::SelectOp::fold(FoldAdaptor adaptor) {
if (matchPattern(condition, m_Zero()))
return falseVal;
// If either operand is fully poisoned, return the other.
if (isa_and_nonnull<ub::PoisonAttr>(adaptor.getTrueValue()))
return falseVal;
if (isa_and_nonnull<ub::PoisonAttr>(adaptor.getFalseValue()))
return trueVal;
// select %x, true, false => %x
if (getType().isInteger(1) && matchPattern(getTrueValue(), m_One()) &&
matchPattern(getFalseValue(), m_Zero()))

View File

@@ -28,6 +28,7 @@ add_mlir_dialect_library(MLIRArithDialect
MLIRInferIntRangeInterface
MLIRInferTypeOpInterface
MLIRIR
MLIRUBDialect
)
add_mlir_dialect_library(MLIRArithValueBoundsOpInterfaceImpl

View File

@@ -2567,3 +2567,20 @@ func.func @foldOrXor6(%arg0: index) -> index {
%2 = arith.ori %arg0, %1 : index
return %2 : index
}
// CHECK-LABEL: @selectOfPoison
// CHECK-SAME: %[[ARG:[[:alnum:]]+]]: i32
// CHECK: %[[UB:.*]] = ub.poison : i32
// CHECK: return %[[ARG]], %[[ARG]], %[[UB]], %[[ARG]]
func.func @selectOfPoison(%cond : i1, %arg: i32) -> (i32, i32, i32, i32) {
%poison = ub.poison : i32
%select1 = arith.select %cond, %poison, %arg : i32
%select2 = arith.select %cond, %arg, %poison : i32
// Check that constant folding is applied prior to poison handling.
%true = arith.constant true
%false = arith.constant false
%select3 = arith.select %true, %poison, %arg : i32
%select4 = arith.select %false, %poison, %arg : i32
return %select1, %select2, %select3, %select4 : i32, i32, i32, i32
}