[flang-commits] [flang] add189c - [flang][runtime] Resume rounding hexadecimal floating-point input (#77006)

via flang-commits flang-commits at lists.llvm.org
Mon Jan 15 10:39:25 PST 2024


Author: Peter Klausler
Date: 2024-01-15T10:39:22-08:00
New Revision: add189cdf01e92ca30687291a98e936b7706ee38

URL: https://github.com/llvm/llvm-project/commit/add189cdf01e92ca30687291a98e936b7706ee38
DIFF: https://github.com/llvm/llvm-project/commit/add189cdf01e92ca30687291a98e936b7706ee38.diff

LOG: [flang][runtime] Resume rounding hexadecimal floating-point input (#77006)

This reverts commit cab156c4129e5948a6322054480e66d3ca17b919, and adds
language to Extensions.md documenting the discrepancy with the letter of
the language standard.

Added: 
    

Modified: 
    flang/docs/Extensions.md
    flang/runtime/edit-input.cpp

Removed: 
    


################################################################################
diff  --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 29ec7be4fa466f..33109ae2d30426 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -651,11 +651,10 @@ end
   only in function references, but not an explicit `INTRINSIC` statement,
   its name is not brought into other scopes by a `USE` statement.
 
-* Should hexadecimal floating-point input editing apply any rounding?
-  F'2023 subclause 13.7.2.3.8 only discusses rounding in the context of
-  decimal-to-binary conversion; it would seem to not apply, and so
-  we don't round.  This seems to be how the Intel Fortran compilers
-  behave.
+* The subclause on rounding in formatted I/O (13.7.2.3.8 in F'2023)
+  only discusses rounding for decimal-to/from-binary conversions,
+  omitting any mention of rounding for hexadecimal conversions.
+  As other compilers do apply rounding, so does this one.
 
 * For real `MAXVAL`, `MINVAL`, `MAXLOC`, and `MINLOC`, NaN values are
   essentially ignored unless there are some unmasked array entries and

diff  --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index 6bffe24f03ca74..85cce2f1a16623 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -632,6 +632,31 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
       fraction <<= 1;
       --expo;
     }
+    // Rounding
+    bool increase{false};
+    switch (rounding) {
+    case decimal::RoundNearest: // RN & RP
+      increase = roundingBit && (guardBit | ((int)fraction & 1));
+      break;
+    case decimal::RoundUp: // RU
+      increase = !isNegative && (roundingBit | guardBit);
+      break;
+    case decimal::RoundDown: // RD
+      increase = isNegative && (roundingBit | guardBit);
+      break;
+    case decimal::RoundToZero: // RZ
+      break;
+    case decimal::RoundCompatible: // RC
+      increase = roundingBit != 0;
+      break;
+    }
+    if (increase) {
+      ++fraction;
+      if (fraction >> binaryPrecision) {
+        fraction >>= 1;
+        ++expo;
+      }
+    }
   }
   // Package & return result
   constexpr RawType significandMask{(one << RealType::significandBits) - 1};
@@ -642,9 +667,16 @@ decimal::ConversionToBinaryResult<binaryPrecision> ConvertHexadecimal(
     expo = 0; // subnormal
     flags |= decimal::Underflow;
   } else if (expo >= RealType::maxExponent) {
-    expo = RealType::maxExponent; // +/-Inf
-    fraction = 0;
-    flags |= decimal::Overflow;
+    if (rounding == decimal::RoundToZero ||
+        (rounding == decimal::RoundDown && !isNegative) ||
+        (rounding == decimal::RoundUp && isNegative)) {
+      expo = RealType::maxExponent - 1; // +/-HUGE()
+      fraction = significandMask;
+    } else {
+      expo = RealType::maxExponent; // +/-Inf
+      fraction = 0;
+      flags |= decimal::Overflow;
+    }
   } else {
     fraction &= significandMask; // remove explicit normalization unless x87
   }


        


More information about the flang-commits mailing list