21 #define GEN_PASS_DEF_ARITHUNSIGNEDWHENEQUIVALENT
22 #include "mlir/Dialect/Arith/Transforms/Passes.h.inc"
38 if (!result || result->getValue().isUninitialized())
41 return success(range.
smin().isNonNegative());
49 auto nonNegativePred = [&solver](
Value v) ->
bool {
52 return success(llvm::all_of(op->
getOperands(), nonNegativePred) &&
53 llvm::all_of(op->
getResults(), nonNegativePred));
60 CmpIPredicate pred = op.getPredicate();
62 case CmpIPredicate::sle:
63 case CmpIPredicate::slt:
64 case CmpIPredicate::sge:
65 case CmpIPredicate::sgt:
66 return success(llvm::all_of(op.getOperands(), [&solver](
Value v) ->
bool {
67 return succeeded(staticallyNonNegative(solver, v));
78 case CmpIPredicate::sle:
79 return CmpIPredicate::ule;
80 case CmpIPredicate::slt:
81 return CmpIPredicate::ult;
82 case CmpIPredicate::sge:
83 return CmpIPredicate::uge;
84 case CmpIPredicate::sgt:
85 return CmpIPredicate::ugt;
97 void notifyOperationErased(
Operation *op)
override {
106 template <
typename Signed,
typename Un
signed>
111 LogicalResult matchAndRewrite(Signed op,
PatternRewriter &rw)
const override {
129 LogicalResult matchAndRewrite(CmpIOp op,
PatternRewriter &rw)
const override {
134 op.getLhs(), op.getRhs());
142 struct ArithUnsignedWhenEquivalentPass
143 :
public arith::impl::ArithUnsignedWhenEquivalentBase<
144 ArithUnsignedWhenEquivalentPass> {
146 void runOnOperation()
override {
153 return signalPassFailure();
155 DataFlowListener listener(solver);
167 patterns.add<ConvertOpToUnsigned<DivSIOp, DivUIOp>,
168 ConvertOpToUnsigned<CeilDivSIOp, CeilDivUIOp>,
169 ConvertOpToUnsigned<FloorDivSIOp, DivUIOp>,
170 ConvertOpToUnsigned<RemSIOp, RemUIOp>,
171 ConvertOpToUnsigned<MinSIOp, MinUIOp>,
172 ConvertOpToUnsigned<MaxSIOp, MaxUIOp>,
173 ConvertOpToUnsigned<ExtSIOp, ExtUIOp>, ConvertCmpIToUnsigned>(
178 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.
The general data-flow analysis solver.
void eraseState(AnchorT anchor)
Erase any analysis state associated with the given lattice anchor.
const StateT * lookupState(AnchorT anchor) const
Lookup an analysis state for the given lattice anchor.
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.
Operation is the basic unit of execution within MLIR.
MLIRContext * getContext()
Return the context this operation is associated with.
operand_range getOperands()
Returns an iterator on the underlying Value's.
result_range getResults()
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
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.
void populateUnsignedWhenEquivalentPatterns(RewritePatternSet &patterns, DataFlowSolver &solver)
Replace signed ops with unsigned ones where they are proven equivalent.
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.
const FrozenRewritePatternSet & patterns
void walkAndApplyPatterns(Operation *op, const FrozenRewritePatternSet &patterns, RewriterBase::Listener *listener=nullptr)
A fast walk-based pattern rewrite driver.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...