20 #define GEN_PASS_DEF_ARITHUNSIGNEDWHENEQUIVALENT
21 #include "mlir/Dialect/Arith/Transforms/Passes.h.inc"
34 if (!result || result->getValue().isUninitialized())
37 return success(range.
smin().isNonNegative());
45 auto nonNegativePred = [&solver](
Value v) ->
bool {
48 return success(llvm::all_of(op->
getOperands(), nonNegativePred) &&
49 llvm::all_of(op->
getResults(), nonNegativePred));
56 CmpIPredicate pred = op.getPredicate();
58 case CmpIPredicate::sle:
59 case CmpIPredicate::slt:
60 case CmpIPredicate::sge:
61 case CmpIPredicate::sgt:
63 return succeeded(staticallyNonNegative(solver, v));
74 case CmpIPredicate::sle:
75 return CmpIPredicate::ule;
76 case CmpIPredicate::slt:
77 return CmpIPredicate::ult;
78 case CmpIPredicate::sge:
79 return CmpIPredicate::uge;
80 case CmpIPredicate::sgt:
81 return CmpIPredicate::ugt;
88 template <
typename Signed,
typename Un
signed>
92 LogicalResult matchAndRewrite(Signed op,
typename Signed::Adaptor adaptor,
95 adaptor.getOperands(), op->
getAttrs());
103 LogicalResult matchAndRewrite(CmpIOp op, CmpIOpAdaptor adaptor,
106 op.getLhs(), op.getRhs());
111 struct ArithUnsignedWhenEquivalentPass
112 :
public arith::impl::ArithUnsignedWhenEquivalentBase<
113 ArithUnsignedWhenEquivalentPass> {
117 void runOnOperation()
override {
124 return signalPassFailure();
127 target.addLegalDialect<ArithDialect>();
128 target.addDynamicallyLegalOp<DivSIOp, CeilDivSIOp, FloorDivSIOp, RemSIOp,
129 MinSIOp, MaxSIOp, ExtSIOp>(
130 [&solver](
Operation *op) -> std::optional<bool> {
133 target.addDynamicallyLegalOp<CmpIOp>(
134 [&solver](CmpIOp op) -> std::optional<bool> {
139 patterns.add<ConvertOpToUnsigned<DivSIOp, DivUIOp>,
140 ConvertOpToUnsigned<CeilDivSIOp, CeilDivUIOp>,
141 ConvertOpToUnsigned<FloorDivSIOp, DivUIOp>,
142 ConvertOpToUnsigned<RemSIOp, RemUIOp>,
143 ConvertOpToUnsigned<MinSIOp, MinUIOp>,
144 ConvertOpToUnsigned<MaxSIOp, MaxUIOp>,
145 ConvertOpToUnsigned<ExtSIOp, ExtUIOp>, ConvertCmpIToUnsigned>(
156 return std::make_unique<ArithUnsignedWhenEquivalentPass>();
static LogicalResult staticallyNonNegative(DataFlowSolver &solver, Value v)
Succeeds when a value is statically non-negative in that it has a lower bound on its value (if it is ...
static CmpIPredicate toUnsignedPred(CmpIPredicate pred)
Return the unsigned equivalent of a signed comparison predicate, or the predicate itself if there is ...
static LogicalResult isCmpIConvertable(DataFlowSolver &solver, CmpIOp op)
Succeeds when the comparison predicate is a signed operation and all the operands are non-negative,...
A set of arbitrary-precision integers representing bounds on a given integer value.
const APInt & smin() const
The minimum value of an integer when it is interpreted as signed.
This class implements a pattern rewriter for use with ConversionPatterns.
This class describes a specific conversion target.
The general data-flow analysis solver.
const StateT * lookupState(PointT point) const
Lookup an analysis state for the given program point.
AnalysisT * load(Args &&...args)
Load an analysis into the solver. Return the analysis instance.
LogicalResult initializeAndRun(Operation *top)
Initialize the children analyses starting from the provided top-level operation and run the analysis ...
MLIRContext is the top-level object for a collection of MLIR operations.
OpConversionPattern is a wrapper around ConversionPattern that allows for matching and rewriting agai...
Operation is the basic unit of execution within MLIR.
MLIRContext * getContext()
Return the context this operation is associated with.
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
result_type_range getResultTypes()
operand_range getOperands()
Returns an iterator on the underlying Value's.
result_range getResults()
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Dead code analysis analyzes control-flow, as understood by RegionBranchOpInterface and BranchOpInterf...
Integer range analysis determines the integer value range of SSA values using operations that define ...
This lattice element represents the integer value range of an SSA value.
std::unique_ptr< Pass > createArithUnsignedWhenEquivalentPass()
Create a pass to replace signed ops with unsigned ones where they are proven equivalent.
Include the generated interface declarations.
LogicalResult applyPartialConversion(ArrayRef< Operation * > ops, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config=ConversionConfig())
Below we define several entry points for operation conversion.