[flang] Support aint/anint for 80/128 bit in lowering
authorPeixin Qiao <qiaopeixin@huawei.com>
Sat, 23 Jul 2022 06:44:20 +0000 (14:44 +0800)
committerPeixin Qiao <qiaopeixin@huawei.com>
Sat, 23 Jul 2022 06:44:20 +0000 (14:44 +0800)
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

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

index d68c5b4a9604738af92af0ad6e9588f3767759f6..42737a4fa874cb3a50ca18a3f509b6095422d0cf 100644 (file)
 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>);
index 53f7d5301aee2775424413d5c6933d9885721066..248bb1d07bb0b914de544204f2f2510755ede307 100644 (file)
@@ -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>},
index a989d3a43a4d0ed6b20f27a331952c7dca6326e8..7ab1f137e58efd1407d79f6c3ce457f208638b08 100644 (file)
 
 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
index dd42f8663999b724fe33f38043d144b54b27bec8..1d58a0359f3a4cffa660e0b0792e720ccf4f8cd5 100644 (file)
@@ -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
index 29670b098dea058495de28ac22adeb8dadd0a6c4..fb9d446b647aa22c89400ff4eb83772f652947db 100644 (file)
@@ -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
index 4eb9b97a930821f7a38431849f4c6545f1e6ab9f..3514a76f3bf32e6c1c961000e20ba76402f5f107 100644 (file)
@@ -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
index dc2f010327d908ebf51d0a8a1240120244163ab6..dafde4475bf57c86dffac3fd18994fad15f82bf7 100644 (file)
@@ -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);