34 matchAndRewrite(CeilDivSOp op, CeilDivSOpAdaptor adaptor,
35 ConversionPatternRewriter &rewriter)
const override {
36 Location loc = op.getLoc();
37 Value n = adaptor.getLhs();
38 Value m = adaptor.getRhs();
39 Value zero = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 0);
40 Value posOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 1);
41 Value negOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), -1);
45 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::sgt, m, zero);
46 Value x = LLVM::SelectOp::create(rewriter, loc, mPos, negOne, posOne);
49 Value nPlusX = LLVM::AddOp::create(rewriter, loc, n, x);
50 Value nPlusXDivM = LLVM::SDivOp::create(rewriter, loc, nPlusX, m);
51 Value posRes = LLVM::AddOp::create(rewriter, loc, nPlusXDivM, posOne);
54 Value negN = LLVM::SubOp::create(rewriter, loc, zero, n);
55 Value negNDivM = LLVM::SDivOp::create(rewriter, loc, negN, m);
56 Value negRes = LLVM::SubOp::create(rewriter, loc, zero, negNDivM);
61 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::sgt, n, zero);
62 Value sameSign = LLVM::ICmpOp::create(rewriter, loc,
63 LLVM::ICmpPredicate::eq, nPos, mPos);
65 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::ne, n, zero);
66 Value cmp = LLVM::AndOp::create(rewriter, loc, sameSign, nNonZero);
67 rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, posRes, negRes);
81 matchAndRewrite(CeilDivUOp op, CeilDivUOpAdaptor adaptor,
82 ConversionPatternRewriter &rewriter)
const override {
83 Location loc = op.getLoc();
84 Value n = adaptor.getLhs();
85 Value m = adaptor.getRhs();
86 Value zero = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 0);
87 Value one = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 1);
90 Value minusOne = LLVM::SubOp::create(rewriter, loc, n, one);
91 Value quotient = LLVM::UDivOp::create(rewriter, loc, minusOne, m);
92 Value plusOne = LLVM::AddOp::create(rewriter, loc, quotient, one);
96 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::eq, n, zero);
97 rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, zero, plusOne);
112 matchAndRewrite(FloorDivSOp op, FloorDivSOpAdaptor adaptor,
113 ConversionPatternRewriter &rewriter)
const override {
114 Location loc = op.getLoc();
115 Value n = adaptor.getLhs();
116 Value m = adaptor.getRhs();
117 Value zero = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 0);
118 Value posOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 1);
119 Value negOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), -1);
123 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::slt, m, zero);
124 Value x = LLVM::SelectOp::create(rewriter, loc, mNeg, posOne, negOne);
127 Value xMinusN = LLVM::SubOp::create(rewriter, loc, x, n);
128 Value xMinusNDivM = LLVM::SDivOp::create(rewriter, loc, xMinusN, m);
129 Value negRes = LLVM::SubOp::create(rewriter, loc, negOne, xMinusNDivM);
132 Value posRes = LLVM::SDivOp::create(rewriter, loc, n, m);
137 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::slt, n, zero);
138 Value diffSign = LLVM::ICmpOp::create(rewriter, loc,
139 LLVM::ICmpPredicate::ne, nNeg, mNeg);
141 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::ne, n, zero);
142 Value cmp = LLVM::AndOp::create(rewriter, loc, diffSign, nNonZero);
143 rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, negRes, posRes);
156template <
typename CastOp,
typename ExtOp>
158 using mlir::ConvertOpToLLVMPattern<CastOp>::ConvertOpToLLVMPattern;
161 matchAndRewrite(CastOp op,
typename CastOp::Adaptor adaptor,
162 ConversionPatternRewriter &rewriter)
const override {
163 Type in = adaptor.getInput().getType();
164 Type out = this->getTypeConverter()->convertType(op.getType());
166 rewriter.replaceOp(op, adaptor.getInput());
168 rewriter.replaceOpWithNewOp<LLVM::TruncOp>(op, out, adaptor.getInput());
170 rewriter.replaceOpWithNewOp<ExtOp>(op, out, adaptor.getInput());
175using ConvertIndexCastS = ConvertIndexCast<CastSOp, LLVM::SExtOp>;
176using ConvertIndexCastU = ConvertIndexCast<CastUOp, LLVM::ZExtOp>;
183static constexpr bool checkPredicates(LLVM::ICmpPredicate
lhs,
184 IndexCmpPredicate
rhs) {
185 return static_cast<int>(
lhs) ==
static_cast<int>(
rhs);
189 LLVM::getMaxEnumValForICmpPredicate() ==
190 getMaxEnumValForIndexCmpPredicate() &&
191 checkPredicates(LLVM::ICmpPredicate::eq, IndexCmpPredicate::EQ) &&
192 checkPredicates(LLVM::ICmpPredicate::ne, IndexCmpPredicate::NE) &&
193 checkPredicates(LLVM::ICmpPredicate::sge, IndexCmpPredicate::SGE) &&
194 checkPredicates(LLVM::ICmpPredicate::sgt, IndexCmpPredicate::SGT) &&
195 checkPredicates(LLVM::ICmpPredicate::sle, IndexCmpPredicate::SLE) &&
196 checkPredicates(LLVM::ICmpPredicate::slt, IndexCmpPredicate::SLT) &&
197 checkPredicates(LLVM::ICmpPredicate::uge, IndexCmpPredicate::UGE) &&
198 checkPredicates(LLVM::ICmpPredicate::ugt, IndexCmpPredicate::UGT) &&
199 checkPredicates(LLVM::ICmpPredicate::ule, IndexCmpPredicate::ULE) &&
200 checkPredicates(LLVM::ICmpPredicate::ult, IndexCmpPredicate::ULT),
201 "LLVM ICmpPredicate mismatches IndexCmpPredicate");
207 matchAndRewrite(CmpOp op, CmpOpAdaptor adaptor,
208 ConversionPatternRewriter &rewriter)
const override {
210 rewriter.replaceOpWithNewOp<LLVM::ICmpOp>(
211 op, *LLVM::symbolizeICmpPredicate(
static_cast<uint32_t
>(op.getPred())),
212 adaptor.getLhs(), adaptor.getRhs());
226 matchAndRewrite(SizeOfOp op, SizeOfOpAdaptor adaptor,
227 ConversionPatternRewriter &rewriter)
const override {
228 rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(
229 op, getTypeConverter()->getIndexType(),
230 getTypeConverter()->getIndexTypeBitwidth());
244 matchAndRewrite(ConstantOp op, ConstantOpAdaptor adaptor,
245 ConversionPatternRewriter &rewriter)
const override {
248 rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(
249 op, type, IntegerAttr::get(type, value));
261using ConvertIndexDivS =
263using ConvertIndexDivU =
265using ConvertIndexRemS =
267using ConvertIndexRemU =
269using ConvertIndexMaxS =
271using ConvertIndexMaxU =
273using ConvertIndexMinS =
275using ConvertIndexMinU =
278using ConvertIndexShrS =
280using ConvertIndexShrU =
285using ConvertIndexBoolConstant =
315 ConvertIndexCeilDivS,
316 ConvertIndexCeilDivU,
317 ConvertIndexFloorDivS,
322 ConvertIndexConstant,
323 ConvertIndexBoolConstant
333#define GEN_PASS_DEF_CONVERTINDEXTOLLVMPASS
334#include "mlir/Conversion/Passes.h.inc"
342struct ConvertIndexToLLVMPass
346 void runOnOperation()
override;
350void ConvertIndexToLLVMPass::runOnOperation() {
353 target.addIllegalDialect<IndexDialect>();
354 target.addLegalDialect<LLVM::LLVMDialect>();
359 options.overrideIndexBitwidth(indexBitwidth);
367 applyPartialConversion(getOperation(),
target, std::move(
patterns))))
368 return signalPassFailure();
377struct IndexToLLVMDialectInterface :
public ConvertToLLVMPatternInterface {
379 void loadDependentDialects(MLIRContext *context)
const final {
380 context->loadDialect<LLVM::LLVMDialect>();
385 void populateConvertToLLVMConversionPatterns(
386 ConversionTarget &
target, LLVMTypeConverter &typeConverter,
387 RewritePatternSet &
patterns)
const final {
396 dialect->addInterfaces<IndexToLLVMDialectInterface>();
static llvm::ManagedStatic< PassManagerOptions > options
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
ConvertOpToLLVMPattern(const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
ConvertToLLVMPatternInterface(Dialect *dialect)
Type getIndexType() const
Gets the MLIR type wrapping the LLVM integer type whose bit width is defined by the used type convert...
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
Conversion from types to the LLVM IR dialect.
MLIRContext is the top-level object for a collection of MLIR operations.
Generic implementation of one-to-one conversion from "SourceOp" to "TargetOp" where the latter belong...
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
Type getType() const
Return the type of this value.
void populateIndexToLLVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns)
void registerConvertIndexToLLVMInterface(DialectRegistry ®istry)
Include the generated interface declarations.
static constexpr unsigned kDeriveIndexBitwidthFromDataLayout
Value to pass as bitwidth for the index type when the converter is expected to derive the bitwidth fr...
const FrozenRewritePatternSet & patterns