[flang-commits] [flang] [flang][runtime] Resume rounding hexadecimal floating-point input (PR #77006)
via flang-commits
flang-commits at lists.llvm.org
Thu Jan 4 13:26:04 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-runtime
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
This reverts commit cab156c4129e5948a6322054480e66d3ca17b919, and adds language to Extensions.md documenting the discrepancy with the letter of the language standard.
---
Full diff: https://github.com/llvm/llvm-project/pull/77006.diff
2 Files Affected:
- (modified) flang/docs/Extensions.md (+4-5)
- (modified) flang/runtime/edit-input.cpp (+35-3)
``````````diff
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 16eb67f2e27c81..c71beb5262439f 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -648,11 +648,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.
## De Facto Standard Features
diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index 6d4fa588cbf60d..385a36174ed595 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -627,6 +627,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};
@@ -637,9 +662,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
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/77006
More information about the flang-commits
mailing list