MLIR 22.0.0git
ArithToLLVM.cpp
Go to the documentation of this file.
1//===- ArithToLLVM.cpp - Arithmetic to LLVM dialect conversion -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
21#include <type_traits>
22
23namespace mlir {
24#define GEN_PASS_DEF_ARITHTOLLVMCONVERSIONPASS
25#include "mlir/Conversion/Passes.h.inc"
26} // namespace mlir
27
28using namespace mlir;
29
30namespace {
31
32/// Operations whose conversion will depend on whether they are passed a
33/// rounding mode attribute or not.
34///
35/// `SourceOp` is the source operation; `TargetOp`, the operation it will lower
36/// to; `AttrConvert` is the attribute conversion to convert the rounding mode
37/// attribute.
38template <typename SourceOp, typename TargetOp, bool Constrained,
39 template <typename, typename> typename AttrConvert =
41 bool FailOnUnsupportedFP = false>
42struct ConstrainedVectorConvertToLLVMPattern
43 : public VectorConvertToLLVMPattern<SourceOp, TargetOp, AttrConvert,
44 FailOnUnsupportedFP> {
45 using VectorConvertToLLVMPattern<
46 SourceOp, TargetOp, AttrConvert,
47 FailOnUnsupportedFP>::VectorConvertToLLVMPattern;
48
49 LogicalResult
50 matchAndRewrite(SourceOp op, typename SourceOp::Adaptor adaptor,
51 ConversionPatternRewriter &rewriter) const override {
52 if (Constrained != static_cast<bool>(op.getRoundingModeAttr()))
53 return failure();
54 return VectorConvertToLLVMPattern<
55 SourceOp, TargetOp, AttrConvert,
56 FailOnUnsupportedFP>::matchAndRewrite(op, adaptor, rewriter);
57 }
58};
59
60/// No-op bitcast. Propagate type input arg if converted source and dest types
61/// are the same.
62struct IdentityBitcastLowering final
63 : public OpConversionPattern<arith::BitcastOp> {
64 using Base::Base;
65
66 LogicalResult
67 matchAndRewrite(arith::BitcastOp op, OpAdaptor adaptor,
68 ConversionPatternRewriter &rewriter) const final {
69 Value src = adaptor.getIn();
70 Type resultType = getTypeConverter()->convertType(op.getType());
71 if (src.getType() != resultType)
72 return rewriter.notifyMatchFailure(op, "Types are different");
73
74 rewriter.replaceOp(op, src);
75 return success();
76 }
77};
78
79//===----------------------------------------------------------------------===//
80// Straightforward Op Lowerings
81//===----------------------------------------------------------------------===//
82
83using AddFOpLowering =
84 VectorConvertToLLVMPattern<arith::AddFOp, LLVM::FAddOp,
86 /*FailOnUnsupportedFP=*/true>;
87using AddIOpLowering =
88 VectorConvertToLLVMPattern<arith::AddIOp, LLVM::AddOp,
91using BitcastOpLowering =
93using DivFOpLowering =
94 VectorConvertToLLVMPattern<arith::DivFOp, LLVM::FDivOp,
96 /*FailOnUnsupportedFP=*/true>;
97using DivSIOpLowering =
99using DivUIOpLowering =
101using ExtFOpLowering = VectorConvertToLLVMPattern<arith::ExtFOp, LLVM::FPExtOp,
103 /*FailOnUnsupportedFP=*/true>;
104using ExtSIOpLowering =
106using ExtUIOpLowering =
108using FPToSIOpLowering =
109 VectorConvertToLLVMPattern<arith::FPToSIOp, LLVM::FPToSIOp,
111 /*FailOnUnsupportedFP=*/true>;
112using FPToUIOpLowering =
113 VectorConvertToLLVMPattern<arith::FPToUIOp, LLVM::FPToUIOp,
115 /*FailOnUnsupportedFP=*/true>;
116using MaximumFOpLowering =
117 VectorConvertToLLVMPattern<arith::MaximumFOp, LLVM::MaximumOp,
119 /*FailOnUnsupportedFP=*/true>;
120using MaxNumFOpLowering =
121 VectorConvertToLLVMPattern<arith::MaxNumFOp, LLVM::MaxNumOp,
123 /*FailOnUnsupportedFP=*/true>;
124using MaxSIOpLowering =
126using MaxUIOpLowering =
128using MinimumFOpLowering =
129 VectorConvertToLLVMPattern<arith::MinimumFOp, LLVM::MinimumOp,
131 /*FailOnUnsupportedFP=*/true>;
132using MinNumFOpLowering =
133 VectorConvertToLLVMPattern<arith::MinNumFOp, LLVM::MinNumOp,
135 /*FailOnUnsupportedFP=*/true>;
136using MinSIOpLowering =
138using MinUIOpLowering =
140using MulFOpLowering =
141 VectorConvertToLLVMPattern<arith::MulFOp, LLVM::FMulOp,
143 /*FailOnUnsupportedFP=*/true>;
144using MulIOpLowering =
145 VectorConvertToLLVMPattern<arith::MulIOp, LLVM::MulOp,
147using NegFOpLowering =
148 VectorConvertToLLVMPattern<arith::NegFOp, LLVM::FNegOp,
150 /*FailOnUnsupportedFP=*/true>;
152using RemFOpLowering =
153 VectorConvertToLLVMPattern<arith::RemFOp, LLVM::FRemOp,
155 /*FailOnUnsupportedFP=*/true>;
156using RemSIOpLowering =
158using RemUIOpLowering =
160using SelectOpLowering =
162using ShLIOpLowering =
163 VectorConvertToLLVMPattern<arith::ShLIOp, LLVM::ShlOp,
165using ShRSIOpLowering =
167using ShRUIOpLowering =
169using SIToFPOpLowering =
171using SubFOpLowering =
172 VectorConvertToLLVMPattern<arith::SubFOp, LLVM::FSubOp,
174 /*FailOnUnsupportedFP=*/true>;
175using SubIOpLowering =
176 VectorConvertToLLVMPattern<arith::SubIOp, LLVM::SubOp,
178using TruncFOpLowering =
179 ConstrainedVectorConvertToLLVMPattern<arith::TruncFOp, LLVM::FPTruncOp,
181 /*FailOnUnsupportedFP=*/true>;
182using ConstrainedTruncFOpLowering = ConstrainedVectorConvertToLLVMPattern<
183 arith::TruncFOp, LLVM::ConstrainedFPTruncIntr, true,
184 arith::AttrConverterConstrainedFPToLLVM, /*FailOnUnsupportedFP=*/true>;
185using TruncIOpLowering =
186 VectorConvertToLLVMPattern<arith::TruncIOp, LLVM::TruncOp,
188using UIToFPOpLowering =
189 VectorConvertToLLVMPattern<arith::UIToFPOp, LLVM::UIToFPOp,
191 /*FailOnUnsupportedFP=*/true>;
193
194//===----------------------------------------------------------------------===//
195// Op Lowering Patterns
196//===----------------------------------------------------------------------===//
197
198/// Directly lower to LLVM op.
199struct ConstantOpLowering : public ConvertOpToLLVMPattern<arith::ConstantOp> {
201
202 LogicalResult
203 matchAndRewrite(arith::ConstantOp op, OpAdaptor adaptor,
204 ConversionPatternRewriter &rewriter) const override;
205};
206
207/// The lowering of index_cast becomes an integer conversion since index
208/// becomes an integer. If the bit width of the source and target integer
209/// types is the same, just erase the cast. If the target type is wider,
210/// sign-extend the value, otherwise truncate it.
211template <typename OpTy, typename ExtCastTy>
212struct IndexCastOpLowering : public ConvertOpToLLVMPattern<OpTy> {
213 using ConvertOpToLLVMPattern<OpTy>::ConvertOpToLLVMPattern;
214
215 LogicalResult
216 matchAndRewrite(OpTy op, typename OpTy::Adaptor adaptor,
217 ConversionPatternRewriter &rewriter) const override;
218};
219
220using IndexCastOpSILowering =
221 IndexCastOpLowering<arith::IndexCastOp, LLVM::SExtOp>;
222using IndexCastOpUILowering =
223 IndexCastOpLowering<arith::IndexCastUIOp, LLVM::ZExtOp>;
224
225struct AddUIExtendedOpLowering
226 : public ConvertOpToLLVMPattern<arith::AddUIExtendedOp> {
228
229 LogicalResult
230 matchAndRewrite(arith::AddUIExtendedOp op, OpAdaptor adaptor,
231 ConversionPatternRewriter &rewriter) const override;
232};
233
234template <typename ArithMulOp, bool IsSigned>
235struct MulIExtendedOpLowering : public ConvertOpToLLVMPattern<ArithMulOp> {
236 using ConvertOpToLLVMPattern<ArithMulOp>::ConvertOpToLLVMPattern;
237
238 LogicalResult
239 matchAndRewrite(ArithMulOp op, typename ArithMulOp::Adaptor adaptor,
240 ConversionPatternRewriter &rewriter) const override;
241};
242
243using MulSIExtendedOpLowering =
244 MulIExtendedOpLowering<arith::MulSIExtendedOp, true>;
245using MulUIExtendedOpLowering =
246 MulIExtendedOpLowering<arith::MulUIExtendedOp, false>;
247
248struct CmpIOpLowering : public ConvertOpToLLVMPattern<arith::CmpIOp> {
250
251 LogicalResult
252 matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
253 ConversionPatternRewriter &rewriter) const override;
254};
255
256struct CmpFOpLowering : public ConvertOpToLLVMPattern<arith::CmpFOp> {
258
259 LogicalResult
260 matchAndRewrite(arith::CmpFOp op, OpAdaptor adaptor,
261 ConversionPatternRewriter &rewriter) const override;
262};
263
264struct SelectOpOneToNLowering : public ConvertOpToLLVMPattern<arith::SelectOp> {
267
268 LogicalResult
269 matchAndRewrite(arith::SelectOp op, Adaptor adaptor,
270 ConversionPatternRewriter &rewriter) const override;
271};
272
273} // namespace
274
275//===----------------------------------------------------------------------===//
276// ConstantOpLowering
277//===----------------------------------------------------------------------===//
278
279LogicalResult
280ConstantOpLowering::matchAndRewrite(arith::ConstantOp op, OpAdaptor adaptor,
281 ConversionPatternRewriter &rewriter) const {
282 return LLVM::detail::oneToOneRewrite(op, LLVM::ConstantOp::getOperationName(),
283 adaptor.getOperands(), op->getAttrs(),
284 /*propAttr=*/Attribute{},
285 *getTypeConverter(), rewriter);
286}
287
288//===----------------------------------------------------------------------===//
289// IndexCastOpLowering
290//===----------------------------------------------------------------------===//
291
292template <typename OpTy, typename ExtCastTy>
293LogicalResult IndexCastOpLowering<OpTy, ExtCastTy>::matchAndRewrite(
294 OpTy op, typename OpTy::Adaptor adaptor,
295 ConversionPatternRewriter &rewriter) const {
296 Type resultType = op.getResult().getType();
297 Type targetElementType =
298 this->typeConverter->convertType(getElementTypeOrSelf(resultType));
299 Type sourceElementType =
300 this->typeConverter->convertType(getElementTypeOrSelf(op.getIn()));
301 unsigned targetBits = targetElementType.getIntOrFloatBitWidth();
302 unsigned sourceBits = sourceElementType.getIntOrFloatBitWidth();
303
304 if (targetBits == sourceBits) {
305 rewriter.replaceOp(op, adaptor.getIn());
306 return success();
307 }
308
309 // Handle the scalar and 1D vector cases.
310 Type operandType = adaptor.getIn().getType();
311 if (!isa<LLVM::LLVMArrayType>(operandType)) {
312 Type targetType = this->typeConverter->convertType(resultType);
313 if (targetBits < sourceBits)
314 rewriter.replaceOpWithNewOp<LLVM::TruncOp>(op, targetType,
315 adaptor.getIn());
316 else
317 rewriter.replaceOpWithNewOp<ExtCastTy>(op, targetType, adaptor.getIn());
318 return success();
319 }
320
321 if (!isa<VectorType>(resultType))
322 return rewriter.notifyMatchFailure(op, "expected vector result type");
323
325 op.getOperation(), adaptor.getOperands(), *(this->getTypeConverter()),
326 [&](Type llvm1DVectorTy, ValueRange operands) -> Value {
327 typename OpTy::Adaptor adaptor(operands);
328 if (targetBits < sourceBits) {
329 return LLVM::TruncOp::create(rewriter, op.getLoc(), llvm1DVectorTy,
330 adaptor.getIn());
331 }
332 return ExtCastTy::create(rewriter, op.getLoc(), llvm1DVectorTy,
333 adaptor.getIn());
334 },
335 rewriter);
336}
337
338//===----------------------------------------------------------------------===//
339// AddUIExtendedOpLowering
340//===----------------------------------------------------------------------===//
341
342LogicalResult AddUIExtendedOpLowering::matchAndRewrite(
343 arith::AddUIExtendedOp op, OpAdaptor adaptor,
344 ConversionPatternRewriter &rewriter) const {
345 Type operandType = adaptor.getLhs().getType();
346 Type sumResultType = op.getSum().getType();
347 Type overflowResultType = op.getOverflow().getType();
348
349 if (!LLVM::isCompatibleType(operandType))
350 return failure();
351
352 MLIRContext *ctx = rewriter.getContext();
353 Location loc = op.getLoc();
354
355 // Handle the scalar and 1D vector cases.
356 if (!isa<LLVM::LLVMArrayType>(operandType)) {
357 Type newOverflowType = typeConverter->convertType(overflowResultType);
358 Type structType =
359 LLVM::LLVMStructType::getLiteral(ctx, {sumResultType, newOverflowType});
360 Value addOverflow = LLVM::UAddWithOverflowOp::create(
361 rewriter, loc, structType, adaptor.getLhs(), adaptor.getRhs());
362 Value sumExtracted =
363 LLVM::ExtractValueOp::create(rewriter, loc, addOverflow, 0);
364 Value overflowExtracted =
365 LLVM::ExtractValueOp::create(rewriter, loc, addOverflow, 1);
366 rewriter.replaceOp(op, {sumExtracted, overflowExtracted});
367 return success();
369
370 if (!isa<VectorType>(sumResultType))
371 return rewriter.notifyMatchFailure(loc, "expected vector result types");
373 return rewriter.notifyMatchFailure(loc,
374 "ND vector types are not supported yet");
376
377//===----------------------------------------------------------------------===//
378// MulIExtendedOpLowering
379//===----------------------------------------------------------------------===//
380
381template <typename ArithMulOp, bool IsSigned>
382LogicalResult MulIExtendedOpLowering<ArithMulOp, IsSigned>::matchAndRewrite(
383 ArithMulOp op, typename ArithMulOp::Adaptor adaptor,
384 ConversionPatternRewriter &rewriter) const {
385 Type resultType = adaptor.getLhs().getType();
387 if (!LLVM::isCompatibleType(resultType))
388 return failure();
390 Location loc = op.getLoc();
391
392 // Handle the scalar and 1D vector cases. Because LLVM does not have a
393 // matching extended multiplication intrinsic, perform regular multiplication
394 // on operands zero-extended to i(2*N) bits, and truncate the results back to
395 // iN types.
396 if (!isa<LLVM::LLVMArrayType>(resultType)) {
397 // Shift amount necessary to extract the high bits from widened result.
398 TypedAttr shiftValAttr;
399
400 if (auto intTy = dyn_cast<IntegerType>(resultType)) {
401 unsigned resultBitwidth = intTy.getWidth();
402 auto attrTy = rewriter.getIntegerType(resultBitwidth * 2);
403 shiftValAttr = rewriter.getIntegerAttr(attrTy, resultBitwidth);
404 } else {
405 auto vecTy = cast<VectorType>(resultType);
406 unsigned resultBitwidth = vecTy.getElementTypeBitWidth();
407 auto attrTy = VectorType::get(
408 vecTy.getShape(), rewriter.getIntegerType(resultBitwidth * 2));
409 shiftValAttr = SplatElementsAttr::get(
410 attrTy, APInt(resultBitwidth * 2, resultBitwidth));
412 Type wideType = shiftValAttr.getType();
413 assert(LLVM::isCompatibleType(wideType) &&
414 "LLVM dialect should support all signless integer types");
416 using LLVMExtOp = std::conditional_t<IsSigned, LLVM::SExtOp, LLVM::ZExtOp>;
417 Value lhsExt = LLVMExtOp::create(rewriter, loc, wideType, adaptor.getLhs());
418 Value rhsExt = LLVMExtOp::create(rewriter, loc, wideType, adaptor.getRhs());
419 Value mulExt = LLVM::MulOp::create(rewriter, loc, wideType, lhsExt, rhsExt);
420
421 // Split the 2*N-bit wide result into two N-bit values.
422 Value low = LLVM::TruncOp::create(rewriter, loc, resultType, mulExt);
423 Value shiftVal = LLVM::ConstantOp::create(rewriter, loc, shiftValAttr);
424 Value highExt = LLVM::LShrOp::create(rewriter, loc, mulExt, shiftVal);
425 Value high = LLVM::TruncOp::create(rewriter, loc, resultType, highExt);
426
427 rewriter.replaceOp(op, {low, high});
428 return success();
429 }
430
431 if (!isa<VectorType>(resultType))
432 return rewriter.notifyMatchFailure(op, "expected vector result type");
433
434 return rewriter.notifyMatchFailure(op,
435 "ND vector types are not supported yet");
436}
437
438//===----------------------------------------------------------------------===//
439// CmpIOpLowering
440//===----------------------------------------------------------------------===//
441
442// Convert arith.cmp predicate into the LLVM dialect CmpPredicate. The two enums
443// share numerical values so just cast.
444template <typename LLVMPredType, typename PredType>
445static LLVMPredType convertCmpPredicate(PredType pred) {
446 return static_cast<LLVMPredType>(pred);
447}
448
449LogicalResult
450CmpIOpLowering::matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
451 ConversionPatternRewriter &rewriter) const {
452 Type operandType = adaptor.getLhs().getType();
453 Type resultType = op.getResult().getType();
454
455 // Handle the scalar and 1D vector cases.
456 if (!isa<LLVM::LLVMArrayType>(operandType)) {
457 rewriter.replaceOpWithNewOp<LLVM::ICmpOp>(
458 op, typeConverter->convertType(resultType),
460 adaptor.getLhs(), adaptor.getRhs());
461 return success();
462 }
463
464 if (!isa<VectorType>(resultType))
465 return rewriter.notifyMatchFailure(op, "expected vector result type");
466
468 op.getOperation(), adaptor.getOperands(), *getTypeConverter(),
469 [&](Type llvm1DVectorTy, ValueRange operands) {
470 OpAdaptor adaptor(operands);
471 return LLVM::ICmpOp::create(
472 rewriter, op.getLoc(), llvm1DVectorTy,
474 adaptor.getLhs(), adaptor.getRhs());
475 },
476 rewriter);
477}
478
479//===----------------------------------------------------------------------===//
480// CmpFOpLowering
481//===----------------------------------------------------------------------===//
482
483LogicalResult
484CmpFOpLowering::matchAndRewrite(arith::CmpFOp op, OpAdaptor adaptor,
485 ConversionPatternRewriter &rewriter) const {
486 if (LLVM::detail::isUnsupportedFloatingPointType(*this->getTypeConverter(),
487 op.getLhs().getType()))
488 return rewriter.notifyMatchFailure(op, "unsupported floating point type");
489
490 Type operandType = adaptor.getLhs().getType();
491 Type resultType = op.getResult().getType();
492 LLVM::FastmathFlags fmf =
493 arith::convertArithFastMathFlagsToLLVM(op.getFastmath());
494
495 // Handle the scalar and 1D vector cases.
496 if (!isa<LLVM::LLVMArrayType>(operandType)) {
497 rewriter.replaceOpWithNewOp<LLVM::FCmpOp>(
498 op, typeConverter->convertType(resultType),
500 adaptor.getLhs(), adaptor.getRhs(), fmf);
501 return success();
502 }
503
504 if (!isa<VectorType>(resultType))
505 return rewriter.notifyMatchFailure(op, "expected vector result type");
506
508 op.getOperation(), adaptor.getOperands(), *getTypeConverter(),
509 [&](Type llvm1DVectorTy, ValueRange operands) {
510 OpAdaptor adaptor(operands);
511 return LLVM::FCmpOp::create(
512 rewriter, op.getLoc(), llvm1DVectorTy,
514 adaptor.getLhs(), adaptor.getRhs(), fmf);
515 },
516 rewriter);
517}
518
519//===----------------------------------------------------------------------===//
520// SelectOpOneToNLowering
521//===----------------------------------------------------------------------===//
522
523/// Pattern for arith.select where the true/false values lower to multiple
524/// SSA values (1:N conversion). This pattern generates multiple arith.select
525/// than can be lowered by the 1:1 arith.select pattern.
526LogicalResult SelectOpOneToNLowering::matchAndRewrite(
527 arith::SelectOp op, Adaptor adaptor,
528 ConversionPatternRewriter &rewriter) const {
529 // In case of a 1:1 conversion, the 1:1 pattern will match.
530 if (llvm::hasSingleElement(adaptor.getTrueValue()))
531 return rewriter.notifyMatchFailure(
532 op, "not a 1:N conversion, 1:1 pattern will match");
533 if (!op.getCondition().getType().isInteger(1))
534 return rewriter.notifyMatchFailure(op,
535 "non-i1 conditions are not supported");
536 SmallVector<Value> results;
537 for (auto [trueValue, falseValue] :
538 llvm::zip_equal(adaptor.getTrueValue(), adaptor.getFalseValue()))
539 results.push_back(arith::SelectOp::create(
540 rewriter, op.getLoc(), op.getCondition(), trueValue, falseValue));
541 rewriter.replaceOpWithMultiple(op, {results});
542 return success();
543}
544
545//===----------------------------------------------------------------------===//
546// Pass Definition
547//===----------------------------------------------------------------------===//
548
549namespace {
550struct ArithToLLVMConversionPass
551 : public impl::ArithToLLVMConversionPassBase<ArithToLLVMConversionPass> {
552 using Base::Base;
553
554 void runOnOperation() override {
555 LLVMConversionTarget target(getContext());
556 RewritePatternSet patterns(&getContext());
557
558 LowerToLLVMOptions options(&getContext());
559 if (indexBitwidth != kDeriveIndexBitwidthFromDataLayout)
560 options.overrideIndexBitwidth(indexBitwidth);
561
562 LLVMTypeConverter converter(&getContext(), options);
563 arith::populateCeilFloorDivExpandOpsPatterns(patterns);
564 arith::populateArithToLLVMConversionPatterns(converter, patterns);
565
566 if (failed(applyPartialConversion(getOperation(), target,
567 std::move(patterns))))
568 signalPassFailure();
569 }
570};
571} // namespace
572
573//===----------------------------------------------------------------------===//
574// ConvertToLLVMPatternInterface implementation
575//===----------------------------------------------------------------------===//
576
577namespace {
578/// Implement the interface to convert MemRef to LLVM.
579struct ArithToLLVMDialectInterface : public ConvertToLLVMPatternInterface {
581 void loadDependentDialects(MLIRContext *context) const final {
582 context->loadDialect<LLVM::LLVMDialect>();
583 }
584
585 /// Hook for derived dialect interface to provide conversion patterns
586 /// and mark dialect legal for the conversion target.
587 void populateConvertToLLVMConversionPatterns(
588 ConversionTarget &target, LLVMTypeConverter &typeConverter,
589 RewritePatternSet &patterns) const final {
590 arith::populateCeilFloorDivExpandOpsPatterns(patterns);
591 arith::populateArithToLLVMConversionPatterns(typeConverter, patterns);
592 }
593};
594} // namespace
595
597 DialectRegistry &registry) {
598 registry.addExtension(+[](MLIRContext *ctx, arith::ArithDialect *dialect) {
599 dialect->addInterfaces<ArithToLLVMDialectInterface>();
600 });
601}
602
603//===----------------------------------------------------------------------===//
604// Pattern Population
605//===----------------------------------------------------------------------===//
606
608 const LLVMTypeConverter &converter, RewritePatternSet &patterns) {
609
610 // Set a higher pattern benefit for IdentityBitcastLowering so it will run
611 // before BitcastOpLowering.
612 patterns.add<IdentityBitcastLowering>(converter, patterns.getContext(),
613 /*patternBenefit*/ 10);
614
615 // clang-format off
616 patterns.add<
617 AddFOpLowering,
618 AddIOpLowering,
619 AndIOpLowering,
620 AddUIExtendedOpLowering,
621 BitcastOpLowering,
622 ConstantOpLowering,
623 CmpFOpLowering,
624 CmpIOpLowering,
625 DivFOpLowering,
626 DivSIOpLowering,
627 DivUIOpLowering,
628 ExtFOpLowering,
629 ExtSIOpLowering,
630 ExtUIOpLowering,
631 FPToSIOpLowering,
632 FPToUIOpLowering,
633 IndexCastOpSILowering,
634 IndexCastOpUILowering,
635 MaximumFOpLowering,
636 MaxNumFOpLowering,
637 MaxSIOpLowering,
638 MaxUIOpLowering,
639 MinimumFOpLowering,
640 MinNumFOpLowering,
641 MinSIOpLowering,
642 MinUIOpLowering,
643 MulFOpLowering,
644 MulIOpLowering,
645 MulSIExtendedOpLowering,
646 MulUIExtendedOpLowering,
647 NegFOpLowering,
648 OrIOpLowering,
649 RemFOpLowering,
650 RemSIOpLowering,
651 RemUIOpLowering,
652 SelectOpLowering,
653 SelectOpOneToNLowering,
654 ShLIOpLowering,
655 ShRSIOpLowering,
656 ShRUIOpLowering,
657 SIToFPOpLowering,
658 SubFOpLowering,
659 SubIOpLowering,
660 TruncFOpLowering,
661 ConstrainedTruncFOpLowering,
662 TruncIOpLowering,
663 UIToFPOpLowering,
664 XOrIOpLowering
665 >(converter);
666 // clang-format on
667}
return success()
static LLVMPredType convertCmpPredicate(PredType pred)
b getContext())
static llvm::ManagedStatic< PassManagerOptions > options
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
Definition Pattern.h:207
ConvertOpToLLVMPattern(const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
Definition Pattern.h:213
typename SourceOp::template GenericAdaptor< ArrayRef< ValueRange > > OneToNOpAdaptor
Definition Pattern.h:210
ConvertToLLVMPatternInterface(Dialect *dialect)
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
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.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
Definition Types.cpp:122
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Type getType() const
Return the type of this value.
Definition Value.h:105
Basic lowering implementation to rewrite Ops with just one result to the LLVM Dialect.
LogicalResult handleMultidimensionalVectors(Operation *op, ValueRange operands, const LLVMTypeConverter &typeConverter, std::function< Value(Type, ValueRange)> createOperand, ConversionPatternRewriter &rewriter)
bool isUnsupportedFloatingPointType(const TypeConverter &typeConverter, Type type)
Return "true" if the given type is an unsupported floating point type.
LogicalResult oneToOneRewrite(Operation *op, StringRef targetOp, ValueRange operands, ArrayRef< NamedAttribute > targetAttrs, Attribute propertiesAttr, const LLVMTypeConverter &typeConverter, ConversionPatternRewriter &rewriter)
Replaces the given operation "op" with a new operation of type "targetOp" and given operands.
Definition Pattern.cpp:301
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
void populateArithToLLVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns)
void registerConvertArithToLLVMInterface(DialectRegistry &registry)
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:561
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...
Type getElementTypeOrSelf(Type type)
Return the element type or return the type itself.
const FrozenRewritePatternSet & patterns