diff --git a/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp b/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp --- a/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp +++ b/mlir/lib/Conversion/ComplexToStandard/ComplexToStandard.cpp @@ -728,6 +728,33 @@ return success(); } }; + +struct TanhOpConversion : public OpConversionPattern { + using OpConversionPattern::OpConversionPattern; + + LogicalResult + matchAndRewrite(complex::TanhOp op, OpAdaptor adaptor, + ConversionPatternRewriter &rewriter) const override { + auto loc = op.getLoc(); + auto type = adaptor.getComplex().getType().cast(); + auto elementType = type.getElementType().cast(); + Value real = + rewriter.create(loc, elementType, adaptor.getComplex()); + Value imag = + rewriter.create(loc, elementType, adaptor.getComplex()); + Value tanhA = rewriter.create(loc, real); + Value cosB = rewriter.create(loc, imag); + Value sinB = rewriter.create(loc, imag); + Value tanB = rewriter.create(loc, sinB, cosB); + Value numerator = rewriter.create(loc, type, tanhA, tanB); + Value one = rewriter.create( + loc, elementType, rewriter.getFloatAttr(elementType, 1)); + Value mul = rewriter.create(loc, tanhA, tanB); + Value denominator = rewriter.create(loc, type, one, mul); + rewriter.replaceOpWithNewOp(op, numerator, denominator); + return success(); + } +}; } // namespace void mlir::populateComplexToStandardConversionPatterns( @@ -748,7 +775,8 @@ MulOpConversion, NegOpConversion, SignOpConversion, - SinOpConversion>(patterns.getContext()); + SinOpConversion, + TanhOpConversion>(patterns.getContext()); // clang-format on } diff --git a/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir b/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir --- a/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir +++ b/mlir/test/Conversion/ComplexToStandard/convert-to-standard.mlir @@ -459,3 +459,20 @@ // CHECK: %[[RESULT_IMAG:.*]] = arith.subf %[[IMAG_LHS]], %[[IMAG_RHS]] : f32 // CHECK: %[[RESULT:.*]] = complex.create %[[RESULT_REAL]], %[[RESULT_IMAG]] : complex // CHECK: return %[[RESULT]] : complex + +// CHECK-LABEL: func @complex_tanh +// CHECK-SAME: %[[ARG:.*]]: complex +func.func @complex_tanh(%arg: complex) -> complex { + %tanh = complex.tanh %arg: complex + return %tanh : complex +} +// CHECK: %[[REAL:.*]] = complex.re %[[ARG]] : complex +// CHECK: %[[IMAG:.*]] = complex.im %[[ARG]] : complex +// CHECK: %[[TANH_A:.*]] = math.tanh %[[REAL]] : f32 +// CHECK: %[[COS_B:.*]] = math.cos %[[IMAG]] : f32 +// CHECK: %[[SIN_B:.*]] = math.sin %[[IMAG]] : f32 +// CHECK: %[[TAN_B:.*]] = arith.divf %[[SIN_B]], %[[COS_B]] : f32 +// CHECK: %[[NUM:.*]] = complex.create %[[TANH_A]], %[[TAN_B]] : complex +// CHECK: %[[ONE:.*]] = arith.constant 1.000000e+00 : f32 +// CHECK: %[[MUL:.*]] = arith.mulf %[[TANH_A]], %[[TAN_B]] : f32 +// CHECK: %[[DENOM:.*]] = complex.create %[[ONE]], %[[MUL]] : complex \ No newline at end of file