[flang-commits] [flang] 1c6e09c - [flang] Added COMPLEX(16) ** INTEGER(4/8) lowering and runtime. (#84115)
via flang-commits
flang-commits at lists.llvm.org
Wed Mar 6 08:17:13 PST 2024
Author: Slava Zakharin
Date: 2024-03-06T08:17:09-08:00
New Revision: 1c6e09c27f2216070abe5c268fb6269aeea97e68
URL: https://github.com/llvm/llvm-project/commit/1c6e09c27f2216070abe5c268fb6269aeea97e68
DIFF: https://github.com/llvm/llvm-project/commit/1c6e09c27f2216070abe5c268fb6269aeea97e68.diff
LOG: [flang] Added COMPLEX(16) ** INTEGER(4/8) lowering and runtime. (#84115)
Added:
flang/test/Lower/Intrinsics/pow_complex16i.f90
flang/test/Lower/Intrinsics/pow_complex16k.f90
Modified:
flang/lib/Optimizer/Builder/IntrinsicCall.cpp
flang/runtime/complex-powi.cpp
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 25598ed1683162..2f7ace658e4752 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -930,6 +930,10 @@ constexpr auto FuncTypeComplex16Complex16 =
genFuncType<Ty::Complex<16>, Ty::Complex<16>>;
constexpr auto FuncTypeComplex16Complex16Complex16 =
genFuncType<Ty::Complex<16>, Ty::Complex<16>, Ty::Complex<16>>;
+constexpr auto FuncTypeComplex16Complex16Integer4 =
+ genFuncType<Ty::Complex<16>, Ty::Complex<16>, Ty::Integer<4>>;
+constexpr auto FuncTypeComplex16Complex16Integer8 =
+ genFuncType<Ty::Complex<16>, Ty::Complex<16>, Ty::Integer<8>>;
static constexpr MathOperation mathOperations[] = {
{"abs", "fabsf", genFuncType<Ty::Real<4>, Ty::Real<4>>,
@@ -1226,10 +1230,14 @@ static constexpr MathOperation mathOperations[] = {
genFuncType<Ty::Complex<4>, Ty::Complex<4>, Ty::Integer<4>>, genLibCall},
{"pow", RTNAME_STRING(zpowi),
genFuncType<Ty::Complex<8>, Ty::Complex<8>, Ty::Integer<4>>, genLibCall},
+ {"pow", RTNAME_STRING(cqpowi), FuncTypeComplex16Complex16Integer4,
+ genLibF128Call},
{"pow", RTNAME_STRING(cpowk),
genFuncType<Ty::Complex<4>, Ty::Complex<4>, Ty::Integer<8>>, genLibCall},
{"pow", RTNAME_STRING(zpowk),
genFuncType<Ty::Complex<8>, Ty::Complex<8>, Ty::Integer<8>>, genLibCall},
+ {"pow", RTNAME_STRING(cqpowk), FuncTypeComplex16Complex16Integer8,
+ genLibF128Call},
{"sign", "copysignf", genFuncType<Ty::Real<4>, Ty::Real<4>, Ty::Real<4>>,
genMathOp<mlir::math::CopySignOp>},
{"sign", "copysign", genFuncType<Ty::Real<8>, Ty::Real<8>, Ty::Real<8>>,
diff --git a/flang/runtime/complex-powi.cpp b/flang/runtime/complex-powi.cpp
index 18723bb93cbf17..77031e40242791 100644
--- a/flang/runtime/complex-powi.cpp
+++ b/flang/runtime/complex-powi.cpp
@@ -6,6 +6,7 @@
*
* ===-----------------------------------------------------------------------===
*/
+#include "flang/Common/float128.h"
#include "flang/Runtime/entry-names.h"
#include <cstdint>
#include <cstdio>
@@ -79,6 +80,30 @@ extern "C" double _Complex RTNAME(zpowk)(
double _Complex base, std::int64_t exp) {
return tgpowi(base, exp);
}
+
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+// Duplicate CFloat128ComplexType definition from flang/Common/float128.h.
+// float128.h does not define it for C++, because _Complex triggers
+// c99-extension warnings. We decided to disable warnings for this
+// particular file, so we can use _Complex here.
+#if LDBL_MANT_DIG == 113
+typedef long double _Complex Qcomplex;
+#elif HAS_FLOAT128
+#if !defined(_ARCH_PPC) || defined(__LONG_DOUBLE_IEEE128__)
+typedef _Complex float __attribute__((mode(TC))) Qcomplex;
+#else
+typedef _Complex float __attribute__((mode(KC))) Qcomplex;
+#endif
+#endif
+
+extern "C" Qcomplex RTNAME(cqpowi)(Qcomplex base, std::int32_t exp) {
+ return tgpowi(base, exp);
+}
+extern "C" Qcomplex RTNAME(cqpowk)(Qcomplex base, std::int64_t exp) {
+ return tgpowi(base, exp);
+}
+#endif
+
#else
// on MSVC, C complex is always just a struct of two members as it is not
// 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) {
return *(Fcomplex *)(&cppres);
}
-extern "C" Dcomplex RTNAME(zpowk)(Dcomplex base, std::int32_t exp) {
+extern "C" Dcomplex RTNAME(zpowk)(Dcomplex base, std::int64_t exp) {
auto cppbase = *(std::complex<double> *)(&base);
auto cppres = tgpowi(cppbase, exp);
return *(Dcomplex *)(&cppres);
}
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+struct Qcomplex {
+ CFloat128Type re;
+ CFloat128Type im;
+};
+
+extern "C" Dcomplex RTNAME(cqpowi)(Qcomplex base, std::int32_t exp) {
+ auto cppbase = *(std::complex<CFloat128Type> *)(&base);
+ auto cppres = tgpowi(cppbase, exp);
+ return *(Qcomplex *)(&cppres);
+}
+
+extern "C" Dcomplex RTNAME(cqpowk)(Qcomplex base, std::int64_t exp) {
+ auto cppbase = *(std::complex<CFloat128Type> *)(&base);
+ auto cppres = tgpowi(cppbase, exp);
+ return *(Qcomplex *)(&cppres);
+}
+#endif
#endif
diff --git a/flang/test/Lower/Intrinsics/pow_complex16i.f90 b/flang/test/Lower/Intrinsics/pow_complex16i.f90
new file mode 100644
index 00000000000000..1cabaf94f8a605
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/pow_complex16i.f90
@@ -0,0 +1,9 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK: fir.call @_FortranAcqpowi({{.*}}){{.*}}: (!fir.complex<16>, i32) -> !fir.complex<16>
+ complex(16) :: a
+ integer(4) :: b
+ b = a ** b
+end
diff --git a/flang/test/Lower/Intrinsics/pow_complex16k.f90 b/flang/test/Lower/Intrinsics/pow_complex16k.f90
new file mode 100644
index 00000000000000..e3b1b4d31afa72
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/pow_complex16k.f90
@@ -0,0 +1,9 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: bbc --math-runtime=precise -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK: fir.call @_FortranAcqpowk({{.*}}){{.*}}: (!fir.complex<16>, i64) -> !fir.complex<16>
+ complex(16) :: a
+ integer(8) :: b
+ b = a ** b
+end
More information about the flang-commits
mailing list