xref: /llvm-project/mlir/lib/Conversion/IndexToLLVM/IndexToLLVM.cpp (revision 206fad0e218e83799e49ca15545d997c6c5e8a03)
1cae746d9SJeff Niu //===- IndexToLLVM.cpp - Index to LLVM dialect conversion -------*- C++ -*-===//
2cae746d9SJeff Niu //
3cae746d9SJeff Niu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cae746d9SJeff Niu // See https://llvm.org/LICENSE.txt for license information.
5cae746d9SJeff Niu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cae746d9SJeff Niu //
7cae746d9SJeff Niu //===----------------------------------------------------------------------===//
8cae746d9SJeff Niu 
9cae746d9SJeff Niu #include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h"
10bfdc4723SMatthias Springer 
11bfdc4723SMatthias Springer #include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
12cae746d9SJeff Niu #include "mlir/Conversion/LLVMCommon/Pattern.h"
13cae746d9SJeff Niu #include "mlir/Dialect/Index/IR/IndexAttrs.h"
14cae746d9SJeff Niu #include "mlir/Dialect/Index/IR/IndexDialect.h"
15cae746d9SJeff Niu #include "mlir/Dialect/Index/IR/IndexOps.h"
16cae746d9SJeff Niu #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
17cae746d9SJeff Niu #include "mlir/Pass/Pass.h"
18cae746d9SJeff Niu 
19cae746d9SJeff Niu using namespace mlir;
20cae746d9SJeff Niu using namespace index;
21cae746d9SJeff Niu 
22cae746d9SJeff Niu namespace {
23cae746d9SJeff Niu 
24cae746d9SJeff Niu //===----------------------------------------------------------------------===//
25cae746d9SJeff Niu // ConvertIndexCeilDivS
26cae746d9SJeff Niu //===----------------------------------------------------------------------===//
27cae746d9SJeff Niu 
28cae746d9SJeff Niu /// Convert `ceildivs(n, m)` into `x = m > 0 ? -1 : 1` and then
29cae746d9SJeff Niu /// `n*m > 0 ? (n+x)/m + 1 : -(-n/m)`.
30cae746d9SJeff Niu struct ConvertIndexCeilDivS : mlir::ConvertOpToLLVMPattern<CeilDivSOp> {
31cae746d9SJeff Niu   using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
32cae746d9SJeff Niu 
33cae746d9SJeff Niu   LogicalResult
34cae746d9SJeff Niu   matchAndRewrite(CeilDivSOp op, CeilDivSOpAdaptor adaptor,
35cae746d9SJeff Niu                   ConversionPatternRewriter &rewriter) const override {
36cae746d9SJeff Niu     Location loc = op.getLoc();
37cae746d9SJeff Niu     Value n = adaptor.getLhs();
38cae746d9SJeff Niu     Value m = adaptor.getRhs();
39cae746d9SJeff Niu     Value zero = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 0);
40cae746d9SJeff Niu     Value posOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 1);
41cae746d9SJeff Niu     Value negOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), -1);
42cae746d9SJeff Niu 
43cae746d9SJeff Niu     // Compute `x`.
44cae746d9SJeff Niu     Value mPos =
45cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::sgt, m, zero);
46cae746d9SJeff Niu     Value x = rewriter.create<LLVM::SelectOp>(loc, mPos, negOne, posOne);
47cae746d9SJeff Niu 
48cae746d9SJeff Niu     // Compute the positive result.
49cae746d9SJeff Niu     Value nPlusX = rewriter.create<LLVM::AddOp>(loc, n, x);
50cae746d9SJeff Niu     Value nPlusXDivM = rewriter.create<LLVM::SDivOp>(loc, nPlusX, m);
51cae746d9SJeff Niu     Value posRes = rewriter.create<LLVM::AddOp>(loc, nPlusXDivM, posOne);
52cae746d9SJeff Niu 
53cae746d9SJeff Niu     // Compute the negative result.
54cae746d9SJeff Niu     Value negN = rewriter.create<LLVM::SubOp>(loc, zero, n);
55cae746d9SJeff Niu     Value negNDivM = rewriter.create<LLVM::SDivOp>(loc, negN, m);
56cae746d9SJeff Niu     Value negRes = rewriter.create<LLVM::SubOp>(loc, zero, negNDivM);
57cae746d9SJeff Niu 
58cae746d9SJeff Niu     // Pick the positive result if `n` and `m` have the same sign and `n` is
59cae746d9SJeff Niu     // non-zero, i.e. `(n > 0) == (m > 0) && n != 0`.
60cae746d9SJeff Niu     Value nPos =
61cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::sgt, n, zero);
62cae746d9SJeff Niu     Value sameSign =
63cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::eq, nPos, mPos);
64cae746d9SJeff Niu     Value nNonZero =
65cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::ne, n, zero);
66cae746d9SJeff Niu     Value cmp = rewriter.create<LLVM::AndOp>(loc, sameSign, nNonZero);
67cae746d9SJeff Niu     rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, posRes, negRes);
68cae746d9SJeff Niu     return success();
69cae746d9SJeff Niu   }
70cae746d9SJeff Niu };
71cae746d9SJeff Niu 
72cae746d9SJeff Niu //===----------------------------------------------------------------------===//
73cae746d9SJeff Niu // ConvertIndexCeilDivU
74cae746d9SJeff Niu //===----------------------------------------------------------------------===//
75cae746d9SJeff Niu 
76cae746d9SJeff Niu /// Convert `ceildivu(n, m)` into `n == 0 ? 0 : (n-1)/m + 1`.
77cae746d9SJeff Niu struct ConvertIndexCeilDivU : mlir::ConvertOpToLLVMPattern<CeilDivUOp> {
78cae746d9SJeff Niu   using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
79cae746d9SJeff Niu 
80cae746d9SJeff Niu   LogicalResult
81cae746d9SJeff Niu   matchAndRewrite(CeilDivUOp op, CeilDivUOpAdaptor adaptor,
82cae746d9SJeff Niu                   ConversionPatternRewriter &rewriter) const override {
83cae746d9SJeff Niu     Location loc = op.getLoc();
84cae746d9SJeff Niu     Value n = adaptor.getLhs();
85cae746d9SJeff Niu     Value m = adaptor.getRhs();
86cae746d9SJeff Niu     Value zero = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 0);
87cae746d9SJeff Niu     Value one = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 1);
88cae746d9SJeff Niu 
89cae746d9SJeff Niu     // Compute the non-zero result.
90cae746d9SJeff Niu     Value minusOne = rewriter.create<LLVM::SubOp>(loc, n, one);
91cae746d9SJeff Niu     Value quotient = rewriter.create<LLVM::UDivOp>(loc, minusOne, m);
92cae746d9SJeff Niu     Value plusOne = rewriter.create<LLVM::AddOp>(loc, quotient, one);
93cae746d9SJeff Niu 
94cae746d9SJeff Niu     // Pick the result.
95cae746d9SJeff Niu     Value cmp =
96cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::eq, n, zero);
97cae746d9SJeff Niu     rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, zero, plusOne);
98cae746d9SJeff Niu     return success();
99cae746d9SJeff Niu   }
100cae746d9SJeff Niu };
101cae746d9SJeff Niu 
102cae746d9SJeff Niu //===----------------------------------------------------------------------===//
103cae746d9SJeff Niu // ConvertIndexFloorDivS
104cae746d9SJeff Niu //===----------------------------------------------------------------------===//
105cae746d9SJeff Niu 
106cae746d9SJeff Niu /// Convert `floordivs(n, m)` into `x = m < 0 ? 1 : -1` and then
107cae746d9SJeff Niu /// `n*m < 0 ? -1 - (x-n)/m : n/m`.
108cae746d9SJeff Niu struct ConvertIndexFloorDivS : mlir::ConvertOpToLLVMPattern<FloorDivSOp> {
109cae746d9SJeff Niu   using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
110cae746d9SJeff Niu 
111cae746d9SJeff Niu   LogicalResult
112cae746d9SJeff Niu   matchAndRewrite(FloorDivSOp op, FloorDivSOpAdaptor adaptor,
113cae746d9SJeff Niu                   ConversionPatternRewriter &rewriter) const override {
114cae746d9SJeff Niu     Location loc = op.getLoc();
115cae746d9SJeff Niu     Value n = adaptor.getLhs();
116cae746d9SJeff Niu     Value m = adaptor.getRhs();
117cae746d9SJeff Niu     Value zero = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 0);
118cae746d9SJeff Niu     Value posOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), 1);
119cae746d9SJeff Niu     Value negOne = rewriter.create<LLVM::ConstantOp>(loc, n.getType(), -1);
120cae746d9SJeff Niu 
121cae746d9SJeff Niu     // Compute `x`.
122cae746d9SJeff Niu     Value mNeg =
123cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::slt, m, zero);
124cae746d9SJeff Niu     Value x = rewriter.create<LLVM::SelectOp>(loc, mNeg, posOne, negOne);
125cae746d9SJeff Niu 
126cae746d9SJeff Niu     // Compute the negative result.
127cae746d9SJeff Niu     Value xMinusN = rewriter.create<LLVM::SubOp>(loc, x, n);
128cae746d9SJeff Niu     Value xMinusNDivM = rewriter.create<LLVM::SDivOp>(loc, xMinusN, m);
129cae746d9SJeff Niu     Value negRes = rewriter.create<LLVM::SubOp>(loc, negOne, xMinusNDivM);
130cae746d9SJeff Niu 
131cae746d9SJeff Niu     // Compute the positive result.
132cae746d9SJeff Niu     Value posRes = rewriter.create<LLVM::SDivOp>(loc, n, m);
133cae746d9SJeff Niu 
134cae746d9SJeff Niu     // Pick the negative result if `n` and `m` have different signs and `n` is
135cae746d9SJeff Niu     // non-zero, i.e. `(n < 0) != (m < 0) && n != 0`.
136cae746d9SJeff Niu     Value nNeg =
137cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::slt, n, zero);
138cae746d9SJeff Niu     Value diffSign =
139cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::ne, nNeg, mNeg);
140cae746d9SJeff Niu     Value nNonZero =
141cae746d9SJeff Niu         rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::ne, n, zero);
142cae746d9SJeff Niu     Value cmp = rewriter.create<LLVM::AndOp>(loc, diffSign, nNonZero);
143cae746d9SJeff Niu     rewriter.replaceOpWithNewOp<LLVM::SelectOp>(op, cmp, negRes, posRes);
144cae746d9SJeff Niu     return success();
145cae746d9SJeff Niu   }
146cae746d9SJeff Niu };
147cae746d9SJeff Niu 
148cae746d9SJeff Niu //===----------------------------------------------------------------------===//
149cae746d9SJeff Niu // CovnertIndexCast
150cae746d9SJeff Niu //===----------------------------------------------------------------------===//
151cae746d9SJeff Niu 
152cae746d9SJeff Niu /// Convert a cast op. If the materialized index type is the same as the other
153cae746d9SJeff Niu /// type, fold away the op. Otherwise, truncate or extend the op as appropriate.
154cae746d9SJeff Niu /// Signed casts sign extend when the result bitwidth is larger. Unsigned casts
155cae746d9SJeff Niu /// zero extend when the result bitwidth is larger.
156cae746d9SJeff Niu template <typename CastOp, typename ExtOp>
157cae746d9SJeff Niu struct ConvertIndexCast : public mlir::ConvertOpToLLVMPattern<CastOp> {
158cae746d9SJeff Niu   using mlir::ConvertOpToLLVMPattern<CastOp>::ConvertOpToLLVMPattern;
159cae746d9SJeff Niu 
160cae746d9SJeff Niu   LogicalResult
161cae746d9SJeff Niu   matchAndRewrite(CastOp op, typename CastOp::Adaptor adaptor,
162cae746d9SJeff Niu                   ConversionPatternRewriter &rewriter) const override {
163cae746d9SJeff Niu     Type in = adaptor.getInput().getType();
164cae746d9SJeff Niu     Type out = this->getTypeConverter()->convertType(op.getType());
165cae746d9SJeff Niu     if (in == out)
166cae746d9SJeff Niu       rewriter.replaceOp(op, adaptor.getInput());
167cae746d9SJeff Niu     else if (in.getIntOrFloatBitWidth() > out.getIntOrFloatBitWidth())
168cae746d9SJeff Niu       rewriter.replaceOpWithNewOp<LLVM::TruncOp>(op, out, adaptor.getInput());
169cae746d9SJeff Niu     else
170cae746d9SJeff Niu       rewriter.replaceOpWithNewOp<ExtOp>(op, out, adaptor.getInput());
171cae746d9SJeff Niu     return success();
172cae746d9SJeff Niu   }
173cae746d9SJeff Niu };
174cae746d9SJeff Niu 
175cae746d9SJeff Niu using ConvertIndexCastS = ConvertIndexCast<CastSOp, LLVM::SExtOp>;
176cae746d9SJeff Niu using ConvertIndexCastU = ConvertIndexCast<CastUOp, LLVM::ZExtOp>;
177cae746d9SJeff Niu 
178cae746d9SJeff Niu //===----------------------------------------------------------------------===//
179cae746d9SJeff Niu // ConvertIndexCmp
180cae746d9SJeff Niu //===----------------------------------------------------------------------===//
181cae746d9SJeff Niu 
182cae746d9SJeff Niu /// Assert that the LLVM comparison enum lines up with index's enum.
183cae746d9SJeff Niu static constexpr bool checkPredicates(LLVM::ICmpPredicate lhs,
184cae746d9SJeff Niu                                       IndexCmpPredicate rhs) {
185cae746d9SJeff Niu   return static_cast<int>(lhs) == static_cast<int>(rhs);
186cae746d9SJeff Niu }
187cae746d9SJeff Niu 
188cae746d9SJeff Niu static_assert(
189cae746d9SJeff Niu     LLVM::getMaxEnumValForICmpPredicate() ==
190cae746d9SJeff Niu             getMaxEnumValForIndexCmpPredicate() &&
191cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::eq, IndexCmpPredicate::EQ) &&
192cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::ne, IndexCmpPredicate::NE) &&
193cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::sge, IndexCmpPredicate::SGE) &&
194cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::sgt, IndexCmpPredicate::SGT) &&
195cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::sle, IndexCmpPredicate::SLE) &&
196cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::slt, IndexCmpPredicate::SLT) &&
197cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::uge, IndexCmpPredicate::UGE) &&
198cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::ugt, IndexCmpPredicate::UGT) &&
199cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::ule, IndexCmpPredicate::ULE) &&
200cae746d9SJeff Niu         checkPredicates(LLVM::ICmpPredicate::ult, IndexCmpPredicate::ULT),
201cae746d9SJeff Niu     "LLVM ICmpPredicate mismatches IndexCmpPredicate");
202cae746d9SJeff Niu 
203cae746d9SJeff Niu struct ConvertIndexCmp : public mlir::ConvertOpToLLVMPattern<CmpOp> {
204cae746d9SJeff Niu   using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
205cae746d9SJeff Niu 
206cae746d9SJeff Niu   LogicalResult
207cae746d9SJeff Niu   matchAndRewrite(CmpOp op, CmpOpAdaptor adaptor,
208cae746d9SJeff Niu                   ConversionPatternRewriter &rewriter) const override {
209cae746d9SJeff Niu     // The LLVM enum has the same values as the index predicate enums.
210cae746d9SJeff Niu     rewriter.replaceOpWithNewOp<LLVM::ICmpOp>(
211cae746d9SJeff Niu         op, *LLVM::symbolizeICmpPredicate(static_cast<uint32_t>(op.getPred())),
212cae746d9SJeff Niu         adaptor.getLhs(), adaptor.getRhs());
213cae746d9SJeff Niu     return success();
214cae746d9SJeff Niu   }
215cae746d9SJeff Niu };
216cae746d9SJeff Niu 
217cae746d9SJeff Niu //===----------------------------------------------------------------------===//
218cae746d9SJeff Niu // ConvertIndexSizeOf
219cae746d9SJeff Niu //===----------------------------------------------------------------------===//
220cae746d9SJeff Niu 
221cae746d9SJeff Niu /// Lower `index.sizeof` to a constant with the value of the index bitwidth.
222cae746d9SJeff Niu struct ConvertIndexSizeOf : public mlir::ConvertOpToLLVMPattern<SizeOfOp> {
223cae746d9SJeff Niu   using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
224cae746d9SJeff Niu 
225cae746d9SJeff Niu   LogicalResult
226cae746d9SJeff Niu   matchAndRewrite(SizeOfOp op, SizeOfOpAdaptor adaptor,
227cae746d9SJeff Niu                   ConversionPatternRewriter &rewriter) const override {
228cae746d9SJeff Niu     rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(
229cae746d9SJeff Niu         op, getTypeConverter()->getIndexType(),
230cae746d9SJeff Niu         getTypeConverter()->getIndexTypeBitwidth());
231cae746d9SJeff Niu     return success();
232cae746d9SJeff Niu   }
233cae746d9SJeff Niu };
234cae746d9SJeff Niu 
235cae746d9SJeff Niu //===----------------------------------------------------------------------===//
236cae746d9SJeff Niu // ConvertIndexConstant
237cae746d9SJeff Niu //===----------------------------------------------------------------------===//
238cae746d9SJeff Niu 
239cae746d9SJeff Niu /// Convert an index constant. Truncate the value as appropriate.
240cae746d9SJeff Niu struct ConvertIndexConstant : public mlir::ConvertOpToLLVMPattern<ConstantOp> {
241cae746d9SJeff Niu   using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern;
242cae746d9SJeff Niu 
243cae746d9SJeff Niu   LogicalResult
244cae746d9SJeff Niu   matchAndRewrite(ConstantOp op, ConstantOpAdaptor adaptor,
245cae746d9SJeff Niu                   ConversionPatternRewriter &rewriter) const override {
246cae746d9SJeff Niu     Type type = getTypeConverter()->getIndexType();
247cae746d9SJeff Niu     APInt value = op.getValue().trunc(type.getIntOrFloatBitWidth());
248cae746d9SJeff Niu     rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(
249cae746d9SJeff Niu         op, type, IntegerAttr::get(type, value));
250cae746d9SJeff Niu     return success();
251cae746d9SJeff Niu   }
252cae746d9SJeff Niu };
253cae746d9SJeff Niu 
254cae746d9SJeff Niu //===----------------------------------------------------------------------===//
255cae746d9SJeff Niu // Trivial Conversions
256cae746d9SJeff Niu //===----------------------------------------------------------------------===//
257cae746d9SJeff Niu 
258cae746d9SJeff Niu using ConvertIndexAdd = mlir::OneToOneConvertToLLVMPattern<AddOp, LLVM::AddOp>;
259cae746d9SJeff Niu using ConvertIndexSub = mlir::OneToOneConvertToLLVMPattern<SubOp, LLVM::SubOp>;
260cae746d9SJeff Niu using ConvertIndexMul = mlir::OneToOneConvertToLLVMPattern<MulOp, LLVM::MulOp>;
261cae746d9SJeff Niu using ConvertIndexDivS =
262cae746d9SJeff Niu     mlir::OneToOneConvertToLLVMPattern<DivSOp, LLVM::SDivOp>;
263cae746d9SJeff Niu using ConvertIndexDivU =
264cae746d9SJeff Niu     mlir::OneToOneConvertToLLVMPattern<DivUOp, LLVM::UDivOp>;
265cae746d9SJeff Niu using ConvertIndexRemS =
266cae746d9SJeff Niu     mlir::OneToOneConvertToLLVMPattern<RemSOp, LLVM::SRemOp>;
267cae746d9SJeff Niu using ConvertIndexRemU =
268cae746d9SJeff Niu     mlir::OneToOneConvertToLLVMPattern<RemUOp, LLVM::URemOp>;
269cae746d9SJeff Niu using ConvertIndexMaxS =
270cae746d9SJeff Niu     mlir::OneToOneConvertToLLVMPattern<MaxSOp, LLVM::SMaxOp>;
271cae746d9SJeff Niu using ConvertIndexMaxU =
272cae746d9SJeff Niu     mlir::OneToOneConvertToLLVMPattern<MaxUOp, LLVM::UMaxOp>;
2738cdb4f9fSKrzysztof Drewniak using ConvertIndexMinS =
2748cdb4f9fSKrzysztof Drewniak     mlir::OneToOneConvertToLLVMPattern<MinSOp, LLVM::SMinOp>;
2758cdb4f9fSKrzysztof Drewniak using ConvertIndexMinU =
2768cdb4f9fSKrzysztof Drewniak     mlir::OneToOneConvertToLLVMPattern<MinUOp, LLVM::UMinOp>;
2779ef31465SJeff Niu using ConvertIndexShl = mlir::OneToOneConvertToLLVMPattern<ShlOp, LLVM::ShlOp>;
2789ef31465SJeff Niu using ConvertIndexShrS =
2799ef31465SJeff Niu     mlir::OneToOneConvertToLLVMPattern<ShrSOp, LLVM::AShrOp>;
2809ef31465SJeff Niu using ConvertIndexShrU =
2819ef31465SJeff Niu     mlir::OneToOneConvertToLLVMPattern<ShrUOp, LLVM::LShrOp>;
2824f9c9295SLuca Boasso using ConvertIndexAnd = mlir::OneToOneConvertToLLVMPattern<AndOp, LLVM::AndOp>;
2834f9c9295SLuca Boasso using ConvertIndexOr = mlir::OneToOneConvertToLLVMPattern<OrOp, LLVM::OrOp>;
2844f9c9295SLuca Boasso using ConvertIndexXor = mlir::OneToOneConvertToLLVMPattern<XOrOp, LLVM::XOrOp>;
285cae746d9SJeff Niu using ConvertIndexBoolConstant =
286cae746d9SJeff Niu     mlir::OneToOneConvertToLLVMPattern<BoolConstantOp, LLVM::ConstantOp>;
287cae746d9SJeff Niu 
288cae746d9SJeff Niu } // namespace
289cae746d9SJeff Niu 
290cae746d9SJeff Niu //===----------------------------------------------------------------------===//
291cae746d9SJeff Niu // Pattern Population
292cae746d9SJeff Niu //===----------------------------------------------------------------------===//
293cae746d9SJeff Niu 
294cae746d9SJeff Niu void index::populateIndexToLLVMConversionPatterns(
295*206fad0eSMatthias Springer     const LLVMTypeConverter &typeConverter, RewritePatternSet &patterns) {
296cae746d9SJeff Niu   patterns.insert<
297cae746d9SJeff Niu       // clang-format off
298cae746d9SJeff Niu       ConvertIndexAdd,
299cae746d9SJeff Niu       ConvertIndexSub,
300cae746d9SJeff Niu       ConvertIndexMul,
301cae746d9SJeff Niu       ConvertIndexDivS,
302cae746d9SJeff Niu       ConvertIndexDivU,
303cae746d9SJeff Niu       ConvertIndexRemS,
304cae746d9SJeff Niu       ConvertIndexRemU,
305cae746d9SJeff Niu       ConvertIndexMaxS,
306cae746d9SJeff Niu       ConvertIndexMaxU,
3078cdb4f9fSKrzysztof Drewniak       ConvertIndexMinS,
3088cdb4f9fSKrzysztof Drewniak       ConvertIndexMinU,
3099ef31465SJeff Niu       ConvertIndexShl,
3109ef31465SJeff Niu       ConvertIndexShrS,
3119ef31465SJeff Niu       ConvertIndexShrU,
3124f9c9295SLuca Boasso       ConvertIndexAnd,
3134f9c9295SLuca Boasso       ConvertIndexOr,
3144f9c9295SLuca Boasso       ConvertIndexXor,
315cae746d9SJeff Niu       ConvertIndexCeilDivS,
316cae746d9SJeff Niu       ConvertIndexCeilDivU,
317cae746d9SJeff Niu       ConvertIndexFloorDivS,
318cae746d9SJeff Niu       ConvertIndexCastS,
319cae746d9SJeff Niu       ConvertIndexCastU,
320cae746d9SJeff Niu       ConvertIndexCmp,
321cae746d9SJeff Niu       ConvertIndexSizeOf,
322cae746d9SJeff Niu       ConvertIndexConstant,
323cae746d9SJeff Niu       ConvertIndexBoolConstant
324cae746d9SJeff Niu       // clang-format on
325cae746d9SJeff Niu       >(typeConverter);
326cae746d9SJeff Niu }
327cae746d9SJeff Niu 
328cae746d9SJeff Niu //===----------------------------------------------------------------------===//
329cae746d9SJeff Niu // ODS-Generated Definitions
330cae746d9SJeff Niu //===----------------------------------------------------------------------===//
331cae746d9SJeff Niu 
332cae746d9SJeff Niu namespace mlir {
333cae746d9SJeff Niu #define GEN_PASS_DEF_CONVERTINDEXTOLLVMPASS
334cae746d9SJeff Niu #include "mlir/Conversion/Passes.h.inc"
335cae746d9SJeff Niu } // namespace mlir
336cae746d9SJeff Niu 
337cae746d9SJeff Niu //===----------------------------------------------------------------------===//
338cae746d9SJeff Niu // Pass Definition
339cae746d9SJeff Niu //===----------------------------------------------------------------------===//
340cae746d9SJeff Niu 
341cae746d9SJeff Niu namespace {
342cae746d9SJeff Niu struct ConvertIndexToLLVMPass
343cae746d9SJeff Niu     : public impl::ConvertIndexToLLVMPassBase<ConvertIndexToLLVMPass> {
344cae746d9SJeff Niu   using Base::Base;
345cae746d9SJeff Niu 
346cae746d9SJeff Niu   void runOnOperation() override;
347cae746d9SJeff Niu };
348cae746d9SJeff Niu } // namespace
349cae746d9SJeff Niu 
350cae746d9SJeff Niu void ConvertIndexToLLVMPass::runOnOperation() {
351cae746d9SJeff Niu   // Configure dialect conversion.
352cae746d9SJeff Niu   ConversionTarget target(getContext());
353cae746d9SJeff Niu   target.addIllegalDialect<IndexDialect>();
354cae746d9SJeff Niu   target.addLegalDialect<LLVM::LLVMDialect>();
355cae746d9SJeff Niu 
356cae746d9SJeff Niu   // Set LLVM lowering options.
357cae746d9SJeff Niu   LowerToLLVMOptions options(&getContext());
358cae746d9SJeff Niu   if (indexBitwidth != kDeriveIndexBitwidthFromDataLayout)
359cae746d9SJeff Niu     options.overrideIndexBitwidth(indexBitwidth);
360cae746d9SJeff Niu   LLVMTypeConverter typeConverter(&getContext(), options);
361cae746d9SJeff Niu 
362cae746d9SJeff Niu   // Populate patterns and run the conversion.
363cae746d9SJeff Niu   RewritePatternSet patterns(&getContext());
364cae746d9SJeff Niu   populateIndexToLLVMConversionPatterns(typeConverter, patterns);
365cae746d9SJeff Niu 
366cae746d9SJeff Niu   if (failed(
367cae746d9SJeff Niu           applyPartialConversion(getOperation(), target, std::move(patterns))))
368cae746d9SJeff Niu     return signalPassFailure();
369cae746d9SJeff Niu }
370bfdc4723SMatthias Springer 
371bfdc4723SMatthias Springer //===----------------------------------------------------------------------===//
372bfdc4723SMatthias Springer // ConvertToLLVMPatternInterface implementation
373bfdc4723SMatthias Springer //===----------------------------------------------------------------------===//
374bfdc4723SMatthias Springer 
375bfdc4723SMatthias Springer namespace {
376bfdc4723SMatthias Springer /// Implement the interface to convert Index to LLVM.
377bfdc4723SMatthias Springer struct IndexToLLVMDialectInterface : public ConvertToLLVMPatternInterface {
378bfdc4723SMatthias Springer   using ConvertToLLVMPatternInterface::ConvertToLLVMPatternInterface;
379bfdc4723SMatthias Springer   void loadDependentDialects(MLIRContext *context) const final {
380bfdc4723SMatthias Springer     context->loadDialect<LLVM::LLVMDialect>();
381bfdc4723SMatthias Springer   }
382bfdc4723SMatthias Springer 
383bfdc4723SMatthias Springer   /// Hook for derived dialect interface to provide conversion patterns
384bfdc4723SMatthias Springer   /// and mark dialect legal for the conversion target.
385bfdc4723SMatthias Springer   void populateConvertToLLVMConversionPatterns(
386bfdc4723SMatthias Springer       ConversionTarget &target, LLVMTypeConverter &typeConverter,
387bfdc4723SMatthias Springer       RewritePatternSet &patterns) const final {
388bfdc4723SMatthias Springer     populateIndexToLLVMConversionPatterns(typeConverter, patterns);
389bfdc4723SMatthias Springer   }
390bfdc4723SMatthias Springer };
391bfdc4723SMatthias Springer } // namespace
392bfdc4723SMatthias Springer 
393bfdc4723SMatthias Springer void mlir::index::registerConvertIndexToLLVMInterface(
394bfdc4723SMatthias Springer     DialectRegistry &registry) {
395bfdc4723SMatthias Springer   registry.addExtension(+[](MLIRContext *ctx, index::IndexDialect *dialect) {
396bfdc4723SMatthias Springer     dialect->addInterfaces<IndexToLLVMDialectInterface>();
397bfdc4723SMatthias Springer   });
398bfdc4723SMatthias Springer }
399