26#define GEN_PASS_DEF_ARITHTOLLVMCONVERSIONPASS
27#include "mlir/Conversion/Passes.h.inc"
47template <
typename SourceOp,
typename TargetOp,
bool HasRoundingMode,
48 template <
typename,
typename>
typename AttrConvert =
50 bool FailOnUnsupportedFP =
false>
51struct ConstrainedVectorConvertToLLVMPattern
53 FailOnUnsupportedFP> {
54 using VectorConvertToLLVMPattern<
55 SourceOp, TargetOp, AttrConvert,
56 FailOnUnsupportedFP>::VectorConvertToLLVMPattern;
59 matchAndRewrite(SourceOp op,
typename SourceOp::Adaptor adaptor,
60 ConversionPatternRewriter &rewriter)
const override {
61 if (HasRoundingMode !=
static_cast<bool>(op.getRoundingModeAttr()))
63 return VectorConvertToLLVMPattern<
64 SourceOp, TargetOp, AttrConvert,
65 FailOnUnsupportedFP>::matchAndRewrite(op, adaptor, rewriter);
71struct IdentityBitcastLowering final
72 :
public OpConversionPattern<arith::BitcastOp> {
76 matchAndRewrite(arith::BitcastOp op, OpAdaptor adaptor,
77 ConversionPatternRewriter &rewriter)
const final {
78 Value src = adaptor.getIn();
79 Type resultType = getTypeConverter()->convertType(op.getType());
80 if (src.
getType() != resultType)
81 return rewriter.notifyMatchFailure(op,
"Types are different");
83 rewriter.replaceOp(op, src);
93 ConstrainedVectorConvertToLLVMPattern<arith::AddFOp, LLVM::FAddOp,
97using ConstrainedAddFOpLowering = ConstrainedVectorConvertToLLVMPattern<
98 arith::AddFOp, LLVM::ConstrainedFAddIntr,
true,
100using AddIOpLowering =
104using BitcastOpLowering =
106using DivFOpLowering =
107 ConstrainedVectorConvertToLLVMPattern<arith::DivFOp, LLVM::FDivOp,
111using ConstrainedDivFOpLowering = ConstrainedVectorConvertToLLVMPattern<
112 arith::DivFOp, LLVM::ConstrainedFDivIntr,
true,
114using DivSIOpLowering =
116using DivUIOpLowering =
118using ExtFOpLowering =
122using ExtSIOpLowering =
124using ExtUIOpLowering =
127using FPToSIOpLowering =
131using FPToUIOpLowering =
135using MaximumFOpLowering =
139using MaxNumFOpLowering =
143using MaximumNumFOpLowering =
147using MaxSIOpLowering =
149using MaxUIOpLowering =
151using MinimumFOpLowering =
155using MinNumFOpLowering =
159using MinimumNumFOpLowering =
163using MinSIOpLowering =
165using MinUIOpLowering =
167using MulFOpLowering =
168 ConstrainedVectorConvertToLLVMPattern<arith::MulFOp, LLVM::FMulOp,
172using ConstrainedMulFOpLowering = ConstrainedVectorConvertToLLVMPattern<
173 arith::MulFOp, LLVM::ConstrainedFMulIntr,
true,
175using MulIOpLowering =
178using NegFOpLowering =
183using RemFOpLowering =
187using RemSIOpLowering =
189using RemUIOpLowering =
191using SelectOpLowering =
193using ShLIOpLowering =
196using ShRSIOpLowering =
198using ShRUIOpLowering =
200using SIToFPOpLowering =
202using SubFOpLowering =
203 ConstrainedVectorConvertToLLVMPattern<arith::SubFOp, LLVM::FSubOp,
207using ConstrainedSubFOpLowering = ConstrainedVectorConvertToLLVMPattern<
208 arith::SubFOp, LLVM::ConstrainedFSubIntr,
true,
210using SubIOpLowering =
213using TruncFOpLowering =
214 ConstrainedVectorConvertToLLVMPattern<arith::TruncFOp, LLVM::FPTruncOp,
218using ConstrainedTruncFOpLowering = ConstrainedVectorConvertToLLVMPattern<
219 arith::TruncFOp, LLVM::ConstrainedFPTruncIntr,
true,
221using TruncIOpLowering =
224using UIToFPOpLowering =
239 matchAndRewrite(arith::ConstantOp op, OpAdaptor adaptor,
240 ConversionPatternRewriter &rewriter)
const override;
247template <
typename OpTy,
typename ExtCastTy>
249 using ConvertOpToLLVMPattern<OpTy>::ConvertOpToLLVMPattern;
252 matchAndRewrite(OpTy op,
typename OpTy::Adaptor adaptor,
253 ConversionPatternRewriter &rewriter)
const override;
256using IndexCastOpSILowering =
257 IndexCastOpLowering<arith::IndexCastOp, LLVM::SExtOp>;
258using IndexCastOpUILowering =
259 IndexCastOpLowering<arith::IndexCastUIOp, LLVM::ZExtOp>;
261struct AddUIExtendedOpLowering
266 matchAndRewrite(arith::AddUIExtendedOp op, OpAdaptor adaptor,
267 ConversionPatternRewriter &rewriter)
const override;
270struct SubUIExtendedOpLowering
275 matchAndRewrite(arith::SubUIExtendedOp op, OpAdaptor adaptor,
276 ConversionPatternRewriter &rewriter)
const override;
279template <
typename ArithMulOp,
bool IsSigned>
281 using ConvertOpToLLVMPattern<ArithMulOp>::ConvertOpToLLVMPattern;
284 matchAndRewrite(ArithMulOp op,
typename ArithMulOp::Adaptor adaptor,
285 ConversionPatternRewriter &rewriter)
const override;
288using MulSIExtendedOpLowering =
289 MulIExtendedOpLowering<arith::MulSIExtendedOp, true>;
290using MulUIExtendedOpLowering =
291 MulIExtendedOpLowering<arith::MulUIExtendedOp, false>;
297 matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
298 ConversionPatternRewriter &rewriter)
const override;
305 matchAndRewrite(arith::CmpFOp op, OpAdaptor adaptor,
306 ConversionPatternRewriter &rewriter)
const override;
318 matchAndRewrite(arith::ConvertFOp op, OpAdaptor adaptor,
319 ConversionPatternRewriter &rewriter)
const override {
321 *getTypeConverter()))
322 return rewriter.notifyMatchFailure(op,
"unsupported floating point type");
328 assert(((srcType.isBF16() && dstType.isF16()) ||
329 (srcType.isF16() && dstType.isBF16())) &&
330 "only bf16 <-> f16 conversions are supported");
332 Type convertedType = getTypeConverter()->convertType(op.getType());
334 return rewriter.notifyMatchFailure(op,
"failed to convert result type");
336 Value input = adaptor.getIn();
337 Location loc = op.getLoc();
339 if (!isa<LLVM::LLVMArrayType>(input.
getType())) {
340 rewriter.replaceOp(op,
341 emitConversion(rewriter, loc, input, convertedType));
345 if (!isa<VectorType>(op.getType()))
346 return rewriter.notifyMatchFailure(op,
"expected vector result type");
349 op.getOperation(), adaptor.getOperands(), *getTypeConverter(),
350 [&](Type llvm1DVectorTy,
ValueRange operands) -> Value {
351 return emitConversion(rewriter, loc, operands.front(),
358 static Value emitConversion(ConversionPatternRewriter &rewriter, Location loc,
359 Value input, Type targetType) {
360 Type f32Scalar = Float32Type::get(rewriter.getContext());
361 Type f32Ty = f32Scalar;
362 if (
auto vecTy = dyn_cast<VectorType>(targetType))
363 f32Ty = VectorType::get(vecTy.getShape(), f32Scalar);
365 Value ext = LLVM::FPExtOp::create(rewriter, loc, f32Ty, input);
366 return LLVM::FPTruncOp::create(rewriter, loc, targetType, ext);
375 matchAndRewrite(arith::SelectOp op, Adaptor adaptor,
376 ConversionPatternRewriter &rewriter)
const override;
398 if (sourceElementType == targetElementType)
401 auto targetIntType = dyn_cast<IntegerType>(targetElementType);
408 if (
auto sourceFloatType = dyn_cast<FloatType>(sourceElementType)) {
409 if (sourceFloatType.getWidth() != targetIntType.getWidth())
418 if (!isa<IndexType>(sourceElementType))
422 unsigned width = targetIntType.getWidth();
424 if (
auto intAttr = dyn_cast<IntegerAttr>(attr))
425 return IntegerAttr::get(targetIntType,
426 intAttr.getValue().sextOrTrunc(width));
429 return values.mapValues(targetIntType, [&](
const APInt &value) {
430 return value.sextOrTrunc(width);
434 if (
auto denseAttr = dyn_cast<DenseIntElementsAttr>(attr))
435 return retypeValues(denseAttr);
437 if (
auto sparseAttr = dyn_cast<SparseElementsAttr>(attr))
438 return SparseElementsAttr::get(
439 cast<ShapedType>(attr.getType()).clone(targetIntType),
440 sparseAttr.getIndices(),
441 retypeValues(cast<DenseIntElementsAttr>(sparseAttr.getValues())));
447 if (
auto resourceAttr = dyn_cast<DenseResourceElementsAttr>(attr)) {
448 if (width != IndexType::kInternalStorageBitWidth)
450 return DenseResourceElementsAttr::get(
451 cast<ShapedType>(attr.getType()).clone(targetIntType),
452 resourceAttr.getRawHandle());
459ConstantOpLowering::matchAndRewrite(arith::ConstantOp op, OpAdaptor adaptor,
460 ConversionPatternRewriter &rewriter)
const {
461 Type resultType = getTypeConverter()->convertType(op.getType());
463 return rewriter.notifyMatchFailure(op,
"failed to convert result type");
467 return rewriter.notifyMatchFailure(
468 op,
"failed to convert value attribute to the converted result type");
473 DictionaryAttr discardableAttrs = op->getDiscardableAttrDictionary();
475 LLVM::ConstantOp::create(rewriter, op.getLoc(), resultType, value);
476 constantOp->setDiscardableAttrs(discardableAttrs);
477 rewriter.replaceOp(op, constantOp);
485template <
typename OpTy,
typename ExtCastTy>
486LogicalResult IndexCastOpLowering<OpTy, ExtCastTy>::matchAndRewrite(
487 OpTy op,
typename OpTy::Adaptor adaptor,
488 ConversionPatternRewriter &rewriter)
const {
489 Type resultType = op.getResult().getType();
490 Type targetElementType =
492 Type sourceElementType =
497 if (targetBits == sourceBits) {
498 rewriter.replaceOp(op, adaptor.getIn());
505 if (isa<MemRefType>(op.getIn().getType())) {
506 rewriter.replaceOp(op, adaptor.getIn());
510 bool isNonNeg =
false;
511 if constexpr (std::is_same_v<ExtCastTy, LLVM::ZExtOp>)
512 isNonNeg = op.getNonNeg();
515 Type operandType = adaptor.getIn().getType();
516 if (!isa<LLVM::LLVMArrayType>(operandType)) {
517 Type targetType = this->typeConverter->convertType(resultType);
518 if (targetBits < sourceBits) {
519 rewriter.replaceOpWithNewOp<LLVM::TruncOp>(op, targetType,
522 auto extOp = rewriter.replaceOpWithNewOp<ExtCastTy>(op, targetType,
524 if constexpr (std::is_same_v<ExtCastTy, LLVM::ZExtOp>)
525 extOp.setNonNeg(isNonNeg);
530 if (!isa<VectorType>(resultType))
531 return rewriter.notifyMatchFailure(op,
"expected vector result type");
534 op.getOperation(), adaptor.getOperands(), *(this->getTypeConverter()),
535 [&](Type llvm1DVectorTy,
ValueRange operands) -> Value {
536 typename OpTy::Adaptor adaptor(operands);
537 if (targetBits < sourceBits) {
538 return LLVM::TruncOp::create(rewriter, op.getLoc(), llvm1DVectorTy,
541 auto extOp = ExtCastTy::create(rewriter, op.getLoc(), llvm1DVectorTy,
543 if constexpr (std::is_same_v<ExtCastTy, LLVM::ZExtOp>) {
545 extOp.setNonNeg(
true);
556LogicalResult AddUIExtendedOpLowering::matchAndRewrite(
557 arith::AddUIExtendedOp op, OpAdaptor adaptor,
558 ConversionPatternRewriter &rewriter)
const {
559 Type operandType = adaptor.getLhs().getType();
560 Type sumResultType = op.getSum().getType();
561 Type overflowResultType = op.getOverflow().getType();
563 if (!LLVM::isCompatibleType(operandType))
566 MLIRContext *ctx = rewriter.getContext();
567 Location loc = op.getLoc();
570 if (!isa<LLVM::LLVMArrayType>(operandType)) {
571 Type newOverflowType = typeConverter->convertType(overflowResultType);
573 LLVM::LLVMStructType::getLiteral(ctx, {sumResultType, newOverflowType});
574 Value addOverflow = LLVM::UAddWithOverflowOp::create(
575 rewriter, loc, structType, adaptor.getLhs(), adaptor.getRhs());
577 LLVM::ExtractValueOp::create(rewriter, loc, addOverflow, 0);
578 Value overflowExtracted =
579 LLVM::ExtractValueOp::create(rewriter, loc, addOverflow, 1);
580 rewriter.replaceOp(op, {sumExtracted, overflowExtracted});
584 if (!isa<VectorType>(sumResultType))
585 return rewriter.notifyMatchFailure(loc,
"expected vector result types");
587 return rewriter.notifyMatchFailure(loc,
588 "ND vector types are not supported yet");
595LogicalResult SubUIExtendedOpLowering::matchAndRewrite(
596 arith::SubUIExtendedOp op, OpAdaptor adaptor,
597 ConversionPatternRewriter &rewriter)
const {
598 Type operandType = adaptor.getLhs().getType();
599 Type diffResultType = op.getDiff().getType();
600 Type borrowResultType = op.getBorrow().getType();
602 if (!LLVM::isCompatibleType(operandType))
605 MLIRContext *ctx = rewriter.getContext();
606 Location loc = op.getLoc();
609 if (!isa<LLVM::LLVMArrayType>(operandType)) {
610 Type newBorrowType = typeConverter->convertType(borrowResultType);
612 LLVM::LLVMStructType::getLiteral(ctx, {diffResultType, newBorrowType});
613 Value subOverflow = LLVM::USubWithOverflowOp::create(
614 rewriter, loc, structType, adaptor.getLhs(), adaptor.getRhs());
615 Value diffExtracted =
616 LLVM::ExtractValueOp::create(rewriter, loc, subOverflow, 0);
617 Value borrowExtracted =
618 LLVM::ExtractValueOp::create(rewriter, loc, subOverflow, 1);
619 rewriter.replaceOp(op, {diffExtracted, borrowExtracted});
623 if (!isa<VectorType>(diffResultType))
624 return rewriter.notifyMatchFailure(loc,
"expected vector result types");
626 return rewriter.notifyMatchFailure(loc,
627 "ND vector types are not supported yet");
634template <
typename ArithMulOp,
bool IsSigned>
635LogicalResult MulIExtendedOpLowering<ArithMulOp, IsSigned>::matchAndRewrite(
636 ArithMulOp op,
typename ArithMulOp::Adaptor adaptor,
637 ConversionPatternRewriter &rewriter)
const {
638 Type resultType = adaptor.getLhs().getType();
640 if (!LLVM::isCompatibleType(resultType))
643 Location loc = op.getLoc();
649 if (!isa<LLVM::LLVMArrayType>(resultType)) {
651 TypedAttr shiftValAttr;
653 if (
auto intTy = dyn_cast<IntegerType>(resultType)) {
654 unsigned resultBitwidth = intTy.getWidth();
655 auto attrTy = rewriter.getIntegerType(resultBitwidth * 2);
656 shiftValAttr = rewriter.getIntegerAttr(attrTy, resultBitwidth);
658 auto vecTy = cast<VectorType>(resultType);
659 unsigned resultBitwidth = vecTy.getElementTypeBitWidth();
660 auto attrTy = VectorType::get(
661 vecTy.getShape(), rewriter.getIntegerType(resultBitwidth * 2));
662 shiftValAttr = SplatElementsAttr::get(
663 attrTy, APInt(resultBitwidth * 2, resultBitwidth));
665 Type wideType = shiftValAttr.getType();
666 assert(LLVM::isCompatibleType(wideType) &&
667 "LLVM dialect should support all signless integer types");
669 using LLVMExtOp = std::conditional_t<IsSigned, LLVM::SExtOp, LLVM::ZExtOp>;
670 Value lhsExt = LLVMExtOp::create(rewriter, loc, wideType, adaptor.getLhs());
671 Value rhsExt = LLVMExtOp::create(rewriter, loc, wideType, adaptor.getRhs());
672 Value mulExt = LLVM::MulOp::create(rewriter, loc, wideType, lhsExt, rhsExt);
675 Value low = LLVM::TruncOp::create(rewriter, loc, resultType, mulExt);
676 Value shiftVal = LLVM::ConstantOp::create(rewriter, loc, shiftValAttr);
677 Value highExt = LLVM::LShrOp::create(rewriter, loc, mulExt, shiftVal);
678 Value high = LLVM::TruncOp::create(rewriter, loc, resultType, highExt);
680 rewriter.replaceOp(op, {low, high});
684 if (!isa<VectorType>(resultType))
685 return rewriter.notifyMatchFailure(op,
"expected vector result type");
687 return rewriter.notifyMatchFailure(op,
688 "ND vector types are not supported yet");
697template <
typename LLVMPredType,
typename PredType>
699 return static_cast<LLVMPredType
>(pred);
703CmpIOpLowering::matchAndRewrite(arith::CmpIOp op, OpAdaptor adaptor,
704 ConversionPatternRewriter &rewriter)
const {
705 Type operandType = adaptor.getLhs().getType();
706 Type resultType = op.getResult().getType();
709 if (!isa<LLVM::LLVMArrayType>(operandType)) {
710 rewriter.replaceOpWithNewOp<LLVM::ICmpOp>(
711 op, typeConverter->convertType(resultType),
713 adaptor.getLhs(), adaptor.getRhs());
717 if (!isa<VectorType>(resultType))
718 return rewriter.notifyMatchFailure(op,
"expected vector result type");
721 op.getOperation(), adaptor.getOperands(), *getTypeConverter(),
722 [&](Type llvm1DVectorTy,
ValueRange operands) {
723 OpAdaptor adaptor(operands);
724 return LLVM::ICmpOp::create(
725 rewriter, op.getLoc(), llvm1DVectorTy,
727 adaptor.getLhs(), adaptor.getRhs());
737CmpFOpLowering::matchAndRewrite(arith::CmpFOp op, OpAdaptor adaptor,
738 ConversionPatternRewriter &rewriter)
const {
740 op.getLhs().getType()))
741 return rewriter.notifyMatchFailure(op,
"unsupported floating point type");
743 Type operandType = adaptor.getLhs().getType();
744 Type resultType = op.getResult().getType();
745 LLVM::FastmathFlags fmf =
746 arith::convertArithFastMathFlagsToLLVM(op.getFastmath());
749 if (!isa<LLVM::LLVMArrayType>(operandType)) {
750 rewriter.replaceOpWithNewOp<LLVM::FCmpOp>(
751 op, typeConverter->convertType(resultType),
753 adaptor.getLhs(), adaptor.getRhs(), fmf);
757 if (!isa<VectorType>(resultType))
758 return rewriter.notifyMatchFailure(op,
"expected vector result type");
761 op.getOperation(), adaptor.getOperands(), *getTypeConverter(),
762 [&](Type llvm1DVectorTy,
ValueRange operands) {
763 OpAdaptor adaptor(operands);
764 return LLVM::FCmpOp::create(
765 rewriter, op.getLoc(), llvm1DVectorTy,
767 adaptor.getLhs(), adaptor.getRhs(), fmf);
779LogicalResult SelectOpOneToNLowering::matchAndRewrite(
780 arith::SelectOp op, Adaptor adaptor,
781 ConversionPatternRewriter &rewriter)
const {
783 if (llvm::hasSingleElement(adaptor.getTrueValue()))
784 return rewriter.notifyMatchFailure(
785 op,
"not a 1:N conversion, 1:1 pattern will match");
786 if (!op.getCondition().getType().isInteger(1))
787 return rewriter.notifyMatchFailure(op,
788 "non-i1 conditions are not supported");
789 SmallVector<Value> results;
790 for (
auto [trueValue, falseValue] :
791 llvm::zip_equal(adaptor.getTrueValue(), adaptor.getFalseValue()))
792 results.push_back(arith::SelectOp::create(
793 rewriter, op.getLoc(), op.getCondition(), trueValue, falseValue));
794 rewriter.replaceOpWithMultiple(op, {results});
803struct ArithToLLVMConversionPass
804 :
public impl::ArithToLLVMConversionPassBase<ArithToLLVMConversionPass> {
807 void runOnOperation()
override {
811 const auto &dataLayoutAnalysis = getAnalysis<DataLayoutAnalysis>();
813 dataLayoutAnalysis.getAtOrAbove(getOperation()));
815 options.overrideIndexBitwidth(indexBitwidth);
818 arith::populateCeilFloorDivExpandOpsPatterns(patterns);
819 arith::populateArithToLLVMConversionPatterns(converter, patterns);
821 if (
failed(applyPartialConversion(getOperation(),
target,
822 std::move(patterns))))
834struct ArithToLLVMDialectInterface :
public ConvertToLLVMPatternInterface {
835 ArithToLLVMDialectInterface(Dialect *dialect)
836 : ConvertToLLVMPatternInterface(dialect) {}
838 void loadDependentDialects(MLIRContext *context)
const final {
839 context->loadDialect<LLVM::LLVMDialect>();
844 void populateConvertToLLVMConversionPatterns(
845 ConversionTarget &
target, LLVMTypeConverter &typeConverter,
846 RewritePatternSet &patterns)
const final {
847 arith::populateCeilFloorDivExpandOpsPatterns(patterns);
848 arith::populateArithToLLVMConversionPatterns(typeConverter, patterns);
856 dialect->addInterfaces<ArithToLLVMDialectInterface>();
869 patterns.
add<IdentityBitcastLowering>(converter, patterns.
getContext(),
875 ConstrainedAddFOpLowering,
878 AddUIExtendedOpLowering,
879 SubUIExtendedOpLowering,
885 ConstrainedDivFOpLowering,
894 IndexCastOpSILowering,
895 IndexCastOpUILowering,
898 MaximumNumFOpLowering,
903 MinimumNumFOpLowering,
907 ConstrainedMulFOpLowering,
909 MulSIExtendedOpLowering,
910 MulUIExtendedOpLowering,
917 SelectOpOneToNLowering,
923 ConstrainedSubFOpLowering,
926 ConstrainedTruncFOpLowering,
static LLVMPredType convertCmpPredicate(PredType pred)
static TypedAttr convertConstantValue(TypedAttr attr, Type resultType)
Retypes attr for a llvm.mlir.constant of resultType.
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)
typename SourceOp::template GenericAdaptor< ArrayRef< ValueRange > > OneToNOpAdaptor
An attribute that represents a reference to a dense integer vector or tensor object.
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.
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
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.
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.
bool opHasUnsupportedFloatingPointTypes(Operation *op, const TypeConverter &typeConverter)
Return "true" if the given op has any unsupported floating point types (either operands or results).
Type getConstantElementType(Type type)
Determines the element type of type the way the llvm.mlir.constant verifier does, i....
void populateArithToLLVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns)
void registerConvertArithToLLVMInterface(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...
Type getElementTypeOrSelf(Type type)
Return the element type or return the type itself.