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