20 #define GEN_PASS_DEF_ARITHUNSIGNEDWHENEQUIVALENT
21 #include "mlir/Dialect/Arith/Transforms/Passes.h.inc"
34 if (!result || result->getValue().isUninitialized())
45 auto nonNegativePred = [&solver](
Value v) ->
bool {
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>();
129 .addDynamicallyLegalOp<DivSIOp, CeilDivSIOp, CeilDivUIOp, FloorDivSIOp,
130 RemSIOp, MinSIOp, MaxSIOp, ExtSIOp>(
131 [&solver](
Operation *op) -> std::optional<bool> {
134 target.addDynamicallyLegalOp<CmpIOp>(
135 [&solver](CmpIOp op) -> std::optional<bool> {
140 patterns.add<ConvertOpToUnsigned<DivSIOp, DivUIOp>,
141 ConvertOpToUnsigned<CeilDivSIOp, CeilDivUIOp>,
142 ConvertOpToUnsigned<FloorDivSIOp, DivUIOp>,
143 ConvertOpToUnsigned<RemSIOp, RemUIOp>,
144 ConvertOpToUnsigned<MinSIOp, MinUIOp>,
145 ConvertOpToUnsigned<MaxSIOp, MaxUIOp>,
146 ConvertOpToUnsigned<ExtSIOp, ExtUIOp>, ConvertCmpIToUnsigned>(
157 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)
Replaces the result op with a new op that is created without verification.
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.
This header declares functions that assist transformations in the MemRef dialect.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
LogicalResult applyPartialConversion(ArrayRef< Operation * > ops, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, DenseSet< Operation * > *unconvertedOps=nullptr)
Below we define several entry points for operation conversion.
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.