[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