[flang] some real debugging
authorpeter klausler <pklausler@nvidia.com>
Tue, 5 Jun 2018 23:55:31 +0000 (16:55 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 14 Jun 2018 20:52:45 +0000 (13:52 -0700)
Original-commit: flang-compiler/f18@9653814ed3623f2abf592242b6d914bddc8766c7
Reviewed-on: https://github.com/flang-compiler/f18/pull/101
Tree-same-pre-rewrite: false

flang/lib/evaluate/integer.h
flang/lib/evaluate/real.h
flang/test/evaluate/real.cc

index f855e74..bcf95c8 100644 (file)
@@ -344,7 +344,7 @@ public:
     std::uint64_t n{LEPart(0)};
     int filled{partBits};
     for (int j{1}; filled < 64 && j < parts; ++j, filled += partBits) {
-      n |= LEPart(j) << filled;
+      n |= std::uint64_t{LEPart(j)} << filled;
     }
     return n;
   }
index 7e6e91c..c41769b 100644 (file)
@@ -130,13 +130,13 @@ public:
     if (exponent == maxExponent && !fraction.IsZero()) {  // NaN
       result.flags |= RealFlag::InvalidArgument;
       result.value = result.value.HUGE();
-    } else if (exponent >= exponentBias + result.value.bits) {  // +/-Inf
+    } else if (exponent >= maxExponent || exponent >= exponentBias + result.value.bits) {  // +/-Inf
       if (isNegative) {
         result.value = result.value.MASKL(1);
       } else {
         result.value = result.value.HUGE();
       }
-      result.flags = RealFlag::Overflow;
+      result.flags |= RealFlag::Overflow;
     } else if (exponent < exponentBias) {  // |x| < 1.0
       if (!fraction.IsZero()) {
         result.flags |= RealFlag::Underflow | RealFlag::Inexact;
@@ -409,8 +409,8 @@ private:
         // +/-0.0
         word_ = Word{};
       } else if (biasedExponent <= leadz) {
+        // denormal
         word_ = Word::Convert(fraction).value.SHIFTL(biasedExponent);
-        // TODO: Underflow
       } else {
         word_ = Word::Convert(fraction).value.SHIFTL(leadz);
         if (implicitMSB) {
@@ -425,6 +425,8 @@ private:
     }
   }
 
+  // Determines whether a value should be rounded by increasing its
+  // fraction, given a rounding mode and a summary of the lost bits.
   constexpr bool MustRound(Rounding rounding, const RoundingBits &bits) const {
     bool round{false};  // to dodge bogus g++ warning about missing return
     switch (rounding) {
@@ -443,7 +445,7 @@ private:
     return round;
   }
 
-  // Returns flags.
+  // Rounds a result, if necessary; returns flags.
   int Round(Rounding rounding, const RoundingBits &bits) {
     std::uint64_t exponent{Exponent()};
     int flags{(bits.round | bits.guard) ? RealFlag::Inexact : RealFlag::Ok};
@@ -467,11 +469,22 @@ private:
   Word word_{};  // an Integer<>
 };
 
+using RealKind2 = Real<Integer<16>, 11>;
 extern template class Real<Integer<16>, 11>;
+
+using RealKind4 = Real<Integer<32>, 24>;
 extern template class Real<Integer<32>, 24>;
+
+using RealKind8 = Real<Integer<64>, 53>;
 extern template class Real<Integer<64>, 53>;
+
+using RealKind10 = Real<Integer<80>, 64, false>;  // 80387
 extern template class Real<Integer<80>, 64, false>;
+
+using RealKind16 = Real<Integer<128>, 112>;
 extern template class Real<Integer<128>, 112>;
 
+// N.B. No "double-double" support.
+
 }  // namespace Fortran::evaluate
 #endif  // FORTRAN_EVALUATE_REAL_H_
index 7f51d3e..c4a8190 100644 (file)
 #include "testing.h"
 #include <cstdio>
 
-using Fortran::evaluate::Integer;
-using Fortran::evaluate::Ordering;
-using Fortran::evaluate::Real;
-using Fortran::evaluate::Relation;
-using Fortran::evaluate::ValueWithRealFlags;
+using namespace Fortran::evaluate;
 
 template<typename R> void tests() {
   char desc[64];
@@ -103,24 +99,24 @@ template<typename R> void tests() {
     TEST(!vr.value.IsZero())("%s,%d,0x%llx",desc,j,x);
     auto ivf = vr.value.template ToInteger<Integer<64>>();
     if (j > (maxExponent / 2)) {
-      MATCH(Fortran::evaluate::RealFlag::Overflow, vr.flags)(desc);
+      MATCH(RealFlag::Overflow, vr.flags)(desc);
       TEST(vr.value.IsInfinite())("%s,%d,0x%llx",desc,j,x);
-      MATCH(Fortran::evaluate::RealFlag::Overflow, ivf.flags)("%s,%d,0x%llx",desc,j,x);
+      MATCH(RealFlag::Overflow, ivf.flags)("%s,%d,0x%llx",desc,j,x);
       MATCH(0x7fffffffffffffff, ivf.value.ToUInt64())("%s,%d,0x%llx",desc,j,x);
     } else {
-      MATCH(Fortran::evaluate::RealFlag::Ok, vr.flags)(desc);
+      MATCH(RealFlag::Ok, vr.flags)(desc);
       TEST(!vr.value.IsInfinite())("%s,%d,0x%llx",desc,j,x);
-      MATCH(Fortran::evaluate::RealFlag::Ok, ivf.flags)("%s,%d,0x%llx",desc,j,x);
+      MATCH(RealFlag::Ok, ivf.flags)("%s,%d,0x%llx",desc,j,x);
       MATCH(x, ivf.value.ToUInt64())("%s,%d,0x%llx",desc,j,x);
     }
   }
 }
 
 int main() {
-  tests<Real<Integer<16>, 11>>();
-  tests<Real<Integer<32>, 24>>();
-  tests<Real<Integer<64>, 53>>();
-  tests<Real<Integer<80>, 64, false>>();
-  tests<Real<Integer<128>, 112>>();
+  tests<RealKind2>();
+  tests<RealKind4>();
+  tests<RealKind8>();
+  tests<RealKind10>();
+  tests<RealKind16>();
   return testing::Complete();
 }