aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorPeixin Qiao <qiaopeixin@huawei.com>2022-07-23 14:44:20 +0800
committerPeixin Qiao <qiaopeixin@huawei.com>2022-07-23 14:44:20 +0800
commit3ccd4ce29ca7f59eb12b077705cde2c11ac13aae (patch)
treeac0f4610effeb6d48913113937c29212a06bd82f /flang
parent33c18fbc190d3a1cd38f976b758026247120c412 (diff)
downloadllvm-3ccd4ce29ca7f59eb12b077705cde2c11ac13aae.zip
llvm-3ccd4ce29ca7f59eb12b077705cde2c11ac13aae.tar.gz
llvm-3ccd4ce29ca7f59eb12b077705cde2c11ac13aae.tar.bz2
[flang] Support aint/anint for 80/128 bit in lowering
For aint/anint, LLVM conversion operations llvm.trunc and llvm.round can support the edge case of aint(-0.) and anint(-0.). The output is -0. and it is the same of `gfortran` and `classic flang`, while the output of `ifort` is 0.. The `real(10)/real(16)` is not supported before. Support it and remove the runtime functions for aint/anint. For nint, `gfortran`, `ifort`, and LLVM Flang using llvm.lround have different results when the magnitude of argument is more than the max of result value range. So delay its support in lowering after more investigations. Reviewed By: vzakhari Differential Revision: https://reviews.llvm.org/D130024
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Runtime/numeric.h84
-rw-r--r--flang/lib/Lower/IntrinsicCall.cpp11
-rw-r--r--flang/runtime/numeric.cpp169
-rw-r--r--flang/test/Lower/Intrinsics/aint.f9042
-rw-r--r--flang/test/Lower/Intrinsics/anint.f9054
-rw-r--r--flang/test/Lower/math-lowering.f9036
-rw-r--r--flang/unittests/Runtime/Numeric.cpp22
7 files changed, 162 insertions, 256 deletions
diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index d68c5b4..42737a4 100644
--- a/flang/include/flang/Runtime/numeric.h
+++ b/flang/include/flang/Runtime/numeric.h
@@ -18,90 +18,6 @@
namespace Fortran::runtime {
extern "C" {
-// AINT
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)(
- CppTypeFor<TypeCategory::Real, 4>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)(
- CppTypeFor<TypeCategory::Real, 4>);
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
- CppTypeFor<TypeCategory::Real, 4>);
-#endif
-#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
- CppTypeFor<TypeCategory::Real, 4>);
-#endif
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)(
- CppTypeFor<TypeCategory::Real, 8>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
- CppTypeFor<TypeCategory::Real, 8>);
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)(
- CppTypeFor<TypeCategory::Real, 8>);
-#endif
-#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)(
- CppTypeFor<TypeCategory::Real, 8>);
-#endif
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint10_4)(
- CppTypeFor<TypeCategory::Real, 10>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint10_8)(
- CppTypeFor<TypeCategory::Real, 10>);
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
- CppTypeFor<TypeCategory::Real, 10>);
-#endif
-#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint16_4)(
- CppTypeFor<TypeCategory::Real, 16>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint16_8)(
- CppTypeFor<TypeCategory::Real, 16>);
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint16_16)(
- CppTypeFor<TypeCategory::Real, 16>);
-#endif
-
-// ANINT
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)(
- CppTypeFor<TypeCategory::Real, 4>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)(
- CppTypeFor<TypeCategory::Real, 4>);
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
- CppTypeFor<TypeCategory::Real, 4>);
-#endif
-#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
- CppTypeFor<TypeCategory::Real, 4>);
-#endif
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)(
- CppTypeFor<TypeCategory::Real, 8>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
- CppTypeFor<TypeCategory::Real, 8>);
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)(
- CppTypeFor<TypeCategory::Real, 8>);
-#endif
-#if LDBL_MANT_DIG == 113
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)(
- CppTypeFor<TypeCategory::Real, 8>);
-#endif
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint10_4)(
- CppTypeFor<TypeCategory::Real, 10>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint10_8)(
- CppTypeFor<TypeCategory::Real, 10>);
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
- CppTypeFor<TypeCategory::Real, 10>);
-#endif
-#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint16_4)(
- CppTypeFor<TypeCategory::Real, 16>);
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint16_8)(
- CppTypeFor<TypeCategory::Real, 16>);
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint16_16)(
- CppTypeFor<TypeCategory::Real, 16>);
-#endif
-
// CEILING
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)(
CppTypeFor<TypeCategory::Real, 4>);
diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 53f7d53..248bb1d 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -1045,6 +1045,11 @@ static mlir::FunctionType genF64F64FuncType(mlir::MLIRContext *context) {
return mlir::FunctionType::get(context, {t}, {t});
}
+static mlir::FunctionType genF80F80FuncType(mlir::MLIRContext *context) {
+ mlir::Type t = mlir::FloatType::getF80(context);
+ return mlir::FunctionType::get(context, {t}, {t});
+}
+
static mlir::FunctionType genF128F128FuncType(mlir::MLIRContext *context) {
mlir::Type t = mlir::FloatType::getF128(context);
return mlir::FunctionType::get(context, {t}, {t});
@@ -1190,11 +1195,17 @@ static constexpr MathOperation mathOperations[] = {
// llvm.trunc behaves the same way as libm's trunc.
{"aint", "llvm.trunc.f32", genF32F32FuncType, genLibCall},
{"aint", "llvm.trunc.f64", genF64F64FuncType, genLibCall},
+ {"aint", "llvm.trunc.f80", genF80F80FuncType, genLibCall},
+ {"aint", "llvm.trunc.f128", genF128F128FuncType, genLibCall},
// llvm.round behaves the same way as libm's round.
{"anint", "llvm.round.f32", genF32F32FuncType,
genMathOp<mlir::LLVM::RoundOp>},
{"anint", "llvm.round.f64", genF64F64FuncType,
genMathOp<mlir::LLVM::RoundOp>},
+ {"anint", "llvm.round.f80", genF80F80FuncType,
+ genMathOp<mlir::LLVM::RoundOp>},
+ {"anint", "llvm.round.f128", genF128F128FuncType,
+ genMathOp<mlir::LLVM::RoundOp>},
{"atan", "atanf", genF32F32FuncType, genMathOp<mlir::math::AtanOp>},
{"atan", "atan", genF64F64FuncType, genMathOp<mlir::math::AtanOp>},
{"atan2", "atan2f", genF32F32F32FuncType, genMathOp<mlir::math::Atan2Op>},
diff --git a/flang/runtime/numeric.cpp b/flang/runtime/numeric.cpp
index a989d3a..7ab1f13 100644
--- a/flang/runtime/numeric.cpp
+++ b/flang/runtime/numeric.cpp
@@ -16,13 +16,8 @@
namespace Fortran::runtime {
-// AINT
-template <typename RESULT, typename ARG> inline RESULT Aint(ARG x) {
- return std::trunc(x);
-}
-
-// ANINT & NINT
-template <typename RESULT, typename ARG> inline RESULT Anint(ARG x) {
+// NINT (16.9.141)
+template <typename RESULT, typename ARG> inline RESULT Nint(ARG x) {
if (x >= 0) {
return std::trunc(x + ARG{0.5});
} else {
@@ -163,126 +158,6 @@ template <int PREC, typename T> inline T Nearest(T x, bool positive) {
extern "C" {
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
-}
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
-}
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint10_4)(
- CppTypeFor<TypeCategory::Real, 10> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint10_8)(
- CppTypeFor<TypeCategory::Real, 10> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
- CppTypeFor<TypeCategory::Real, 10> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
-}
-#elif LDBL_MANT_DIG == 113
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
-}
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
-}
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint16_4)(
- CppTypeFor<TypeCategory::Real, 16> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint16_8)(
- CppTypeFor<TypeCategory::Real, 16> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint16_16)(
- CppTypeFor<TypeCategory::Real, 16> x) {
- return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
-}
-#endif
-
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-#if LDBL_MANT_DIG == 64
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
-}
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
-}
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint10_4)(
- CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint10_8)(
- CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
- CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
-}
-#elif LDBL_MANT_DIG == 113
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
- CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
-}
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)(
- CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
-}
-CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint16_4)(
- CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
-}
-CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint16_8)(
- CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
-}
-CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint16_16)(
- CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
-}
-#endif
-
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)(
CppTypeFor<TypeCategory::Real, 4> x) {
return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
@@ -689,92 +564,92 @@ CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
}
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint4_2)(
CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
}
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint4_4)(
CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
}
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint4_8)(
CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint4_16)(
CppTypeFor<TypeCategory::Real, 4> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint8_1)(
CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
}
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint8_2)(
CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
}
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint8_4)(
CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
}
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
CppTypeFor<TypeCategory::Real, 8> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#if LDBL_MANT_DIG == 64
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
}
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
}
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint10_4)(
CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
}
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
CppTypeFor<TypeCategory::Real, 10> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#elif LDBL_MANT_DIG == 113
CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
}
CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
}
CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
}
CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
CppTypeFor<TypeCategory::Real, 16> x) {
- return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
+ return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
}
#endif
#endif
diff --git a/flang/test/Lower/Intrinsics/aint.f90 b/flang/test/Lower/Intrinsics/aint.f90
index dd42f86..1d58a03 100644
--- a/flang/test/Lower/Intrinsics/aint.f90
+++ b/flang/test/Lower/Intrinsics/aint.f90
@@ -10,3 +10,45 @@ subroutine aint_test(a, b)
real :: a, b
b = aint(a)
end subroutine
+
+! CHECK-LABEL: func.func @_QPaint_test_real8(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f64> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f64> {fir.bindc_name = "b"}) {
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<f64>
+! CHECK: %[[VAL_3:.*]] = fir.call @llvm.trunc.f64(%[[VAL_2]]) : (f64) -> f64
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f64>
+! CHECK: return
+! CHECK: }
+
+subroutine aint_test_real8(a, b)
+ real(8) :: a, b
+ b = aint(a)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPaint_test_real10(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f80> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f80> {fir.bindc_name = "b"}) {
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<f80>
+! CHECK: %[[VAL_3:.*]] = fir.call @llvm.trunc.f80(%[[VAL_2]]) : (f80) -> f80
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f80>
+! CHECK: return
+! CHECK: }
+
+subroutine aint_test_real10(a, b)
+ real(10) :: a, b
+ b = aint(a)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPaint_test_real16(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f128> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f128> {fir.bindc_name = "b"}) {
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<f128>
+! CHECK: %[[VAL_3:.*]] = fir.call @llvm.trunc.f128(%[[VAL_2]]) : (f128) -> f128
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f128>
+! CHECK: return
+! CHECK: }
+
+subroutine aint_test_real16(a, b)
+ real(16) :: a, b
+ b = aint(a)
+end subroutine
diff --git a/flang/test/Lower/Intrinsics/anint.f90 b/flang/test/Lower/Intrinsics/anint.f90
index 29670b0..fb9d446 100644
--- a/flang/test/Lower/Intrinsics/anint.f90
+++ b/flang/test/Lower/Intrinsics/anint.f90
@@ -1,9 +1,57 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
-! CHECK-LABEL: anint_test
+! CHECK-LABEL: func.func @_QPanint_test(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}) {
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<f32>
+! CHECK: %[[VAL_3:.*]] = "llvm.intr.round"(%[[VAL_2]]) : (f32) -> f32
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f32>
+! CHECK: return
+! CHECK: }
+
subroutine anint_test(a, b)
real :: a, b
- ! CHECK: "llvm.intr.round"
b = anint(a)
end subroutine
-
+
+! CHECK-LABEL: func.func @_QPanint_test_real8(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f64> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f64> {fir.bindc_name = "b"}) {
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<f64>
+! CHECK: %[[VAL_3:.*]] = "llvm.intr.round"(%[[VAL_2]]) : (f64) -> f64
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f64>
+! CHECK: return
+! CHECK: }
+
+subroutine anint_test_real8(a, b)
+ real(8) :: a, b
+ b = anint(a)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPanint_test_real10(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f80> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f80> {fir.bindc_name = "b"}) {
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<f80>
+! CHECK: %[[VAL_3:.*]] = "llvm.intr.round"(%[[VAL_2]]) : (f80) -> f80
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f80>
+! CHECK: return
+! CHECK: }
+
+subroutine anint_test_real10(a, b)
+ real(10) :: a, b
+ b = anint(a)
+end subroutine
+
+! CHECK-LABEL: func.func @_QPanint_test_real16(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f128> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<f128> {fir.bindc_name = "b"}) {
+! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<f128>
+! CHECK: %[[VAL_3:.*]] = "llvm.intr.round"(%[[VAL_2]]) : (f128) -> f128
+! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<f128>
+! CHECK: return
+! CHECK: }
+
+subroutine anint_test_real16(a, b)
+ real(16) :: a, b
+ b = anint(a)
+end subroutine
diff --git a/flang/test/Lower/math-lowering.f90 b/flang/test/Lower/math-lowering.f90
index 4eb9b97..3514a76 100644
--- a/flang/test/Lower/math-lowering.f90
+++ b/flang/test/Lower/math-lowering.f90
@@ -77,6 +77,22 @@ end function
! ALL-LABEL: @_QPtest_real8
! ALL: {{%[A-Za-z0-9._]+}} = fir.call @llvm.trunc.f64({{%[A-Za-z0-9._]+}}) : (f64) -> f64
+function test_real10(x)
+ real(10) :: x, test_real10
+ test_real10 = aint(x)
+end function
+
+! ALL-LABEL: @_QPtest_real10
+! ALL: {{%[A-Za-z0-9._]+}} = fir.call @llvm.trunc.f80({{%[A-Za-z0-9._]+}}) : (f80) -> f80
+
+function test_real16(x)
+ real(16) :: x, test_real16
+ test_real16 = aint(x)
+end function
+
+! ALL-LABEL: @_QPtest_real16
+! ALL: {{%[A-Za-z0-9._]+}} = fir.call @llvm.trunc.f128({{%[A-Za-z0-9._]+}}) : (f128) -> f128
+
//--- anint.f90
! RUN: bbc -emit-fir %t/anint.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/anint.f90
! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/anint.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/anint.f90
@@ -105,6 +121,26 @@ end function
! RELAXED: {{%[A-Za-z0-9._]+}} = "llvm.intr.round"({{%[A-Za-z0-9._]+}}) : (f64) -> f64
! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @llvm.round.f64({{%[A-Za-z0-9._]+}}) : (f64) -> f64
+function test_real10(x)
+ real(10) :: x, test_real10
+ test_real10 = anint(x)
+end function
+
+! ALL-LABEL: @_QPtest_real10
+! FAST: {{%[A-Za-z0-9._]+}} = "llvm.intr.round"({{%[A-Za-z0-9._]+}}) : (f80) -> f80
+! RELAXED: {{%[A-Za-z0-9._]+}} = "llvm.intr.round"({{%[A-Za-z0-9._]+}}) : (f80) -> f80
+! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @llvm.round.f80({{%[A-Za-z0-9._]+}}) : (f80) -> f80
+
+function test_real16(x)
+ real(16) :: x, test_real16
+ test_real16 = anint(x)
+end function
+
+! ALL-LABEL: @_QPtest_real16
+! FAST: {{%[A-Za-z0-9._]+}} = "llvm.intr.round"({{%[A-Za-z0-9._]+}}) : (f128) -> f128
+! RELAXED: {{%[A-Za-z0-9._]+}} = "llvm.intr.round"({{%[A-Za-z0-9._]+}}) : (f128) -> f128
+! PRECISE: {{%[A-Za-z0-9._]+}} = fir.call @llvm.round.f128({{%[A-Za-z0-9._]+}}) : (f128) -> f128
+
//--- atan.f90
! RUN: bbc -emit-fir %t/atan.f90 -o - --math-runtime=fast | FileCheck --check-prefixes=ALL,FAST %t/atan.f90
! RUN: %flang_fc1 -emit-fir -mllvm -math-runtime=fast %t/atan.f90 -o - | FileCheck --check-prefixes=ALL,FAST %t/atan.f90
diff --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp
index dc2f010..dafde44 100644
--- a/flang/unittests/Runtime/Numeric.cpp
+++ b/flang/unittests/Runtime/Numeric.cpp
@@ -18,28 +18,6 @@ template <int KIND> using Real = CppTypeFor<TypeCategory::Real, KIND>;
// Simple tests of numeric intrinsic functions using examples from Fortran 2018
-TEST(Numeric, Aint) {
- EXPECT_EQ(RTNAME(Aint4_4)(Real<4>{3.7}), 3.0);
- EXPECT_EQ(RTNAME(Aint8_4)(Real<8>{-3.7}), -3.0);
- EXPECT_EQ(RTNAME(Aint8_8)(Real<8>{0}), 0.0);
- EXPECT_EQ(RTNAME(Aint4_4)(std::numeric_limits<Real<4>>::infinity()),
- std::numeric_limits<Real<4>>::infinity());
- EXPECT_TRUE(
- std::isnan(RTNAME(Aint8_8)(std::numeric_limits<Real<8>>::quiet_NaN())));
-}
-
-TEST(Numeric, Anint) {
- EXPECT_EQ(RTNAME(Anint4_4)(Real<4>{2.783}), 3.0);
- EXPECT_EQ(RTNAME(Anint8_4)(Real<8>{-2.783}), -3.0);
- EXPECT_EQ(RTNAME(Anint4_4)(Real<4>{2.5}), 3.0);
- EXPECT_EQ(RTNAME(Anint8_4)(Real<8>{-2.5}), -3.0);
- EXPECT_EQ(RTNAME(Anint8_8)(Real<8>{0}), 0.0);
- EXPECT_EQ(RTNAME(Anint4_4)(std::numeric_limits<Real<4>>::infinity()),
- std::numeric_limits<Real<4>>::infinity());
- EXPECT_TRUE(
- std::isnan(RTNAME(Aint8_8)(std::numeric_limits<Real<8>>::quiet_NaN())));
-}
-
TEST(Numeric, Ceiling) {
EXPECT_EQ(RTNAME(Ceiling4_4)(Real<4>{3.7}), 4);
EXPECT_EQ(RTNAME(Ceiling8_8)(Real<8>{-3.7}), -3);