[flang] Add cpowi function to runtime and use instead of pgmath
[platform/upstream/llvm.git] / flang / unittests / Runtime / Complex.cpp
1 //===-- flang/unittests/Runtime/Complex.cpp ---------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "gmock/gmock.h"
9 #include "gtest/gtest-matchers.h"
10 #include <limits>
11
12 #ifdef __clang__
13 #pragma clang diagnostic ignored "-Wc99-extensions"
14 #endif
15
16 #include "flang/Common/Fortran.h"
17 #include "flang/Runtime/cpp-type.h"
18 #include "flang/Runtime/entry-names.h"
19
20 #include <complex>
21 #include <cstdint>
22
23 #ifndef _MSC_VER
24 #include <complex.h>
25 typedef float _Complex float_Complex_t;
26 typedef double _Complex double_Complex_t;
27 #else
28 struct float_Complex_t {
29   float re;
30   float im;
31 };
32 struct double_Complex_t {
33   double re;
34   double im;
35 };
36 #endif
37
38 extern "C" float_Complex_t RTNAME(cpowi)(
39     float_Complex_t base, std::int32_t exp);
40
41 extern "C" double_Complex_t RTNAME(zpowi)(
42     double_Complex_t base, std::int32_t exp);
43
44 extern "C" float_Complex_t RTNAME(cpowk)(
45     float_Complex_t base, std::int64_t exp);
46
47 extern "C" double_Complex_t RTNAME(zpowk)(
48     double_Complex_t base, std::int64_t exp);
49
50 static std::complex<float> cpowi(std::complex<float> base, std::int32_t exp) {
51   float_Complex_t cbase{*(float_Complex_t *)(&base)};
52   float_Complex_t cres{RTNAME(cpowi)(cbase, exp)};
53   return *(std::complex<float> *)(&cres);
54 }
55
56 static std::complex<double> zpowi(std::complex<double> base, std::int32_t exp) {
57   double_Complex_t cbase{*(double_Complex_t *)(&base)};
58   double_Complex_t cres{RTNAME(zpowi)(cbase, exp)};
59   return *(std::complex<double> *)(&cres);
60 }
61
62 static std::complex<float> cpowk(std::complex<float> base, std::int64_t exp) {
63   float_Complex_t cbase{*(float_Complex_t *)(&base)};
64   float_Complex_t cres{RTNAME(cpowk)(cbase, exp)};
65   return *(std::complex<float> *)(&cres);
66 }
67
68 static std::complex<double> zpowk(std::complex<double> base, std::int64_t exp) {
69   double_Complex_t cbase{*(double_Complex_t *)(&base)};
70   double_Complex_t cres{RTNAME(zpowk)(cbase, exp)};
71   return *(std::complex<double> *)(&cres);
72 }
73
74 MATCHER_P(ExpectComplexFloatEq, c, "") {
75   using namespace testing;
76   return ExplainMatchResult(
77       AllOf(Property(&std::complex<float>::real, FloatEq(c.real())),
78           Property(&std::complex<float>::imag, FloatEq(c.imag()))),
79       arg, result_listener);
80 }
81
82 MATCHER_P(ExpectComplexDoubleEq, c, "") {
83   using namespace testing;
84   return ExplainMatchResult(AllOf(Property(&std::complex<double>::real,
85                                       DoubleNear(c.real(), 0.00000001)),
86                                 Property(&std::complex<double>::imag,
87                                     DoubleNear(c.imag(), 0.00000001))),
88       arg, result_listener);
89 }
90
91 #define EXPECT_COMPLEX_FLOAT_EQ(val1, val2) \
92   EXPECT_THAT(val1, ExpectComplexFloatEq(val2))
93
94 #define EXPECT_COMPLEX_DOUBLE_EQ(val1, val2) \
95   EXPECT_THAT(val1, ExpectComplexDoubleEq(val2))
96
97 using namespace std::literals::complex_literals;
98
99 TEST(Complex, cpowi) {
100   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 0), 1.f + 0if);
101   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 1), 3.f + 4if);
102
103   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 2), -7.f + 24if);
104   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 3), -117.f + 44if);
105   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, 4), -527.f - 336if);
106
107   EXPECT_COMPLEX_FLOAT_EQ(cpowi(3.f + 4if, -2), -0.0112f - 0.0384if);
108   EXPECT_COMPLEX_FLOAT_EQ(cpowi(2.f + 1if, 10), -237.f - 3116if);
109   EXPECT_COMPLEX_FLOAT_EQ(cpowi(0.5f + 0.6if, -10), -9.322937f - 7.2984829if);
110
111   EXPECT_COMPLEX_FLOAT_EQ(cpowi(2.f + 1if, 5), -38.f + 41if);
112   EXPECT_COMPLEX_FLOAT_EQ(cpowi(0.5f + 0.6if, -5), -1.121837f + 3.252915if);
113
114   EXPECT_COMPLEX_FLOAT_EQ(
115       cpowi(0.f + 1if, std::numeric_limits<std::int32_t>::min()), 1.f + 0if);
116 }
117
118 TEST(Complex, cpowk) {
119   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 0), 1.f + 0if);
120   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 1), 3.f + 4if);
121   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 2), -7.f + 24if);
122   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 3), -117.f + 44if);
123   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, 4), -527.f - 336if);
124
125   EXPECT_COMPLEX_FLOAT_EQ(cpowk(3.f + 4if, -2), -0.0112f - 0.0384if);
126   EXPECT_COMPLEX_FLOAT_EQ(cpowk(2.f + 1if, 10), -237.f - 3116if);
127   EXPECT_COMPLEX_FLOAT_EQ(cpowk(0.5f + 0.6if, -10), -9.322937f - 7.2984829if);
128
129   EXPECT_COMPLEX_FLOAT_EQ(cpowk(2.f + 1if, 5), -38.f + 41if);
130   EXPECT_COMPLEX_FLOAT_EQ(cpowk(0.5f + 0.6if, -5), -1.121837f + 3.252915if);
131
132   EXPECT_COMPLEX_FLOAT_EQ(
133       cpowk(0.f + 1if, std::numeric_limits<std::int64_t>::min()), 1.f + 0if);
134 }
135
136 TEST(Complex, zpowi) {
137   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 0), 1. + 0i);
138   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 1), 3. + 4i);
139   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 2), -7. + 24i);
140   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 3), -117. + 44i);
141   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 4), -527. - 336i);
142
143   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, -2), -0.0112 - 0.0384i);
144   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 10), -237. - 3116i);
145   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
146
147   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 5), -38. + 41i);
148   EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
149
150   EXPECT_COMPLEX_DOUBLE_EQ(
151       zpowi(0. + 1i, std::numeric_limits<std::int32_t>::min()), 1. + 0i);
152 }
153
154 TEST(Complex, zpowk) {
155   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 0), 1. + 0i);
156   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 1), 3. + 4i);
157   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 2), -7. + 24i);
158   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 3), -117. + 44i);
159   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 4), -527. - 336i);
160
161   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, -2), -0.0112 - 0.0384i);
162   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(2. + 1i, 10), -237. - 3116i);
163   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
164
165   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(2. + 1i, 5l), -38. + 41i);
166   EXPECT_COMPLEX_DOUBLE_EQ(zpowk(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
167
168   EXPECT_COMPLEX_DOUBLE_EQ(
169       zpowk(0. + 1i, std::numeric_limits<std::int64_t>::min()), 1. + 0i);
170 }