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