//===- ComplexToStandard.cpp - conversion from Complex to Standard dialect ===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/ComplexToStandard/ComplexToStandard.h"

#include "mlir/Conversion/ComplexCommon/DivisionConverter.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Complex/IR/Complex.h"
#include "mlir/Dialect/Math/IR/Math.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Transforms/DialectConversion.h"
#include <type_traits>

namespace mlir {
#define GEN_PASS_DEF_CONVERTCOMPLEXTOSTANDARDPASS
#include "mlir/Conversion/Passes.h.inc"
} // namespace mlir

using namespace mlir;

namespace {

enum class AbsFn { abs, sqrt, rsqrt };

// Returns the absolute value, its square root or its reciprocal square root.
Value computeAbs(Value real, Value imag, arith::FastMathFlags fmf,
                 ImplicitLocOpBuilder &b, AbsFn fn = AbsFn::abs) {
  Value one = arith::ConstantOp::create(b, real.getType(),
                                        b.getFloatAttr(real.getType(), 1.0));

  Value absReal = math::AbsFOp::create(b, real, fmf);
  Value absImag = math::AbsFOp::create(b, imag, fmf);

  Value max = arith::MaximumFOp::create(b, absReal, absImag, fmf);
  Value min = arith::MinimumFOp::create(b, absReal, absImag, fmf);

  // The lowering below requires NaNs and infinities to work correctly.
  arith::FastMathFlags fmfWithNaNInf = arith::bitEnumClear(
      fmf, arith::FastMathFlags::nnan | arith::FastMathFlags::ninf);
  Value ratio = arith::DivFOp::create(b, min, max, fmfWithNaNInf);
  Value ratioSq = arith::MulFOp::create(b, ratio, ratio, fmfWithNaNInf);
  Value ratioSqPlusOne = arith::AddFOp::create(b, ratioSq, one, fmfWithNaNInf);
  Value result;

  if (fn == AbsFn::rsqrt) {
    ratioSqPlusOne = math::RsqrtOp::create(b, ratioSqPlusOne, fmfWithNaNInf);
    min = math::RsqrtOp::create(b, min, fmfWithNaNInf);
    max = math::RsqrtOp::create(b, max, fmfWithNaNInf);
  }

  if (fn == AbsFn::sqrt) {
    Value quarter = arith::ConstantOp::create(
        b, real.getType(), b.getFloatAttr(real.getType(), 0.25));
    // sqrt(sqrt(a*b)) would avoid the pow, but will overflow more easily.
    Value sqrt = math::SqrtOp::create(b, max, fmfWithNaNInf);
    Value p025 =
        math::PowFOp::create(b, ratioSqPlusOne, quarter, fmfWithNaNInf);
    result = arith::MulFOp::create(b, sqrt, p025, fmfWithNaNInf);
  } else {
    Value sqrt = math::SqrtOp::create(b, ratioSqPlusOne, fmfWithNaNInf);
    result = arith::MulFOp::create(b, max, sqrt, fmfWithNaNInf);
  }

  Value isNaN = arith::CmpFOp::create(b, arith::CmpFPredicate::UNO, result,
                                      result, fmfWithNaNInf);
  return arith::SelectOp::create(b, isNaN, min, result);
}

struct AbsOpConversion : public OpConversionPattern<complex::AbsOp> {
  using OpConversionPattern<complex::AbsOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::AbsOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    ImplicitLocOpBuilder b(op.getLoc(), rewriter);

    arith::FastMathFlags fmf = op.getFastMathFlagsAttr().getValue();

    Value real = complex::ReOp::create(b, adaptor.getComplex());
    Value imag = complex::ImOp::create(b, adaptor.getComplex());
    rewriter.replaceOp(op, computeAbs(real, imag, fmf, b));

    return success();
  }
};

// atan2(y,x) = -i * log((x + i * y)/sqrt(x**2+y**2))
struct Atan2OpConversion : public OpConversionPattern<complex::Atan2Op> {
  using OpConversionPattern<complex::Atan2Op>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::Atan2Op op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);

    auto type = cast<ComplexType>(op.getType());
    Type elementType = type.getElementType();
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();

    Value lhs = adaptor.getLhs();
    Value rhs = adaptor.getRhs();

    Value rhsSquared = complex::MulOp::create(b, type, rhs, rhs, fmf);
    Value lhsSquared = complex::MulOp::create(b, type, lhs, lhs, fmf);
    Value rhsSquaredPlusLhsSquared =
        complex::AddOp::create(b, type, rhsSquared, lhsSquared, fmf);
    Value sqrtOfRhsSquaredPlusLhsSquared =
        complex::SqrtOp::create(b, type, rhsSquaredPlusLhsSquared, fmf);

    Value zero =
        arith::ConstantOp::create(b, elementType, b.getZeroAttr(elementType));
    Value one = arith::ConstantOp::create(b, elementType,
                                          b.getFloatAttr(elementType, 1));
    Value i = complex::CreateOp::create(b, type, zero, one);
    Value iTimesLhs = complex::MulOp::create(b, i, lhs, fmf);
    Value rhsPlusILhs = complex::AddOp::create(b, rhs, iTimesLhs, fmf);

    Value divResult = complex::DivOp::create(
        b, rhsPlusILhs, sqrtOfRhsSquaredPlusLhsSquared, fmf);
    Value logResult = complex::LogOp::create(b, divResult, fmf);

    Value negativeOne = arith::ConstantOp::create(
        b, elementType, b.getFloatAttr(elementType, -1));
    Value negativeI = complex::CreateOp::create(b, type, zero, negativeOne);

    rewriter.replaceOpWithNewOp<complex::MulOp>(op, negativeI, logResult, fmf);
    return success();
  }
};

template <typename ComparisonOp, arith::CmpFPredicate p>
struct ComparisonOpConversion : public OpConversionPattern<ComparisonOp> {
  using OpConversionPattern<ComparisonOp>::OpConversionPattern;
  using ResultCombiner =
      std::conditional_t<std::is_same<ComparisonOp, complex::EqualOp>::value,
                         arith::AndIOp, arith::OrIOp>;

  LogicalResult
  matchAndRewrite(ComparisonOp op, typename ComparisonOp::Adaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto loc = op.getLoc();
    auto type = cast<ComplexType>(adaptor.getLhs().getType()).getElementType();

    Value realLhs =
        complex::ReOp::create(rewriter, loc, type, adaptor.getLhs());
    Value imagLhs =
        complex::ImOp::create(rewriter, loc, type, adaptor.getLhs());
    Value realRhs =
        complex::ReOp::create(rewriter, loc, type, adaptor.getRhs());
    Value imagRhs =
        complex::ImOp::create(rewriter, loc, type, adaptor.getRhs());
    Value realComparison =
        arith::CmpFOp::create(rewriter, loc, p, realLhs, realRhs);
    Value imagComparison =
        arith::CmpFOp::create(rewriter, loc, p, imagLhs, imagRhs);

    rewriter.replaceOpWithNewOp<ResultCombiner>(op, realComparison,
                                                imagComparison);
    return success();
  }
};

// Default conversion which applies the BinaryStandardOp separately on the real
// and imaginary parts. Can for example be used for complex::AddOp and
// complex::SubOp.
template <typename BinaryComplexOp, typename BinaryStandardOp>
struct BinaryComplexOpConversion : public OpConversionPattern<BinaryComplexOp> {
  using OpConversionPattern<BinaryComplexOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(BinaryComplexOp op, typename BinaryComplexOp::Adaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto type = cast<ComplexType>(adaptor.getLhs().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();

    Value realLhs = complex::ReOp::create(b, elementType, adaptor.getLhs());
    Value realRhs = complex::ReOp::create(b, elementType, adaptor.getRhs());
    Value resultReal = BinaryStandardOp::create(b, elementType, realLhs,
                                                realRhs, fmf.getValue());
    Value imagLhs = complex::ImOp::create(b, elementType, adaptor.getLhs());
    Value imagRhs = complex::ImOp::create(b, elementType, adaptor.getRhs());
    Value resultImag = BinaryStandardOp::create(b, elementType, imagLhs,
                                                imagRhs, fmf.getValue());
    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);
    return success();
  }
};

template <typename TrigonometricOp>
struct TrigonometricOpConversion : public OpConversionPattern<TrigonometricOp> {
  using OpAdaptor = typename OpConversionPattern<TrigonometricOp>::OpAdaptor;

  using OpConversionPattern<TrigonometricOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(TrigonometricOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto loc = op.getLoc();
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();

    Value real =
        complex::ReOp::create(rewriter, loc, elementType, adaptor.getComplex());
    Value imag =
        complex::ImOp::create(rewriter, loc, elementType, adaptor.getComplex());

    // Trigonometric ops use a set of common building blocks to convert to real
    // ops. Here we create these building blocks and call into an op-specific
    // implementation in the subclass to combine them.
    Value half = arith::ConstantOp::create(
        rewriter, loc, elementType, rewriter.getFloatAttr(elementType, 0.5));
    Value exp = math::ExpOp::create(rewriter, loc, imag, fmf);
    Value scaledExp = arith::MulFOp::create(rewriter, loc, half, exp, fmf);
    Value reciprocalExp = arith::DivFOp::create(rewriter, loc, half, exp, fmf);
    Value sin = math::SinOp::create(rewriter, loc, real, fmf);
    Value cos = math::CosOp::create(rewriter, loc, real, fmf);

    auto resultPair =
        combine(loc, scaledExp, reciprocalExp, sin, cos, rewriter, fmf);

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultPair.first,
                                                   resultPair.second);
    return success();
  }

  virtual std::pair<Value, Value>
  combine(Location loc, Value scaledExp, Value reciprocalExp, Value sin,
          Value cos, ConversionPatternRewriter &rewriter,
          arith::FastMathFlagsAttr fmf) const = 0;
};

struct CosOpConversion : public TrigonometricOpConversion<complex::CosOp> {
  using TrigonometricOpConversion<complex::CosOp>::TrigonometricOpConversion;

  std::pair<Value, Value> combine(Location loc, Value scaledExp,
                                  Value reciprocalExp, Value sin, Value cos,
                                  ConversionPatternRewriter &rewriter,
                                  arith::FastMathFlagsAttr fmf) const override {
    // Complex cosine is defined as;
    //   cos(x + iy) = 0.5 * (exp(i(x + iy)) + exp(-i(x + iy)))
    // Plugging in:
    //   exp(i(x+iy)) = exp(-y + ix) = exp(-y)(cos(x) + i sin(x))
    //   exp(-i(x+iy)) = exp(y + i(-x)) = exp(y)(cos(x) + i (-sin(x)))
    // and defining t := exp(y)
    // We get:
    //   Re(cos(x + iy)) = (0.5/t + 0.5*t) * cos x
    //   Im(cos(x + iy)) = (0.5/t - 0.5*t) * sin x
    Value sum =
        arith::AddFOp::create(rewriter, loc, reciprocalExp, scaledExp, fmf);
    Value resultReal = arith::MulFOp::create(rewriter, loc, sum, cos, fmf);
    Value diff =
        arith::SubFOp::create(rewriter, loc, reciprocalExp, scaledExp, fmf);
    Value resultImag = arith::MulFOp::create(rewriter, loc, diff, sin, fmf);
    return {resultReal, resultImag};
  }
};

struct DivOpConversion : public OpConversionPattern<complex::DivOp> {
  DivOpConversion(MLIRContext *context, complex::ComplexRangeFlags target)
      : OpConversionPattern<complex::DivOp>(context), complexRange(target) {}

  using OpConversionPattern<complex::DivOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::DivOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto loc = op.getLoc();
    auto type = cast<ComplexType>(adaptor.getLhs().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();

    Value lhsReal =
        complex::ReOp::create(rewriter, loc, elementType, adaptor.getLhs());
    Value lhsImag =
        complex::ImOp::create(rewriter, loc, elementType, adaptor.getLhs());
    Value rhsReal =
        complex::ReOp::create(rewriter, loc, elementType, adaptor.getRhs());
    Value rhsImag =
        complex::ImOp::create(rewriter, loc, elementType, adaptor.getRhs());

    Value resultReal, resultImag;

    if (complexRange == complex::ComplexRangeFlags::basic ||
        complexRange == complex::ComplexRangeFlags::none) {
      mlir::complex::convertDivToStandardUsingAlgebraic(
          rewriter, loc, lhsReal, lhsImag, rhsReal, rhsImag, fmf, &resultReal,
          &resultImag);
    } else if (complexRange == complex::ComplexRangeFlags::improved) {
      mlir::complex::convertDivToStandardUsingRangeReduction(
          rewriter, loc, lhsReal, lhsImag, rhsReal, rhsImag, fmf, &resultReal,
          &resultImag);
    }

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);

    return success();
  }

private:
  complex::ComplexRangeFlags complexRange;
};

struct ExpOpConversion : public OpConversionPattern<complex::ExpOp> {
  using OpConversionPattern<complex::ExpOp>::OpConversionPattern;

  // exp(x+I*y) = exp(x)*(cos(y)+I*sin(y))
  // Handle special cases as StableHLO implementation does:
  // 1. When b == 0, set imag(exp(z)) = 0
  // 2. When exp(x) == inf, use exp(x/2)*(cos(y)+I*sin(y))*exp(x/2)
  LogicalResult
  matchAndRewrite(complex::ExpOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto loc = op.getLoc();
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto ET = cast<FloatType>(type.getElementType());
    arith::FastMathFlags fmf = op.getFastMathFlagsAttr().getValue();
    const auto &floatSemantics = ET.getFloatSemantics();
    ImplicitLocOpBuilder b(loc, rewriter);

    Value x = complex::ReOp::create(b, ET, adaptor.getComplex());
    Value y = complex::ImOp::create(b, ET, adaptor.getComplex());
    Value zero = arith::ConstantOp::create(b, ET, b.getZeroAttr(ET));
    Value half = arith::ConstantOp::create(b, ET, b.getFloatAttr(ET, 0.5));
    Value inf = arith::ConstantOp::create(
        b, ET, b.getFloatAttr(ET, APFloat::getInf(floatSemantics)));

    Value exp = math::ExpOp::create(b, x, fmf);
    Value xHalf = arith::MulFOp::create(b, x, half, fmf);
    Value expHalf = math::ExpOp::create(b, xHalf, fmf);
    Value cos = math::CosOp::create(b, y, fmf);
    Value sin = math::SinOp::create(b, y, fmf);

    Value expIsInf =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, exp, inf, fmf);
    Value yIsZero =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, y, zero);

    // Real path: select between exp(x)*cos(y) and exp(x/2)*cos(y)*exp(x/2)
    Value realNormal = arith::MulFOp::create(b, exp, cos, fmf);
    Value expHalfCos = arith::MulFOp::create(b, expHalf, cos, fmf);
    Value realOverflow = arith::MulFOp::create(b, expHalfCos, expHalf, fmf);
    Value resultReal =
        arith::SelectOp::create(b, expIsInf, realOverflow, realNormal);

    // Imaginary part: if y == 0 return 0 else select between exp(x)*sin(y) and
    // exp(x/2)*sin(y)*exp(x/2)
    Value imagNormal = arith::MulFOp::create(b, exp, sin, fmf);
    Value expHalfSin = arith::MulFOp::create(b, expHalf, sin, fmf);
    Value imagOverflow = arith::MulFOp::create(b, expHalfSin, expHalf, fmf);
    Value imagNonZero =
        arith::SelectOp::create(b, expIsInf, imagOverflow, imagNormal);
    Value resultImag = arith::SelectOp::create(b, yIsZero, zero, imagNonZero);

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);
    return success();
  }
};

Value evaluatePolynomial(ImplicitLocOpBuilder &b, Value arg,
                         ArrayRef<double> coefficients,
                         arith::FastMathFlagsAttr fmf) {
  auto argType = mlir::cast<FloatType>(arg.getType());
  Value poly =
      arith::ConstantOp::create(b, b.getFloatAttr(argType, coefficients[0]));
  for (unsigned i = 1; i < coefficients.size(); ++i) {
    poly = math::FmaOp::create(
        b, poly, arg,
        arith::ConstantOp::create(b, b.getFloatAttr(argType, coefficients[i])),
        fmf);
  }
  return poly;
}

struct Expm1OpConversion : public OpConversionPattern<complex::Expm1Op> {
  using OpConversionPattern<complex::Expm1Op>::OpConversionPattern;

  // e^(a+bi)-1 = (e^a*cos(b)-1)+e^a*sin(b)i
  //            [handle inaccuracies when a and/or b are small]
  //            = ((e^a - 1) * cos(b) + cos(b) - 1) + e^a*sin(b)i
  //            = (expm1(a) * cos(b) + cosm1(b)) + e^a*sin(b)i
  LogicalResult
  matchAndRewrite(complex::Expm1Op op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto type = op.getType();
    auto elemType = mlir::cast<FloatType>(type.getElementType());

    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();
    ImplicitLocOpBuilder b(op.getLoc(), rewriter);
    Value real = complex::ReOp::create(b, adaptor.getComplex());
    Value imag = complex::ImOp::create(b, adaptor.getComplex());

    Value zero = arith::ConstantOp::create(b, b.getFloatAttr(elemType, 0.0));
    Value one = arith::ConstantOp::create(b, b.getFloatAttr(elemType, 1.0));

    Value expm1Real = math::ExpM1Op::create(b, real, fmf);
    Value expReal = arith::AddFOp::create(b, expm1Real, one, fmf);

    Value sinImag = math::SinOp::create(b, imag, fmf);
    Value cosm1Imag = emitCosm1(imag, fmf, b);
    Value cosImag = arith::AddFOp::create(b, cosm1Imag, one, fmf);

    Value realResult = arith::AddFOp::create(
        b, arith::MulFOp::create(b, expm1Real, cosImag, fmf), cosm1Imag, fmf);

    Value imagIsZero = arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, imag,
                                             zero, fmf.getValue());
    Value imagResult = arith::SelectOp::create(
        b, imagIsZero, zero, arith::MulFOp::create(b, expReal, sinImag, fmf));

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, realResult,
                                                   imagResult);
    return success();
  }

private:
  Value emitCosm1(Value arg, arith::FastMathFlagsAttr fmf,
                  ImplicitLocOpBuilder &b) const {
    auto argType = mlir::cast<FloatType>(arg.getType());
    auto negHalf = arith::ConstantOp::create(b, b.getFloatAttr(argType, -0.5));
    auto negOne = arith::ConstantOp::create(b, b.getFloatAttr(argType, -1.0));

    // Algorithm copied from cephes cosm1.
    SmallVector<double, 7> kCoeffs{
        4.7377507964246204691685E-14, -1.1470284843425359765671E-11,
        2.0876754287081521758361E-9,  -2.7557319214999787979814E-7,
        2.4801587301570552304991E-5,  -1.3888888888888872993737E-3,
        4.1666666666666666609054E-2,
    };
    Value cos = math::CosOp::create(b, arg, fmf);
    Value forLargeArg = arith::AddFOp::create(b, cos, negOne, fmf);

    Value argPow2 = arith::MulFOp::create(b, arg, arg, fmf);
    Value argPow4 = arith::MulFOp::create(b, argPow2, argPow2, fmf);
    Value poly = evaluatePolynomial(b, argPow2, kCoeffs, fmf);

    auto forSmallArg =
        arith::AddFOp::create(b, arith::MulFOp::create(b, argPow4, poly, fmf),
                              arith::MulFOp::create(b, negHalf, argPow2, fmf));

    // (pi/4)^2 is approximately 0.61685
    Value piOver4Pow2 =
        arith::ConstantOp::create(b, b.getFloatAttr(argType, 0.61685));
    Value cond = arith::CmpFOp::create(b, arith::CmpFPredicate::OGE, argPow2,
                                       piOver4Pow2, fmf.getValue());
    return arith::SelectOp::create(b, cond, forLargeArg, forSmallArg);
  }
};

struct LogOpConversion : public OpConversionPattern<complex::LogOp> {
  using OpConversionPattern<complex::LogOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::LogOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();
    mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);

    Value abs = complex::AbsOp::create(b, elementType, adaptor.getComplex(),
                                       fmf.getValue());
    Value resultReal = math::LogOp::create(b, elementType, abs, fmf.getValue());
    Value real = complex::ReOp::create(b, elementType, adaptor.getComplex());
    Value imag = complex::ImOp::create(b, elementType, adaptor.getComplex());
    Value resultImag =
        math::Atan2Op::create(b, elementType, imag, real, fmf.getValue());
    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);
    return success();
  }
};

struct Log1pOpConversion : public OpConversionPattern<complex::Log1pOp> {
  using OpConversionPattern<complex::Log1pOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::Log1pOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    arith::FastMathFlags fmf = op.getFastMathFlagsAttr().getValue();
    mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);

    Value real = complex::ReOp::create(b, adaptor.getComplex());
    Value imag = complex::ImOp::create(b, adaptor.getComplex());

    Value half = arith::ConstantOp::create(b, elementType,
                                           b.getFloatAttr(elementType, 0.5));
    Value one = arith::ConstantOp::create(b, elementType,
                                          b.getFloatAttr(elementType, 1));
    Value realPlusOne = arith::AddFOp::create(b, real, one, fmf);
    Value absRealPlusOne = math::AbsFOp::create(b, realPlusOne, fmf);
    Value absImag = math::AbsFOp::create(b, imag, fmf);

    Value maxAbs = arith::MaximumFOp::create(b, absRealPlusOne, absImag, fmf);
    Value minAbs = arith::MinimumFOp::create(b, absRealPlusOne, absImag, fmf);

    Value useReal = arith::CmpFOp::create(b, arith::CmpFPredicate::OGT,
                                          realPlusOne, absImag, fmf);
    Value maxMinusOne = arith::SubFOp::create(b, maxAbs, one, fmf);
    Value maxAbsOfRealPlusOneAndImagMinusOne =
        arith::SelectOp::create(b, useReal, real, maxMinusOne);
    arith::FastMathFlags fmfWithNaNInf = arith::bitEnumClear(
        fmf, arith::FastMathFlags::nnan | arith::FastMathFlags::ninf);
    Value minMaxRatio = arith::DivFOp::create(b, minAbs, maxAbs, fmfWithNaNInf);
    Value logOfMaxAbsOfRealPlusOneAndImag =
        math::Log1pOp::create(b, maxAbsOfRealPlusOneAndImagMinusOne, fmf);
    Value logOfSqrtPart = math::Log1pOp::create(
        b, arith::MulFOp::create(b, minMaxRatio, minMaxRatio, fmfWithNaNInf),
        fmfWithNaNInf);
    Value r = arith::AddFOp::create(
        b, arith::MulFOp::create(b, half, logOfSqrtPart, fmfWithNaNInf),
        logOfMaxAbsOfRealPlusOneAndImag, fmfWithNaNInf);
    Value resultReal = arith::SelectOp::create(
        b,
        arith::CmpFOp::create(b, arith::CmpFPredicate::UNO, r, r,
                              fmfWithNaNInf),
        minAbs, r);
    Value resultImag = math::Atan2Op::create(b, imag, realPlusOne, fmf);
    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);
    return success();
  }
};

struct MulOpConversion : public OpConversionPattern<complex::MulOp> {
  using OpConversionPattern<complex::MulOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::MulOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);
    auto type = cast<ComplexType>(adaptor.getLhs().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();
    auto fmfValue = fmf.getValue();
    Value lhsReal = complex::ReOp::create(b, elementType, adaptor.getLhs());
    Value lhsImag = complex::ImOp::create(b, elementType, adaptor.getLhs());
    Value rhsReal = complex::ReOp::create(b, elementType, adaptor.getRhs());
    Value rhsImag = complex::ImOp::create(b, elementType, adaptor.getRhs());
    Value real;
    Value imag;
    if (arith::bitEnumContainsAll(fmfValue, arith::FastMathFlags::contract)) {
      Value lhsImagTimesRhsImag =
          arith::MulFOp::create(b, lhsImag, rhsImag, fmfValue);
      Value negLhsImagTimesRhsImag =
          arith::NegFOp::create(b, lhsImagTimesRhsImag, fmfValue);
      real = math::FmaOp::create(b, lhsReal, rhsReal, negLhsImagTimesRhsImag,
                                 fmfValue);

      Value lhsImagTimesRhsReal =
          arith::MulFOp::create(b, lhsImag, rhsReal, fmfValue);
      imag = math::FmaOp::create(b, lhsReal, rhsImag, lhsImagTimesRhsReal,
                                 fmfValue);
    } else {
      Value lhsRealTimesRhsReal =
          arith::MulFOp::create(b, lhsReal, rhsReal, fmfValue);
      Value lhsImagTimesRhsImag =
          arith::MulFOp::create(b, lhsImag, rhsImag, fmfValue);
      Value lhsImagTimesRhsReal =
          arith::MulFOp::create(b, lhsImag, rhsReal, fmfValue);
      Value lhsRealTimesRhsImag =
          arith::MulFOp::create(b, lhsReal, rhsImag, fmfValue);

      real = arith::SubFOp::create(b, lhsRealTimesRhsReal, lhsImagTimesRhsImag,
                                   fmfValue);
      imag = arith::AddFOp::create(b, lhsImagTimesRhsReal, lhsRealTimesRhsImag,
                                   fmfValue);
    }
    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, real, imag);
    return success();
  }
};

struct NegOpConversion : public OpConversionPattern<complex::NegOp> {
  using OpConversionPattern<complex::NegOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::NegOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto loc = op.getLoc();
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());

    Value real =
        complex::ReOp::create(rewriter, loc, elementType, adaptor.getComplex());
    Value imag =
        complex::ImOp::create(rewriter, loc, elementType, adaptor.getComplex());
    Value negReal = arith::NegFOp::create(rewriter, loc, real);
    Value negImag = arith::NegFOp::create(rewriter, loc, imag);
    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, negReal, negImag);
    return success();
  }
};

struct SinOpConversion : public TrigonometricOpConversion<complex::SinOp> {
  using TrigonometricOpConversion<complex::SinOp>::TrigonometricOpConversion;

  std::pair<Value, Value> combine(Location loc, Value scaledExp,
                                  Value reciprocalExp, Value sin, Value cos,
                                  ConversionPatternRewriter &rewriter,
                                  arith::FastMathFlagsAttr fmf) const override {
    // Complex sine is defined as;
    //   sin(x + iy) = -0.5i * (exp(i(x + iy)) - exp(-i(x + iy)))
    // Plugging in:
    //   exp(i(x+iy)) = exp(-y + ix) = exp(-y)(cos(x) + i sin(x))
    //   exp(-i(x+iy)) = exp(y + i(-x)) = exp(y)(cos(x) + i (-sin(x)))
    // and defining t := exp(y)
    // We get:
    //   Re(sin(x + iy)) = (0.5*t + 0.5/t) * sin x
    //   Im(sin(x + iy)) = (0.5*t - 0.5/t) * cos x
    Value sum =
        arith::AddFOp::create(rewriter, loc, scaledExp, reciprocalExp, fmf);
    Value resultReal = arith::MulFOp::create(rewriter, loc, sum, sin, fmf);
    Value diff =
        arith::SubFOp::create(rewriter, loc, scaledExp, reciprocalExp, fmf);
    Value resultImag = arith::MulFOp::create(rewriter, loc, diff, cos, fmf);
    return {resultReal, resultImag};
  }
};

// The algorithm is listed in https://dl.acm.org/doi/pdf/10.1145/363717.363780.
struct SqrtOpConversion : public OpConversionPattern<complex::SqrtOp> {
  using OpConversionPattern<complex::SqrtOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::SqrtOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    ImplicitLocOpBuilder b(op.getLoc(), rewriter);

    auto type = cast<ComplexType>(op.getType());
    auto elementType = cast<FloatType>(type.getElementType());
    arith::FastMathFlags fmf = op.getFastMathFlagsAttr().getValue();

    auto cst = [&](APFloat v) {
      return arith::ConstantOp::create(b, elementType,
                                       b.getFloatAttr(elementType, v));
    };
    const auto &floatSemantics = elementType.getFloatSemantics();
    Value zero = cst(APFloat::getZero(floatSemantics));
    Value half = arith::ConstantOp::create(b, elementType,
                                           b.getFloatAttr(elementType, 0.5));

    Value real = complex::ReOp::create(b, elementType, adaptor.getComplex());
    Value imag = complex::ImOp::create(b, elementType, adaptor.getComplex());
    Value absSqrt = computeAbs(real, imag, fmf, b, AbsFn::sqrt);
    Value argArg = math::Atan2Op::create(b, imag, real, fmf);
    Value sqrtArg = arith::MulFOp::create(b, argArg, half, fmf);
    Value cos = math::CosOp::create(b, sqrtArg, fmf);
    Value sin = math::SinOp::create(b, sqrtArg, fmf);
    // sin(atan2(0, inf)) = 0, sqrt(abs(inf)) = inf, but we can't multiply
    // 0 * inf.
    Value sinIsZero =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, sin, zero, fmf);

    Value resultReal = arith::MulFOp::create(b, absSqrt, cos, fmf);
    Value resultImag = arith::SelectOp::create(
        b, sinIsZero, zero, arith::MulFOp::create(b, absSqrt, sin, fmf));
    if (!arith::bitEnumContainsAll(fmf, arith::FastMathFlags::nnan |
                                            arith::FastMathFlags::ninf)) {
      Value inf = cst(APFloat::getInf(floatSemantics));
      Value negInf = cst(APFloat::getInf(floatSemantics, true));
      Value nan = cst(APFloat::getNaN(floatSemantics));
      Value absImag = math::AbsFOp::create(b, elementType, imag, fmf);

      Value absImagIsInf = arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ,
                                                 absImag, inf, fmf);
      Value absImagIsNotInf = arith::CmpFOp::create(
          b, arith::CmpFPredicate::ONE, absImag, inf, fmf);
      Value realIsInf =
          arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, real, inf, fmf);
      Value realIsNegInf = arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ,
                                                 real, negInf, fmf);

      resultReal = arith::SelectOp::create(
          b, arith::AndIOp::create(b, realIsNegInf, absImagIsNotInf), zero,
          resultReal);
      resultReal = arith::SelectOp::create(
          b, arith::OrIOp::create(b, absImagIsInf, realIsInf), inf, resultReal);

      Value imagSignInf = math::CopySignOp::create(b, inf, imag, fmf);
      resultImag = arith::SelectOp::create(
          b,
          arith::CmpFOp::create(b, arith::CmpFPredicate::UNO, absSqrt, absSqrt),
          nan, resultImag);
      resultImag = arith::SelectOp::create(
          b, arith::OrIOp::create(b, absImagIsInf, realIsNegInf), imagSignInf,
          resultImag);
    }

    Value resultIsZero =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, absSqrt, zero, fmf);
    resultReal = arith::SelectOp::create(b, resultIsZero, zero, resultReal);
    resultImag = arith::SelectOp::create(b, resultIsZero, zero, resultImag);

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);
    return success();
  }
};

struct SignOpConversion : public OpConversionPattern<complex::SignOp> {
  using OpConversionPattern<complex::SignOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::SignOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();

    Value real = complex::ReOp::create(b, elementType, adaptor.getComplex());
    Value imag = complex::ImOp::create(b, elementType, adaptor.getComplex());
    Value zero =
        arith::ConstantOp::create(b, elementType, b.getZeroAttr(elementType));
    Value realIsZero =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, real, zero);
    Value imagIsZero =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, imag, zero);
    Value isZero = arith::AndIOp::create(b, realIsZero, imagIsZero);
    auto abs =
        complex::AbsOp::create(b, elementType, adaptor.getComplex(), fmf);
    Value realSign = arith::DivFOp::create(b, real, abs, fmf);
    Value imagSign = arith::DivFOp::create(b, imag, abs, fmf);
    Value sign = complex::CreateOp::create(b, type, realSign, imagSign);
    rewriter.replaceOpWithNewOp<arith::SelectOp>(op, isZero,
                                                 adaptor.getComplex(), sign);
    return success();
  }
};

template <typename Op>
struct TanTanhOpConversion : public OpConversionPattern<Op> {
  using OpConversionPattern<Op>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(Op op, typename Op::Adaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    ImplicitLocOpBuilder b(op.getLoc(), rewriter);
    auto loc = op.getLoc();
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    arith::FastMathFlags fmf = op.getFastMathFlagsAttr().getValue();
    const auto &floatSemantics = elementType.getFloatSemantics();

    Value real =
        complex::ReOp::create(b, loc, elementType, adaptor.getComplex());
    Value imag =
        complex::ImOp::create(b, loc, elementType, adaptor.getComplex());
    Value negOne = arith::ConstantOp::create(b, elementType,
                                             b.getFloatAttr(elementType, -1.0));

    if constexpr (std::is_same_v<Op, complex::TanOp>) {
      // tan(x+yi) = -i*tanh(-y + xi)
      std::swap(real, imag);
      real = arith::MulFOp::create(b, real, negOne, fmf);
    }

    auto cst = [&](APFloat v) {
      return arith::ConstantOp::create(b, elementType,
                                       b.getFloatAttr(elementType, v));
    };
    Value inf = cst(APFloat::getInf(floatSemantics));
    Value four = arith::ConstantOp::create(b, elementType,
                                           b.getFloatAttr(elementType, 4.0));
    Value twoReal = arith::AddFOp::create(b, real, real, fmf);
    Value negTwoReal = arith::MulFOp::create(b, negOne, twoReal, fmf);

    Value expTwoRealMinusOne = math::ExpM1Op::create(b, twoReal, fmf);
    Value expNegTwoRealMinusOne = math::ExpM1Op::create(b, negTwoReal, fmf);
    Value realNum = arith::SubFOp::create(b, expTwoRealMinusOne,
                                          expNegTwoRealMinusOne, fmf);

    Value cosImag = math::CosOp::create(b, imag, fmf);
    Value cosImagSq = arith::MulFOp::create(b, cosImag, cosImag, fmf);
    Value twoCosTwoImagPlusOne = arith::MulFOp::create(b, cosImagSq, four, fmf);
    Value sinImag = math::SinOp::create(b, imag, fmf);

    Value imagNum = arith::MulFOp::create(
        b, four, arith::MulFOp::create(b, cosImag, sinImag, fmf), fmf);

    Value expSumMinusTwo = arith::AddFOp::create(b, expTwoRealMinusOne,
                                                 expNegTwoRealMinusOne, fmf);
    Value denom =
        arith::AddFOp::create(b, expSumMinusTwo, twoCosTwoImagPlusOne, fmf);

    Value isInf = arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ,
                                        expSumMinusTwo, inf, fmf);
    Value realLimit = math::CopySignOp::create(b, negOne, real, fmf);

    Value resultReal = arith::SelectOp::create(
        b, isInf, realLimit, arith::DivFOp::create(b, realNum, denom, fmf));
    Value resultImag = arith::DivFOp::create(b, imagNum, denom, fmf);

    if (!arith::bitEnumContainsAll(fmf, arith::FastMathFlags::nnan |
                                            arith::FastMathFlags::ninf)) {
      Value absReal = math::AbsFOp::create(b, real, fmf);
      Value zero = arith::ConstantOp::create(b, elementType,
                                             b.getFloatAttr(elementType, 0.0));
      Value nan = cst(APFloat::getNaN(floatSemantics));

      Value absRealIsInf = arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ,
                                                 absReal, inf, fmf);
      Value imagIsZero =
          arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, imag, zero, fmf);
      Value absRealIsNotInf = arith::XOrIOp::create(
          b, absRealIsInf, arith::ConstantIntOp::create(b, true, /*width=*/1));

      Value imagNumIsNaN = arith::CmpFOp::create(b, arith::CmpFPredicate::UNO,
                                                 imagNum, imagNum, fmf);
      Value resultRealIsNaN =
          arith::AndIOp::create(b, imagNumIsNaN, absRealIsNotInf);
      Value resultImagIsZero = arith::OrIOp::create(
          b, imagIsZero, arith::AndIOp::create(b, absRealIsInf, imagNumIsNaN));

      resultReal = arith::SelectOp::create(b, resultRealIsNaN, nan, resultReal);
      resultImag =
          arith::SelectOp::create(b, resultImagIsZero, zero, resultImag);
    }

    if constexpr (std::is_same_v<Op, complex::TanOp>) {
      // tan(x+yi) = -i*tanh(-y + xi)
      std::swap(resultReal, resultImag);
      resultImag = arith::MulFOp::create(b, resultImag, negOne, fmf);
    }

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);
    return success();
  }
};

struct ConjOpConversion : public OpConversionPattern<complex::ConjOp> {
  using OpConversionPattern<complex::ConjOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::ConjOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto loc = op.getLoc();
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());
    Value real =
        complex::ReOp::create(rewriter, loc, elementType, adaptor.getComplex());
    Value imag =
        complex::ImOp::create(rewriter, loc, elementType, adaptor.getComplex());
    Value negImag = arith::NegFOp::create(rewriter, loc, elementType, imag);

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, real, negImag);

    return success();
  }
};

/// Converts lhs^y = (a+bi)^(c+di) to
///    (a*a+b*b)^(0.5c) * exp(-d*atan2(b,a)) * (cos(q) + i*sin(q)),
///    where q = c*atan2(b,a)+0.5d*ln(a*a+b*b)
static Value powOpConversionImpl(mlir::ImplicitLocOpBuilder &builder,
                                 ComplexType type, Value lhs, Value c, Value d,
                                 arith::FastMathFlags fmf) {
  auto elementType = cast<FloatType>(type.getElementType());

  Value a = complex::ReOp::create(builder, lhs);
  Value b = complex::ImOp::create(builder, lhs);

  Value abs = complex::AbsOp::create(builder, lhs, fmf);
  Value absToC = math::PowFOp::create(builder, abs, c, fmf);

  Value negD = arith::NegFOp::create(builder, d, fmf);
  Value argLhs = math::Atan2Op::create(builder, b, a, fmf);
  Value negDArgLhs = arith::MulFOp::create(builder, negD, argLhs, fmf);
  Value expNegDArgLhs = math::ExpOp::create(builder, negDArgLhs, fmf);

  Value coeff = arith::MulFOp::create(builder, absToC, expNegDArgLhs, fmf);
  Value lnAbs = math::LogOp::create(builder, abs, fmf);
  Value cArgLhs = arith::MulFOp::create(builder, c, argLhs, fmf);
  Value dLnAbs = arith::MulFOp::create(builder, d, lnAbs, fmf);
  Value q = arith::AddFOp::create(builder, cArgLhs, dLnAbs, fmf);
  Value cosQ = math::CosOp::create(builder, q, fmf);
  Value sinQ = math::SinOp::create(builder, q, fmf);

  Value inf = arith::ConstantOp::create(
      builder, elementType,
      builder.getFloatAttr(elementType,
                           APFloat::getInf(elementType.getFloatSemantics())));
  Value zero = arith::ConstantOp::create(
      builder, elementType, builder.getFloatAttr(elementType, 0.0));
  Value one = arith::ConstantOp::create(builder, elementType,
                                        builder.getFloatAttr(elementType, 1.0));
  Value complexOne = complex::CreateOp::create(builder, type, one, zero);
  Value complexZero = complex::CreateOp::create(builder, type, zero, zero);
  Value complexInf = complex::CreateOp::create(builder, type, inf, zero);

  // Case 0:
  // d^c is 0 if d is 0 and c > 0. 0^0 is defined to be 1.0, see
  // Branch Cuts for Complex Elementary Functions or Much Ado About
  // Nothing's Sign Bit, W. Kahan, Section 10.
  Value absEqZero =
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OEQ, abs, zero, fmf);
  Value dEqZero =
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OEQ, d, zero, fmf);
  Value cEqZero =
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OEQ, c, zero, fmf);
  Value bEqZero =
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OEQ, b, zero, fmf);

  Value zeroLeC =
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OLE, zero, c, fmf);
  Value coeffCosQ = arith::MulFOp::create(builder, coeff, cosQ, fmf);
  Value coeffSinQ = arith::MulFOp::create(builder, coeff, sinQ, fmf);
  Value complexOneOrZero =
      arith::SelectOp::create(builder, cEqZero, complexOne, complexZero);
  Value coeffCosSin =
      complex::CreateOp::create(builder, type, coeffCosQ, coeffSinQ);
  Value cutoff0 = arith::SelectOp::create(
      builder,
      arith::AndIOp::create(
          builder, arith::AndIOp::create(builder, absEqZero, dEqZero), zeroLeC),
      complexOneOrZero, coeffCosSin);

  // Case 1:
  // x^0 is defined to be 1 for any x, see
  // Branch Cuts for Complex Elementary Functions or Much Ado About
  // Nothing's Sign Bit, W. Kahan, Section 10.
  Value rhsEqZero = arith::AndIOp::create(builder, cEqZero, dEqZero);
  Value cutoff1 =
      arith::SelectOp::create(builder, rhsEqZero, complexOne, cutoff0);

  // Case 2:
  // 1^(c + d*i) = 1 + 0*i
  Value lhsEqOne = arith::AndIOp::create(
      builder,
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OEQ, a, one, fmf),
      bEqZero);
  Value cutoff2 =
      arith::SelectOp::create(builder, lhsEqOne, complexOne, cutoff1);

  // Case 3:
  // inf^(c + 0*i) = inf + 0*i, c > 0
  Value lhsEqInf = arith::AndIOp::create(
      builder,
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OEQ, a, inf, fmf),
      bEqZero);
  Value rhsGt0 = arith::AndIOp::create(
      builder, dEqZero,
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OGT, c, zero, fmf));
  Value cutoff3 = arith::SelectOp::create(
      builder, arith::AndIOp::create(builder, lhsEqInf, rhsGt0), complexInf,
      cutoff2);

  // Case 4:
  // inf^(c + 0*i) = 0 + 0*i, c < 0
  Value rhsLt0 = arith::AndIOp::create(
      builder, dEqZero,
      arith::CmpFOp::create(builder, arith::CmpFPredicate::OLT, c, zero, fmf));
  Value cutoff4 = arith::SelectOp::create(
      builder, arith::AndIOp::create(builder, lhsEqInf, rhsLt0), complexZero,
      cutoff3);

  return cutoff4;
}

struct PowiOpConversion : public OpConversionPattern<complex::PowiOp> {
  using OpConversionPattern<complex::PowiOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::PowiOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    ImplicitLocOpBuilder builder(op.getLoc(), rewriter);
    auto type = cast<ComplexType>(op.getType());
    auto elementType = cast<FloatType>(type.getElementType());

    Value floatExponent =
        arith::SIToFPOp::create(builder, elementType, adaptor.getRhs());
    Value zero = arith::ConstantOp::create(
        builder, elementType, builder.getFloatAttr(elementType, 0.0));
    Value complexExponent =
        complex::CreateOp::create(builder, type, floatExponent, zero);

    auto pow = complex::PowOp::create(builder, type, adaptor.getLhs(),
                                      complexExponent, op.getFastmathAttr());
    rewriter.replaceOp(op, pow.getResult());
    return success();
  }
};

struct PowOpConversion : public OpConversionPattern<complex::PowOp> {
  using OpConversionPattern<complex::PowOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::PowOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    mlir::ImplicitLocOpBuilder builder(op.getLoc(), rewriter);
    auto type = cast<ComplexType>(adaptor.getLhs().getType());
    auto elementType = cast<FloatType>(type.getElementType());

    Value c = complex::ReOp::create(builder, elementType, adaptor.getRhs());
    Value d = complex::ImOp::create(builder, elementType, adaptor.getRhs());

    rewriter.replaceOp(op, {powOpConversionImpl(builder, type, adaptor.getLhs(),
                                                c, d, op.getFastmath())});
    return success();
  }
};

struct RsqrtOpConversion : public OpConversionPattern<complex::RsqrtOp> {
  using OpConversionPattern<complex::RsqrtOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::RsqrtOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    mlir::ImplicitLocOpBuilder b(op.getLoc(), rewriter);
    auto type = cast<ComplexType>(adaptor.getComplex().getType());
    auto elementType = cast<FloatType>(type.getElementType());

    arith::FastMathFlags fmf = op.getFastMathFlagsAttr().getValue();

    auto cst = [&](APFloat v) {
      return arith::ConstantOp::create(b, elementType,
                                       b.getFloatAttr(elementType, v));
    };
    const auto &floatSemantics = elementType.getFloatSemantics();
    Value zero = cst(APFloat::getZero(floatSemantics));
    Value inf = cst(APFloat::getInf(floatSemantics));
    Value negHalf = arith::ConstantOp::create(
        b, elementType, b.getFloatAttr(elementType, -0.5));
    Value nan = cst(APFloat::getNaN(floatSemantics));

    Value real = complex::ReOp::create(b, elementType, adaptor.getComplex());
    Value imag = complex::ImOp::create(b, elementType, adaptor.getComplex());
    Value absRsqrt = computeAbs(real, imag, fmf, b, AbsFn::rsqrt);
    Value argArg = math::Atan2Op::create(b, imag, real, fmf);
    Value rsqrtArg = arith::MulFOp::create(b, argArg, negHalf, fmf);
    Value cos = math::CosOp::create(b, rsqrtArg, fmf);
    Value sin = math::SinOp::create(b, rsqrtArg, fmf);

    Value resultReal = arith::MulFOp::create(b, absRsqrt, cos, fmf);
    Value resultImag = arith::MulFOp::create(b, absRsqrt, sin, fmf);

    if (!arith::bitEnumContainsAll(fmf, arith::FastMathFlags::nnan |
                                            arith::FastMathFlags::ninf)) {
      Value negOne = arith::ConstantOp::create(b, elementType,
                                               b.getFloatAttr(elementType, -1));

      Value realSignedZero = math::CopySignOp::create(b, zero, real, fmf);
      Value imagSignedZero = math::CopySignOp::create(b, zero, imag, fmf);
      Value negImagSignedZero =
          arith::MulFOp::create(b, negOne, imagSignedZero, fmf);

      Value absReal = math::AbsFOp::create(b, real, fmf);
      Value absImag = math::AbsFOp::create(b, imag, fmf);

      Value absImagIsInf = arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ,
                                                 absImag, inf, fmf);
      Value realIsNan =
          arith::CmpFOp::create(b, arith::CmpFPredicate::UNO, real, real, fmf);
      Value realIsInf = arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ,
                                              absReal, inf, fmf);
      Value inIsNanInf = arith::AndIOp::create(b, absImagIsInf, realIsNan);

      Value resultIsZero = arith::OrIOp::create(b, inIsNanInf, realIsInf);

      resultReal =
          arith::SelectOp::create(b, resultIsZero, realSignedZero, resultReal);
      resultImag = arith::SelectOp::create(b, resultIsZero, negImagSignedZero,
                                           resultImag);
    }

    Value isRealZero =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, real, zero, fmf);
    Value isImagZero =
        arith::CmpFOp::create(b, arith::CmpFPredicate::OEQ, imag, zero, fmf);
    Value isZero = arith::AndIOp::create(b, isRealZero, isImagZero);

    resultReal = arith::SelectOp::create(b, isZero, inf, resultReal);
    resultImag = arith::SelectOp::create(b, isZero, nan, resultImag);

    rewriter.replaceOpWithNewOp<complex::CreateOp>(op, type, resultReal,
                                                   resultImag);
    return success();
  }
};

struct AngleOpConversion : public OpConversionPattern<complex::AngleOp> {
  using OpConversionPattern<complex::AngleOp>::OpConversionPattern;

  LogicalResult
  matchAndRewrite(complex::AngleOp op, OpAdaptor adaptor,
                  ConversionPatternRewriter &rewriter) const override {
    auto loc = op.getLoc();
    auto type = op.getType();
    arith::FastMathFlagsAttr fmf = op.getFastMathFlagsAttr();

    Value real =
        complex::ReOp::create(rewriter, loc, type, adaptor.getComplex());
    Value imag =
        complex::ImOp::create(rewriter, loc, type, adaptor.getComplex());

    rewriter.replaceOpWithNewOp<math::Atan2Op>(op, imag, real, fmf);

    return success();
  }
};

} // namespace

void mlir::populateComplexToStandardConversionPatterns(
    RewritePatternSet &patterns, complex::ComplexRangeFlags complexRange) {
  // clang-format off
  patterns.add<
      AbsOpConversion,
      AngleOpConversion,
      Atan2OpConversion,
      BinaryComplexOpConversion<complex::AddOp, arith::AddFOp>,
      BinaryComplexOpConversion<complex::SubOp, arith::SubFOp>,
      ComparisonOpConversion<complex::EqualOp, arith::CmpFPredicate::OEQ>,
      ComparisonOpConversion<complex::NotEqualOp, arith::CmpFPredicate::UNE>,
      ConjOpConversion,
      CosOpConversion,
      ExpOpConversion,
      Expm1OpConversion,
      Log1pOpConversion,
      LogOpConversion,
      MulOpConversion,
      NegOpConversion,
      SignOpConversion,
      SinOpConversion,
      SqrtOpConversion,
      TanTanhOpConversion<complex::TanOp>,
      TanTanhOpConversion<complex::TanhOp>,
      PowiOpConversion,
      PowOpConversion,
      RsqrtOpConversion
  >(patterns.getContext());

    patterns.add<DivOpConversion>(patterns.getContext(), complexRange);

  // clang-format on
}

namespace {
struct ConvertComplexToStandardPass
    : public impl::ConvertComplexToStandardPassBase<
          ConvertComplexToStandardPass> {
  using Base::Base;

  void runOnOperation() override;
};

void ConvertComplexToStandardPass::runOnOperation() {
  // Convert to the Standard dialect using the converter defined above.
  RewritePatternSet patterns(&getContext());
  populateComplexToStandardConversionPatterns(patterns, complexRange);

  ConversionTarget target(getContext());
  target.addLegalDialect<arith::ArithDialect, math::MathDialect>();
  target.addLegalOp<complex::CreateOp, complex::ImOp, complex::ReOp>();
  if (failed(
          applyPartialConversion(getOperation(), target, std::move(patterns))))
    signalPassFailure();
}
} // namespace
