[flang-commits] [flang] 3ccd4ce - [flang] Support aint/anint for 80/128 bit in lowering
Peixin Qiao via flang-commits
flang-commits at lists.llvm.org
Fri Jul 22 23:46:09 PDT 2022
Author: Peixin Qiao
Date: 2022-07-23T14:44:20+08:00
New Revision: 3ccd4ce29ca7f59eb12b077705cde2c11ac13aae
URL: https://github.com/llvm/llvm-project/commit/3ccd4ce29ca7f59eb12b077705cde2c11ac13aae
DIFF: https://github.com/llvm/llvm-project/commit/3ccd4ce29ca7f59eb12b077705cde2c11ac13aae.diff
LOG: [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
Added:
Modified:
flang/include/flang/Runtime/numeric.h
flang/lib/Lower/IntrinsicCall.cpp
flang/runtime/numeric.cpp
flang/test/Lower/Intrinsics/aint.f90
flang/test/Lower/Intrinsics/anint.f90
flang/test/Lower/math-lowering.f90
flang/unittests/Runtime/Numeric.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Runtime/numeric.h b/flang/include/flang/Runtime/numeric.h
index d68c5b4a96047..42737a4fa874c 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 53f7d5301aee2..248bb1d07bb0b 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 a989d3a43a4d0..7ab1f137e58ef 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 dd42f8663999b..1d58a0359f3a4 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 29670b098dea0..fb9d446b647aa 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 4eb9b97a93082..3514a76f3bf32 100644
--- a/flang/test/Lower/math-lowering.f90
+++ b/flang/test/Lower/math-lowering.f90
@@ -77,6 +77,22 @@ function test_real8(x)
! 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 @@ function test_real8(x)
! 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 dc2f010327d90..dafde4475bf57 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);
More information about the flang-commits
mailing list