[flang-commits] [flang] [flang][runtime] Detect & signal underflow when reading reals (PR #75232)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Tue Dec 12 10:39:39 PST 2023
https://github.com/klausler created https://github.com/llvm/llvm-project/pull/75232
Extend decimal->binary conversion to detect underflow cases and raise the corresponding floating-point exception.
>From 6be6520b74af68b27e0a30e1af261126df46e22b Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Tue, 12 Dec 2023 10:34:29 -0800
Subject: [PATCH] [flang][runtime] Detect & signal underflow when reading reals
Extend decimal->binary conversion to detect underflow cases
and raise the corresponding floating-point exception.
---
flang/include/flang/Decimal/decimal.h | 1 +
flang/lib/Decimal/decimal-to-binary.cpp | 11 ++++++++---
flang/runtime/edit-input.cpp | 3 +++
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/flang/include/flang/Decimal/decimal.h b/flang/include/flang/Decimal/decimal.h
index a4e0ee7c847460..f0997fb63df018 100644
--- a/flang/include/flang/Decimal/decimal.h
+++ b/flang/include/flang/Decimal/decimal.h
@@ -34,6 +34,7 @@ enum ConversionResultFlags {
Overflow = 1,
Inexact = 2,
Invalid = 4,
+ Underflow = 8,
};
struct ConversionToDecimalResult {
diff --git a/flang/lib/Decimal/decimal-to-binary.cpp b/flang/lib/Decimal/decimal-to-binary.cpp
index d5b66b9fb93388..663deb564a01e2 100644
--- a/flang/lib/Decimal/decimal-to-binary.cpp
+++ b/flang/lib/Decimal/decimal-to-binary.cpp
@@ -261,6 +261,7 @@ ConversionToBinaryResult<PREC> IntermediateFloat<PREC>::ToBinary(
(isNegative && rounding == RoundDown)) {
// round to minimum nonzero value
} else {
+ flags |= Underflow;
return {Binary{}, static_cast<enum ConversionResultFlags>(flags)};
}
} else {
@@ -342,7 +343,8 @@ BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToBinary() {
(isNegative_ && rounding_ == RoundDown)) {
return {Real{Raw{1} | SignBit()}}; // return least nonzero value
} else { // underflow to +/-0.
- return {Real{SignBit()}, Inexact};
+ return {Real{SignBit()},
+ static_cast<enum ConversionResultFlags>(Inexact | Underflow)};
}
} else if (exponent_ > crazy) { // overflow to +/-Inf.
return {Real{Infinity()}, Overflow};
@@ -417,8 +419,11 @@ BigRadixFloatingPointNumber<PREC, LOG10RADIX>::ConvertToBinary(
if (ParseNumber(p, inexact, limit)) {
auto result{ConvertToBinary()};
if (inexact) {
- result.flags =
- static_cast<enum ConversionResultFlags>(result.flags | Inexact);
+ int flags{result.flags | Inexact};
+ if (result.binary.IsZero()) {
+ flags |= Underflow;
+ }
+ result.flags = static_cast<enum ConversionResultFlags>(flags);
}
return result;
} else {
diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp
index 822099b5141b1b..49156603ea265c 100644
--- a/flang/runtime/edit-input.cpp
+++ b/flang/runtime/edit-input.cpp
@@ -478,6 +478,9 @@ static void RaiseFPExceptions(decimal::ConversionResultFlags flags) {
if (flags & decimal::ConversionResultFlags::Overflow) {
RAISE(FE_OVERFLOW);
}
+ if (flags & decimal::ConversionResultFlags::Underflow) {
+ RAISE(FE_UNDERFLOW);
+ }
if (flags & decimal::ConversionResultFlags::Inexact) {
RAISE(FE_INEXACT);
}
More information about the flang-commits
mailing list