Skip to content

Commit 1c6e09c

Browse files
authored
[flang] Added COMPLEX(16) ** INTEGER(4/8) lowering and runtime. (#84115)
1 parent 28e30b4 commit 1c6e09c

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,10 @@ constexpr auto FuncTypeComplex16Complex16 =
930930
genFuncType<Ty::Complex<16>, Ty::Complex<16>>;
931931
constexpr auto FuncTypeComplex16Complex16Complex16 =
932932
genFuncType<Ty::Complex<16>, Ty::Complex<16>, Ty::Complex<16>>;
933+
constexpr auto FuncTypeComplex16Complex16Integer4 =
934+
genFuncType<Ty::Complex<16>, Ty::Complex<16>, Ty::Integer<4>>;
935+
constexpr auto FuncTypeComplex16Complex16Integer8 =
936+
genFuncType<Ty::Complex<16>, Ty::Complex<16>, Ty::Integer<8>>;
933937

934938
static constexpr MathOperation mathOperations[] = {
935939
{"abs", "fabsf", genFuncType<Ty::Real<4>, Ty::Real<4>>,
@@ -1226,10 +1230,14 @@ static constexpr MathOperation mathOperations[] = {
12261230
genFuncType<Ty::Complex<4>, Ty::Complex<4>, Ty::Integer<4>>, genLibCall},
12271231
{"pow", RTNAME_STRING(zpowi),
12281232
genFuncType<Ty::Complex<8>, Ty::Complex<8>, Ty::Integer<4>>, genLibCall},
1233+
{"pow", RTNAME_STRING(cqpowi), FuncTypeComplex16Complex16Integer4,
1234+
genLibF128Call},
12291235
{"pow", RTNAME_STRING(cpowk),
12301236
genFuncType<Ty::Complex<4>, Ty::Complex<4>, Ty::Integer<8>>, genLibCall},
12311237
{"pow", RTNAME_STRING(zpowk),
12321238
genFuncType<Ty::Complex<8>, Ty::Complex<8>, Ty::Integer<8>>, genLibCall},
1239+
{"pow", RTNAME_STRING(cqpowk), FuncTypeComplex16Complex16Integer8,
1240+
genLibF128Call},
12331241
{"sign", "copysignf", genFuncType<Ty::Real<4>, Ty::Real<4>, Ty::Real<4>>,
12341242
genMathOp<mlir::math::CopySignOp>},
12351243
{"sign", "copysign", genFuncType<Ty::Real<8>, Ty::Real<8>, Ty::Real<8>>,

flang/runtime/complex-powi.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*
77
* ===-----------------------------------------------------------------------===
88
*/
9+
#include "flang/Common/float128.h"
910
#include "flang/Runtime/entry-names.h"
1011
#include <cstdint>
1112
#include <cstdio>
@@ -79,6 +80,30 @@ extern "C" double _Complex RTNAME(zpowk)(
7980
double _Complex base, std::int64_t exp) {
8081
return tgpowi(base, exp);
8182
}
83+
84+
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
85+
// Duplicate CFloat128ComplexType definition from flang/Common/float128.h.
86+
// float128.h does not define it for C++, because _Complex triggers
87+
// c99-extension warnings. We decided to disable warnings for this
88+
// particular file, so we can use _Complex here.
89+
#if LDBL_MANT_DIG == 113
90+
typedef long double _Complex Qcomplex;
91+
#elif HAS_FLOAT128
92+
#if !defined(_ARCH_PPC) || defined(__LONG_DOUBLE_IEEE128__)
93+
typedef _Complex float __attribute__((mode(TC))) Qcomplex;
94+
#else
95+
typedef _Complex float __attribute__((mode(KC))) Qcomplex;
96+
#endif
97+
#endif
98+
99+
extern "C" Qcomplex RTNAME(cqpowi)(Qcomplex base, std::int32_t exp) {
100+
return tgpowi(base, exp);
101+
}
102+
extern "C" Qcomplex RTNAME(cqpowk)(Qcomplex base, std::int64_t exp) {
103+
return tgpowi(base, exp);
104+
}
105+
#endif
106+
82107
#else
83108
// on MSVC, C complex is always just a struct of two members as it is not
84109
// supported as a builtin type. So we use C++ complex here as that has the
@@ -116,10 +141,28 @@ extern "C" Fcomplex RTNAME(cpowk)(Fcomplex base, std::int64_t exp) {
116141
return *(Fcomplex *)(&cppres);
117142
}
118143

119-
extern "C" Dcomplex RTNAME(zpowk)(Dcomplex base, std::int32_t exp) {
144+
extern "C" Dcomplex RTNAME(zpowk)(Dcomplex base, std::int64_t exp) {
120145
auto cppbase = *(std::complex<double> *)(&base);
121146
auto cppres = tgpowi(cppbase, exp);
122147
return *(Dcomplex *)(&cppres);
123148
}
124149

150+
#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
151+
struct Qcomplex {
152+
CFloat128Type re;
153+
CFloat128Type im;
154+
};
155+
156+
extern "C" Dcomplex RTNAME(cqpowi)(Qcomplex base, std::int32_t exp) {
157+
auto cppbase = *(std::complex<CFloat128Type> *)(&base);
158+
auto cppres = tgpowi(cppbase, exp);
159+
return *(Qcomplex *)(&cppres);
160+
}
161+
162+
extern "C" Dcomplex RTNAME(cqpowk)(Qcomplex base, std::int64_t exp) {
163+
auto cppbase = *(std::complex<CFloat128Type> *)(&base);
164+
auto cppres = tgpowi(cppbase, exp);
165+
return *(Qcomplex *)(&cppres);
166+
}
167+
#endif
125168
#endif
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s
3+
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
4+
5+
! CHECK: fir.call @_FortranAcqpowi({{.*}}){{.*}}: (!fir.complex<16>, i32) -> !fir.complex<16>
6+
complex(16) :: a
7+
integer(4) :: b
8+
b = a ** b
9+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s
3+
! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
4+
5+
! CHECK: fir.call @_FortranAcqpowk({{.*}}){{.*}}: (!fir.complex<16>, i64) -> !fir.complex<16>
6+
complex(16) :: a
7+
integer(8) :: b
8+
b = a ** b
9+
end

0 commit comments

Comments
 (0)