1d0cb0d30SAlexander Belyaev //===- ComplexToLLVM.cpp - conversion from Complex to LLVM dialect --------===//
2d0cb0d30SAlexander Belyaev //
3d0cb0d30SAlexander Belyaev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d0cb0d30SAlexander Belyaev // See https://llvm.org/LICENSE.txt for license information.
5d0cb0d30SAlexander Belyaev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d0cb0d30SAlexander Belyaev //
7d0cb0d30SAlexander Belyaev //===----------------------------------------------------------------------===//
8d0cb0d30SAlexander Belyaev 
9d0cb0d30SAlexander Belyaev #include "mlir/Conversion/ComplexToLLVM/ComplexToLLVM.h"
10d0cb0d30SAlexander Belyaev 
11d0cb0d30SAlexander Belyaev #include "../PassDetail.h"
1275e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
1375e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/Pattern.h"
14d0cb0d30SAlexander Belyaev #include "mlir/Dialect/Complex/IR/Complex.h"
15d0cb0d30SAlexander Belyaev #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
16d0cb0d30SAlexander Belyaev 
17d0cb0d30SAlexander Belyaev using namespace mlir;
18d0cb0d30SAlexander Belyaev using namespace mlir::LLVM;
19d0cb0d30SAlexander Belyaev 
20b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===//
21b5d847b1SAlex Zinenko // ComplexStructBuilder implementation.
22b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===//
23b5d847b1SAlex Zinenko 
24b5d847b1SAlex Zinenko static constexpr unsigned kRealPosInComplexNumberStruct = 0;
25b5d847b1SAlex Zinenko static constexpr unsigned kImaginaryPosInComplexNumberStruct = 1;
26b5d847b1SAlex Zinenko 
27b5d847b1SAlex Zinenko ComplexStructBuilder ComplexStructBuilder::undef(OpBuilder &builder,
28b5d847b1SAlex Zinenko                                                  Location loc, Type type) {
29b5d847b1SAlex Zinenko   Value val = builder.create<LLVM::UndefOp>(loc, type);
30b5d847b1SAlex Zinenko   return ComplexStructBuilder(val);
31b5d847b1SAlex Zinenko }
32b5d847b1SAlex Zinenko 
33b5d847b1SAlex Zinenko void ComplexStructBuilder::setReal(OpBuilder &builder, Location loc,
34b5d847b1SAlex Zinenko                                    Value real) {
35b5d847b1SAlex Zinenko   setPtr(builder, loc, kRealPosInComplexNumberStruct, real);
36b5d847b1SAlex Zinenko }
37b5d847b1SAlex Zinenko 
38b5d847b1SAlex Zinenko Value ComplexStructBuilder::real(OpBuilder &builder, Location loc) {
39b5d847b1SAlex Zinenko   return extractPtr(builder, loc, kRealPosInComplexNumberStruct);
40b5d847b1SAlex Zinenko }
41b5d847b1SAlex Zinenko 
42b5d847b1SAlex Zinenko void ComplexStructBuilder::setImaginary(OpBuilder &builder, Location loc,
43b5d847b1SAlex Zinenko                                         Value imaginary) {
44b5d847b1SAlex Zinenko   setPtr(builder, loc, kImaginaryPosInComplexNumberStruct, imaginary);
45b5d847b1SAlex Zinenko }
46b5d847b1SAlex Zinenko 
47b5d847b1SAlex Zinenko Value ComplexStructBuilder::imaginary(OpBuilder &builder, Location loc) {
48b5d847b1SAlex Zinenko   return extractPtr(builder, loc, kImaginaryPosInComplexNumberStruct);
49b5d847b1SAlex Zinenko }
50b5d847b1SAlex Zinenko 
51b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===//
52b5d847b1SAlex Zinenko // Conversion patterns.
53b5d847b1SAlex Zinenko //===----------------------------------------------------------------------===//
54b5d847b1SAlex Zinenko 
55d0cb0d30SAlexander Belyaev namespace {
56d0cb0d30SAlexander Belyaev 
5711f4c58cSAlexander Belyaev struct AbsOpConversion : public ConvertOpToLLVMPattern<complex::AbsOp> {
5811f4c58cSAlexander Belyaev   using ConvertOpToLLVMPattern<complex::AbsOp>::ConvertOpToLLVMPattern;
5911f4c58cSAlexander Belyaev 
6011f4c58cSAlexander Belyaev   LogicalResult
61*ef976337SRiver Riddle   matchAndRewrite(complex::AbsOp op, OpAdaptor adaptor,
6211f4c58cSAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
6311f4c58cSAlexander Belyaev     auto loc = op.getLoc();
6411f4c58cSAlexander Belyaev 
65*ef976337SRiver Riddle     ComplexStructBuilder complexStruct(adaptor.complex());
6611f4c58cSAlexander Belyaev     Value real = complexStruct.real(rewriter, op.getLoc());
6711f4c58cSAlexander Belyaev     Value imag = complexStruct.imaginary(rewriter, op.getLoc());
6811f4c58cSAlexander Belyaev 
69038f2a33SMehdi Amini     auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
7011f4c58cSAlexander Belyaev     Value sqNorm = rewriter.create<LLVM::FAddOp>(
7111f4c58cSAlexander Belyaev         loc, rewriter.create<LLVM::FMulOp>(loc, real, real, fmf),
7211f4c58cSAlexander Belyaev         rewriter.create<LLVM::FMulOp>(loc, imag, imag, fmf), fmf);
7311f4c58cSAlexander Belyaev 
7411f4c58cSAlexander Belyaev     rewriter.replaceOpWithNewOp<LLVM::SqrtOp>(op, sqNorm);
7511f4c58cSAlexander Belyaev     return success();
7611f4c58cSAlexander Belyaev   }
7711f4c58cSAlexander Belyaev };
7811f4c58cSAlexander Belyaev 
79d0cb0d30SAlexander Belyaev struct CreateOpConversion : public ConvertOpToLLVMPattern<complex::CreateOp> {
80d0cb0d30SAlexander Belyaev   using ConvertOpToLLVMPattern<complex::CreateOp>::ConvertOpToLLVMPattern;
81d0cb0d30SAlexander Belyaev 
82d0cb0d30SAlexander Belyaev   LogicalResult
83*ef976337SRiver Riddle   matchAndRewrite(complex::CreateOp complexOp, OpAdaptor adaptor,
84d0cb0d30SAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
85d0cb0d30SAlexander Belyaev     // Pack real and imaginary part in a complex number struct.
86d0cb0d30SAlexander Belyaev     auto loc = complexOp.getLoc();
87d0cb0d30SAlexander Belyaev     auto structType = typeConverter->convertType(complexOp.getType());
88d0cb0d30SAlexander Belyaev     auto complexStruct = ComplexStructBuilder::undef(rewriter, loc, structType);
89*ef976337SRiver Riddle     complexStruct.setReal(rewriter, loc, adaptor.real());
90*ef976337SRiver Riddle     complexStruct.setImaginary(rewriter, loc, adaptor.imaginary());
91d0cb0d30SAlexander Belyaev 
92d0cb0d30SAlexander Belyaev     rewriter.replaceOp(complexOp, {complexStruct});
93d0cb0d30SAlexander Belyaev     return success();
94d0cb0d30SAlexander Belyaev   }
95d0cb0d30SAlexander Belyaev };
96d0cb0d30SAlexander Belyaev 
97d0cb0d30SAlexander Belyaev struct ReOpConversion : public ConvertOpToLLVMPattern<complex::ReOp> {
98d0cb0d30SAlexander Belyaev   using ConvertOpToLLVMPattern<complex::ReOp>::ConvertOpToLLVMPattern;
99d0cb0d30SAlexander Belyaev 
100d0cb0d30SAlexander Belyaev   LogicalResult
101*ef976337SRiver Riddle   matchAndRewrite(complex::ReOp op, OpAdaptor adaptor,
102d0cb0d30SAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
103d0cb0d30SAlexander Belyaev     // Extract real part from the complex number struct.
104*ef976337SRiver Riddle     ComplexStructBuilder complexStruct(adaptor.complex());
105d0cb0d30SAlexander Belyaev     Value real = complexStruct.real(rewriter, op.getLoc());
106d0cb0d30SAlexander Belyaev     rewriter.replaceOp(op, real);
107d0cb0d30SAlexander Belyaev 
108d0cb0d30SAlexander Belyaev     return success();
109d0cb0d30SAlexander Belyaev   }
110d0cb0d30SAlexander Belyaev };
111d0cb0d30SAlexander Belyaev 
112d0cb0d30SAlexander Belyaev struct ImOpConversion : public ConvertOpToLLVMPattern<complex::ImOp> {
113d0cb0d30SAlexander Belyaev   using ConvertOpToLLVMPattern<complex::ImOp>::ConvertOpToLLVMPattern;
114d0cb0d30SAlexander Belyaev 
115d0cb0d30SAlexander Belyaev   LogicalResult
116*ef976337SRiver Riddle   matchAndRewrite(complex::ImOp op, OpAdaptor adaptor,
117d0cb0d30SAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
118d0cb0d30SAlexander Belyaev     // Extract imaginary part from the complex number struct.
119*ef976337SRiver Riddle     ComplexStructBuilder complexStruct(adaptor.complex());
120d0cb0d30SAlexander Belyaev     Value imaginary = complexStruct.imaginary(rewriter, op.getLoc());
121d0cb0d30SAlexander Belyaev     rewriter.replaceOp(op, imaginary);
122d0cb0d30SAlexander Belyaev 
123d0cb0d30SAlexander Belyaev     return success();
124d0cb0d30SAlexander Belyaev   }
125d0cb0d30SAlexander Belyaev };
126d0cb0d30SAlexander Belyaev 
127d0cb0d30SAlexander Belyaev struct BinaryComplexOperands {
128d0cb0d30SAlexander Belyaev   std::complex<Value> lhs;
129d0cb0d30SAlexander Belyaev   std::complex<Value> rhs;
130d0cb0d30SAlexander Belyaev };
131d0cb0d30SAlexander Belyaev 
132d0cb0d30SAlexander Belyaev template <typename OpTy>
133d0cb0d30SAlexander Belyaev BinaryComplexOperands
134*ef976337SRiver Riddle unpackBinaryComplexOperands(OpTy op, typename OpTy::Adaptor adaptor,
135d0cb0d30SAlexander Belyaev                             ConversionPatternRewriter &rewriter) {
136d0cb0d30SAlexander Belyaev   auto loc = op.getLoc();
137d0cb0d30SAlexander Belyaev 
138d0cb0d30SAlexander Belyaev   // Extract real and imaginary values from operands.
139d0cb0d30SAlexander Belyaev   BinaryComplexOperands unpacked;
140*ef976337SRiver Riddle   ComplexStructBuilder lhs(adaptor.lhs());
141d0cb0d30SAlexander Belyaev   unpacked.lhs.real(lhs.real(rewriter, loc));
142d0cb0d30SAlexander Belyaev   unpacked.lhs.imag(lhs.imaginary(rewriter, loc));
143*ef976337SRiver Riddle   ComplexStructBuilder rhs(adaptor.rhs());
144d0cb0d30SAlexander Belyaev   unpacked.rhs.real(rhs.real(rewriter, loc));
145d0cb0d30SAlexander Belyaev   unpacked.rhs.imag(rhs.imaginary(rewriter, loc));
146d0cb0d30SAlexander Belyaev 
147d0cb0d30SAlexander Belyaev   return unpacked;
148d0cb0d30SAlexander Belyaev }
149d0cb0d30SAlexander Belyaev 
150d0cb0d30SAlexander Belyaev struct AddOpConversion : public ConvertOpToLLVMPattern<complex::AddOp> {
151d0cb0d30SAlexander Belyaev   using ConvertOpToLLVMPattern<complex::AddOp>::ConvertOpToLLVMPattern;
152d0cb0d30SAlexander Belyaev 
153d0cb0d30SAlexander Belyaev   LogicalResult
154*ef976337SRiver Riddle   matchAndRewrite(complex::AddOp op, OpAdaptor adaptor,
155d0cb0d30SAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
156d0cb0d30SAlexander Belyaev     auto loc = op.getLoc();
157d0cb0d30SAlexander Belyaev     BinaryComplexOperands arg =
158*ef976337SRiver Riddle         unpackBinaryComplexOperands<complex::AddOp>(op, adaptor, rewriter);
159d0cb0d30SAlexander Belyaev 
160d0cb0d30SAlexander Belyaev     // Initialize complex number struct for result.
161d0cb0d30SAlexander Belyaev     auto structType = typeConverter->convertType(op.getType());
162d0cb0d30SAlexander Belyaev     auto result = ComplexStructBuilder::undef(rewriter, loc, structType);
163d0cb0d30SAlexander Belyaev 
164d0cb0d30SAlexander Belyaev     // Emit IR to add complex numbers.
165038f2a33SMehdi Amini     auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
166d0cb0d30SAlexander Belyaev     Value real =
167d0cb0d30SAlexander Belyaev         rewriter.create<LLVM::FAddOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf);
168d0cb0d30SAlexander Belyaev     Value imag =
169d0cb0d30SAlexander Belyaev         rewriter.create<LLVM::FAddOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf);
170d0cb0d30SAlexander Belyaev     result.setReal(rewriter, loc, real);
171d0cb0d30SAlexander Belyaev     result.setImaginary(rewriter, loc, imag);
172d0cb0d30SAlexander Belyaev 
173d0cb0d30SAlexander Belyaev     rewriter.replaceOp(op, {result});
174d0cb0d30SAlexander Belyaev     return success();
175d0cb0d30SAlexander Belyaev   }
176d0cb0d30SAlexander Belyaev };
177d0cb0d30SAlexander Belyaev 
17811f4c58cSAlexander Belyaev struct DivOpConversion : public ConvertOpToLLVMPattern<complex::DivOp> {
17911f4c58cSAlexander Belyaev   using ConvertOpToLLVMPattern<complex::DivOp>::ConvertOpToLLVMPattern;
18011f4c58cSAlexander Belyaev 
18111f4c58cSAlexander Belyaev   LogicalResult
182*ef976337SRiver Riddle   matchAndRewrite(complex::DivOp op, OpAdaptor adaptor,
18311f4c58cSAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
18411f4c58cSAlexander Belyaev     auto loc = op.getLoc();
18511f4c58cSAlexander Belyaev     BinaryComplexOperands arg =
186*ef976337SRiver Riddle         unpackBinaryComplexOperands<complex::DivOp>(op, adaptor, rewriter);
18711f4c58cSAlexander Belyaev 
18811f4c58cSAlexander Belyaev     // Initialize complex number struct for result.
18911f4c58cSAlexander Belyaev     auto structType = typeConverter->convertType(op.getType());
19011f4c58cSAlexander Belyaev     auto result = ComplexStructBuilder::undef(rewriter, loc, structType);
19111f4c58cSAlexander Belyaev 
19211f4c58cSAlexander Belyaev     // Emit IR to add complex numbers.
193038f2a33SMehdi Amini     auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
19411f4c58cSAlexander Belyaev     Value rhsRe = arg.rhs.real();
19511f4c58cSAlexander Belyaev     Value rhsIm = arg.rhs.imag();
19611f4c58cSAlexander Belyaev     Value lhsRe = arg.lhs.real();
19711f4c58cSAlexander Belyaev     Value lhsIm = arg.lhs.imag();
19811f4c58cSAlexander Belyaev 
19911f4c58cSAlexander Belyaev     Value rhsSqNorm = rewriter.create<LLVM::FAddOp>(
20011f4c58cSAlexander Belyaev         loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, rhsRe, fmf),
20111f4c58cSAlexander Belyaev         rewriter.create<LLVM::FMulOp>(loc, rhsIm, rhsIm, fmf), fmf);
20211f4c58cSAlexander Belyaev 
20311f4c58cSAlexander Belyaev     Value resultReal = rewriter.create<LLVM::FAddOp>(
20411f4c58cSAlexander Belyaev         loc, rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsRe, fmf),
20511f4c58cSAlexander Belyaev         rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsIm, fmf), fmf);
20611f4c58cSAlexander Belyaev 
20711f4c58cSAlexander Belyaev     Value resultImag = rewriter.create<LLVM::FSubOp>(
20811f4c58cSAlexander Belyaev         loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf),
20911f4c58cSAlexander Belyaev         rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf);
21011f4c58cSAlexander Belyaev 
21111f4c58cSAlexander Belyaev     result.setReal(
21211f4c58cSAlexander Belyaev         rewriter, loc,
21311f4c58cSAlexander Belyaev         rewriter.create<LLVM::FDivOp>(loc, resultReal, rhsSqNorm, fmf));
21411f4c58cSAlexander Belyaev     result.setImaginary(
21511f4c58cSAlexander Belyaev         rewriter, loc,
21611f4c58cSAlexander Belyaev         rewriter.create<LLVM::FDivOp>(loc, resultImag, rhsSqNorm, fmf));
21711f4c58cSAlexander Belyaev 
21811f4c58cSAlexander Belyaev     rewriter.replaceOp(op, {result});
21911f4c58cSAlexander Belyaev     return success();
22011f4c58cSAlexander Belyaev   }
22111f4c58cSAlexander Belyaev };
22211f4c58cSAlexander Belyaev 
22311f4c58cSAlexander Belyaev struct MulOpConversion : public ConvertOpToLLVMPattern<complex::MulOp> {
22411f4c58cSAlexander Belyaev   using ConvertOpToLLVMPattern<complex::MulOp>::ConvertOpToLLVMPattern;
22511f4c58cSAlexander Belyaev 
22611f4c58cSAlexander Belyaev   LogicalResult
227*ef976337SRiver Riddle   matchAndRewrite(complex::MulOp op, OpAdaptor adaptor,
22811f4c58cSAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
22911f4c58cSAlexander Belyaev     auto loc = op.getLoc();
23011f4c58cSAlexander Belyaev     BinaryComplexOperands arg =
231*ef976337SRiver Riddle         unpackBinaryComplexOperands<complex::MulOp>(op, adaptor, rewriter);
23211f4c58cSAlexander Belyaev 
23311f4c58cSAlexander Belyaev     // Initialize complex number struct for result.
23411f4c58cSAlexander Belyaev     auto structType = typeConverter->convertType(op.getType());
23511f4c58cSAlexander Belyaev     auto result = ComplexStructBuilder::undef(rewriter, loc, structType);
23611f4c58cSAlexander Belyaev 
23711f4c58cSAlexander Belyaev     // Emit IR to add complex numbers.
238038f2a33SMehdi Amini     auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
23911f4c58cSAlexander Belyaev     Value rhsRe = arg.rhs.real();
24011f4c58cSAlexander Belyaev     Value rhsIm = arg.rhs.imag();
24111f4c58cSAlexander Belyaev     Value lhsRe = arg.lhs.real();
24211f4c58cSAlexander Belyaev     Value lhsIm = arg.lhs.imag();
24311f4c58cSAlexander Belyaev 
24411f4c58cSAlexander Belyaev     Value real = rewriter.create<LLVM::FSubOp>(
24511f4c58cSAlexander Belyaev         loc, rewriter.create<LLVM::FMulOp>(loc, rhsRe, lhsRe, fmf),
24611f4c58cSAlexander Belyaev         rewriter.create<LLVM::FMulOp>(loc, rhsIm, lhsIm, fmf), fmf);
24711f4c58cSAlexander Belyaev 
24811f4c58cSAlexander Belyaev     Value imag = rewriter.create<LLVM::FAddOp>(
24911f4c58cSAlexander Belyaev         loc, rewriter.create<LLVM::FMulOp>(loc, lhsIm, rhsRe, fmf),
25011f4c58cSAlexander Belyaev         rewriter.create<LLVM::FMulOp>(loc, lhsRe, rhsIm, fmf), fmf);
25111f4c58cSAlexander Belyaev 
25211f4c58cSAlexander Belyaev     result.setReal(rewriter, loc, real);
25311f4c58cSAlexander Belyaev     result.setImaginary(rewriter, loc, imag);
25411f4c58cSAlexander Belyaev 
25511f4c58cSAlexander Belyaev     rewriter.replaceOp(op, {result});
25611f4c58cSAlexander Belyaev     return success();
25711f4c58cSAlexander Belyaev   }
25811f4c58cSAlexander Belyaev };
25911f4c58cSAlexander Belyaev 
260d0cb0d30SAlexander Belyaev struct SubOpConversion : public ConvertOpToLLVMPattern<complex::SubOp> {
261d0cb0d30SAlexander Belyaev   using ConvertOpToLLVMPattern<complex::SubOp>::ConvertOpToLLVMPattern;
262d0cb0d30SAlexander Belyaev 
263d0cb0d30SAlexander Belyaev   LogicalResult
264*ef976337SRiver Riddle   matchAndRewrite(complex::SubOp op, OpAdaptor adaptor,
265d0cb0d30SAlexander Belyaev                   ConversionPatternRewriter &rewriter) const override {
266d0cb0d30SAlexander Belyaev     auto loc = op.getLoc();
267d0cb0d30SAlexander Belyaev     BinaryComplexOperands arg =
268*ef976337SRiver Riddle         unpackBinaryComplexOperands<complex::SubOp>(op, adaptor, rewriter);
269d0cb0d30SAlexander Belyaev 
270d0cb0d30SAlexander Belyaev     // Initialize complex number struct for result.
271d0cb0d30SAlexander Belyaev     auto structType = typeConverter->convertType(op.getType());
272d0cb0d30SAlexander Belyaev     auto result = ComplexStructBuilder::undef(rewriter, loc, structType);
273d0cb0d30SAlexander Belyaev 
274d0cb0d30SAlexander Belyaev     // Emit IR to substract complex numbers.
275038f2a33SMehdi Amini     auto fmf = LLVM::FMFAttr::get(op.getContext(), {});
276d0cb0d30SAlexander Belyaev     Value real =
277d0cb0d30SAlexander Belyaev         rewriter.create<LLVM::FSubOp>(loc, arg.lhs.real(), arg.rhs.real(), fmf);
278d0cb0d30SAlexander Belyaev     Value imag =
279d0cb0d30SAlexander Belyaev         rewriter.create<LLVM::FSubOp>(loc, arg.lhs.imag(), arg.rhs.imag(), fmf);
280d0cb0d30SAlexander Belyaev     result.setReal(rewriter, loc, real);
281d0cb0d30SAlexander Belyaev     result.setImaginary(rewriter, loc, imag);
282d0cb0d30SAlexander Belyaev 
283d0cb0d30SAlexander Belyaev     rewriter.replaceOp(op, {result});
284d0cb0d30SAlexander Belyaev     return success();
285d0cb0d30SAlexander Belyaev   }
286d0cb0d30SAlexander Belyaev };
287d0cb0d30SAlexander Belyaev } // namespace
288d0cb0d30SAlexander Belyaev 
289d0cb0d30SAlexander Belyaev void mlir::populateComplexToLLVMConversionPatterns(
290dc4e913bSChris Lattner     LLVMTypeConverter &converter, RewritePatternSet &patterns) {
291d0cb0d30SAlexander Belyaev   // clang-format off
292dc4e913bSChris Lattner   patterns.add<
29311f4c58cSAlexander Belyaev       AbsOpConversion,
294d0cb0d30SAlexander Belyaev       AddOpConversion,
295d0cb0d30SAlexander Belyaev       CreateOpConversion,
29611f4c58cSAlexander Belyaev       DivOpConversion,
297d0cb0d30SAlexander Belyaev       ImOpConversion,
29811f4c58cSAlexander Belyaev       MulOpConversion,
299d0cb0d30SAlexander Belyaev       ReOpConversion,
300d0cb0d30SAlexander Belyaev       SubOpConversion
301d0cb0d30SAlexander Belyaev     >(converter);
302d0cb0d30SAlexander Belyaev   // clang-format on
303d0cb0d30SAlexander Belyaev }
304d0cb0d30SAlexander Belyaev 
305d0cb0d30SAlexander Belyaev namespace {
306d0cb0d30SAlexander Belyaev struct ConvertComplexToLLVMPass
307d0cb0d30SAlexander Belyaev     : public ConvertComplexToLLVMBase<ConvertComplexToLLVMPass> {
308d0cb0d30SAlexander Belyaev   void runOnOperation() override;
309d0cb0d30SAlexander Belyaev };
310d0cb0d30SAlexander Belyaev } // namespace
311d0cb0d30SAlexander Belyaev 
312d0cb0d30SAlexander Belyaev void ConvertComplexToLLVMPass::runOnOperation() {
313d0cb0d30SAlexander Belyaev   auto module = getOperation();
314d0cb0d30SAlexander Belyaev 
315d0cb0d30SAlexander Belyaev   // Convert to the LLVM IR dialect using the converter defined above.
316dc4e913bSChris Lattner   RewritePatternSet patterns(&getContext());
317d0cb0d30SAlexander Belyaev   LLVMTypeConverter converter(&getContext());
318d0cb0d30SAlexander Belyaev   populateComplexToLLVMConversionPatterns(converter, patterns);
319d0cb0d30SAlexander Belyaev 
320d0cb0d30SAlexander Belyaev   LLVMConversionTarget target(getContext());
321d6be2773SAlex Zinenko   target.addLegalOp<ModuleOp, FuncOp>();
322d6be2773SAlex Zinenko   target.addIllegalDialect<complex::ComplexDialect>();
323d6be2773SAlex Zinenko   if (failed(applyPartialConversion(module, target, std::move(patterns))))
324d0cb0d30SAlexander Belyaev     signalPassFailure();
325d0cb0d30SAlexander Belyaev }
326d0cb0d30SAlexander Belyaev 
327d0cb0d30SAlexander Belyaev std::unique_ptr<OperationPass<ModuleOp>>
328d0cb0d30SAlexander Belyaev mlir::createConvertComplexToLLVMPass() {
329d0cb0d30SAlexander Belyaev   return std::make_unique<ConvertComplexToLLVMPass>();
330d0cb0d30SAlexander Belyaev }
331