35 matchAndRewrite(CeilDivSOp op, CeilDivSOpAdaptor adaptor,
36 ConversionPatternRewriter &rewriter)
const override {
37 Location loc = op.getLoc();
38 Value n = adaptor.getLhs();
39 Value m = adaptor.getRhs();
40 Value zero = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 0);
41 Value posOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 1);
42 Value negOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), -1);
46 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::sgt, m, zero);
47 Value x = LLVM::SelectOp::create(rewriter, loc, mPos, negOne, posOne);
50 Value nPlusX = LLVM::AddOp::create(rewriter, loc, n, x);
51 Value nPlusXDivM = LLVM::SDivOp::create(rewriter, loc, nPlusX, m);
52 Value posRes = LLVM::AddOp::create(rewriter, loc, nPlusXDivM, posOne);
55 Value negN = LLVM::SubOp::create(rewriter, loc, zero, n);
56 Value negNDivM = LLVM::SDivOp::create(rewriter, loc, negN, m);
57 Value negRes = LLVM::SubOp::create(rewriter, loc, zero, negNDivM);
62 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::sgt, n, zero);
63 Value sameSign = LLVM::ICmpOp::create(rewriter, loc,
64 LLVM::ICmpPredicate::eq, nPos, mPos);
66 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::ne, n, zero);
67 Value cmp = LLVM::AndOp::create(rewriter, loc, sameSign, nNonZero);
68 rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, posRes, negRes);
82 matchAndRewrite(CeilDivUOp op, CeilDivUOpAdaptor adaptor,
83 ConversionPatternRewriter &rewriter)
const override {
84 Location loc = op.getLoc();
85 Value n = adaptor.getLhs();
86 Value m = adaptor.getRhs();
87 Value zero = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 0);
88 Value one = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 1);
91 Value minusOne = LLVM::SubOp::create(rewriter, loc, n, one);
92 Value quotient = LLVM::UDivOp::create(rewriter, loc, minusOne, m);
93 Value plusOne = LLVM::AddOp::create(rewriter, loc, quotient, one);
97 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::eq, n, zero);
98 rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, zero, plusOne);
113 matchAndRewrite(FloorDivSOp op, FloorDivSOpAdaptor adaptor,
114 ConversionPatternRewriter &rewriter)
const override {
115 Location loc = op.getLoc();
116 Value n = adaptor.getLhs();
117 Value m = adaptor.getRhs();
118 Value zero = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 0);
119 Value posOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), 1);
120 Value negOne = LLVM::ConstantOp::create(rewriter, loc, n.
getType(), -1);
124 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::slt, m, zero);
125 Value x = LLVM::SelectOp::create(rewriter, loc, mNeg, posOne, negOne);
128 Value xMinusN = LLVM::SubOp::create(rewriter, loc, x, n);
129 Value xMinusNDivM = LLVM::SDivOp::create(rewriter, loc, xMinusN, m);
130 Value negRes = LLVM::SubOp::create(rewriter, loc, negOne, xMinusNDivM);
133 Value posRes = LLVM::SDivOp::create(rewriter, loc, n, m);
138 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::slt, n, zero);
139 Value diffSign = LLVM::ICmpOp::create(rewriter, loc,
140 LLVM::ICmpPredicate::ne, nNeg, mNeg);
142 LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::ne, n, zero);
143 Value cmp = LLVM::AndOp::create(rewriter, loc, diffSign, nNonZero);
144 rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, negRes, posRes);
157template <
typename CastOp,
typename ExtOp>
159 using mlir::ConvertOpToLLVMPattern<CastOp>::ConvertOpToLLVMPattern;
162 matchAndRewrite(CastOp op,
typename CastOp::Adaptor adaptor,
163 ConversionPatternRewriter &rewriter)
const override {
164 Type in = adaptor.getInput().getType();
165 Type out = this->getTypeConverter()->convertType(op.getType());
167 rewriter.replaceOp(op, adaptor.getInput());
169 rewriter.replaceOpWithNewOp<LLVM::TruncOp>(op, out, adaptor.getInput());
171 rewriter.replaceOpWithNewOp<ExtOp>(op, out, adaptor.getInput());
176using ConvertIndexCastS = ConvertIndexCast<CastSOp, LLVM::SExtOp>;
177using ConvertIndexCastU = ConvertIndexCast<CastUOp, LLVM::ZExtOp>;
184static constexpr bool checkPredicates(LLVM::ICmpPredicate lhs,
185 IndexCmpPredicate rhs) {
186 return static_cast<int>(lhs) ==
static_cast<int>(rhs);
190 LLVM::getMaxEnumValForICmpPredicate() ==
191 getMaxEnumValForIndexCmpPredicate() &&
192 checkPredicates(LLVM::ICmpPredicate::eq, IndexCmpPredicate::EQ) &&
193 checkPredicates(LLVM::ICmpPredicate::ne, IndexCmpPredicate::NE) &&
194 checkPredicates(LLVM::ICmpPredicate::sge, IndexCmpPredicate::SGE) &&
195 checkPredicates(LLVM::ICmpPredicate::sgt, IndexCmpPredicate::SGT) &&
196 checkPredicates(LLVM::ICmpPredicate::sle, IndexCmpPredicate::SLE) &&
197 checkPredicates(LLVM::ICmpPredicate::slt, IndexCmpPredicate::SLT) &&
198 checkPredicates(LLVM::ICmpPredicate::uge, IndexCmpPredicate::UGE) &&
199 checkPredicates(LLVM::ICmpPredicate::ugt, IndexCmpPredicate::UGT) &&
200 checkPredicates(LLVM::ICmpPredicate::ule, IndexCmpPredicate::ULE) &&
201 checkPredicates(LLVM::ICmpPredicate::ult, IndexCmpPredicate::ULT),
202 "LLVM ICmpPredicate mismatches IndexCmpPredicate");
208 matchAndRewrite(CmpOp op, CmpOpAdaptor adaptor,
209 ConversionPatternRewriter &rewriter)
const override {
211 rewriter.replaceOpWithNewOp<LLVM::ICmpOp>(
212 op, *LLVM::symbolizeICmpPredicate(
static_cast<uint32_t
>(op.getPred())),
213 adaptor.getLhs(), adaptor.getRhs());
227 matchAndRewrite(SizeOfOp op, SizeOfOpAdaptor adaptor,
228 ConversionPatternRewriter &rewriter)
const override {
229 rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(
230 op, getTypeConverter()->getIndexType(),
231 getTypeConverter()->getIndexTypeBitwidth());
245 matchAndRewrite(ConstantOp op, ConstantOpAdaptor adaptor,
246 ConversionPatternRewriter &rewriter)
const override {
249 rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(
250 op, type, IntegerAttr::get(type, value));
262using ConvertIndexDivS =
264using ConvertIndexDivU =
266using ConvertIndexRemS =
268using ConvertIndexRemU =
270using ConvertIndexMaxS =
272using ConvertIndexMaxU =
274using ConvertIndexMinS =
276using ConvertIndexMinU =
279using ConvertIndexShrS =
281using ConvertIndexShrU =
286using ConvertIndexBoolConstant =
316 ConvertIndexCeilDivS,
317 ConvertIndexCeilDivU,
318 ConvertIndexFloorDivS,
323 ConvertIndexConstant,
324 ConvertIndexBoolConstant
334#define GEN_PASS_DEF_CONVERTINDEXTOLLVMPASS
335#include "mlir/Conversion/Passes.h.inc"
343struct ConvertIndexToLLVMPass
347 void runOnOperation()
override;
351void ConvertIndexToLLVMPass::runOnOperation() {
354 target.addIllegalDialect<IndexDialect>();
355 target.addLegalDialect<LLVM::LLVMDialect>();
358 const auto &dataLayoutAnalysis = getAnalysis<DataLayoutAnalysis>();
360 dataLayoutAnalysis.getAtOrAbove(getOperation()));
362 options.overrideIndexBitwidth(indexBitwidth);
370 applyPartialConversion(getOperation(),
target, std::move(patterns))))
371 return signalPassFailure();
380struct IndexToLLVMDialectInterface :
public ConvertToLLVMPatternInterface {
381 IndexToLLVMDialectInterface(Dialect *dialect)
382 : ConvertToLLVMPatternInterface(dialect) {}
384 void loadDependentDialects(MLIRContext *context)
const final {
385 context->loadDialect<LLVM::LLVMDialect>();
390 void populateConvertToLLVMConversionPatterns(
391 ConversionTarget &
target, LLVMTypeConverter &typeConverter,
392 RewritePatternSet &patterns)
const final {
401 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)
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...
RewritePatternSet & insert(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
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...