From 28007dabe4c10ba252c3354bc2e11c81beae24a0 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Fri, 29 Dec 2023 12:36:31 -0800 Subject: [PATCH] [flang][runtime] Don't round hexadecimal floating-point input Fortran 2023 subclause 13.7.2.3.8 discusses input rounding only in the context of decimal-to-binary conversion. There is no mention of rounding for hexadecimal floating-point input conversion. At least one Fortran compiler seems to have interpreted this silence as implying no rounding. (Note that this is not the same thing as rounding to zero (RZ), which would return +/-HUGE() for overflow.) --- flang/docs/Extensions.md | 6 ++++++ flang/runtime/edit-input.cpp | 38 +++--------------------------------- 2 files changed, 9 insertions(+), 35 deletions(-) diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index 6c6588025a392..4e65debb177a1 100644 --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -645,6 +645,12 @@ 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. + ## De Facto Standard Features * `EXTENDS_TYPE_OF()` returns `.TRUE.` if both of its arguments have the diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp index c4fa186e289db..f1e0d1a06ee36 100644 --- a/flang/runtime/edit-input.cpp +++ b/flang/runtime/edit-input.cpp @@ -624,31 +624,6 @@ decimal::ConversionToBinaryResult 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}; @@ -659,16 +634,9 @@ decimal::ConversionToBinaryResult ConvertHexadecimal( expo = 0; // subnormal flags |= decimal::Underflow; } else if (expo >= RealType::maxExponent) { - 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; - } + expo = RealType::maxExponent; // +/-Inf + fraction = 0; + flags |= decimal::Overflow; } else { fraction &= significandMask; // remove explicit normalization unless x87 }