[flang] Fix folding of EXPONENT() intrinsic function

The definition of the EXPONENT() intrinsic function differs by one
from the real arithmetic folding templates concept of an unbiased
exponent, and also needs special handling for zero.  Fix, and add
more tests.

Differential Revision: https://reviews.llvm.org/D115084
This commit is contained in:
Peter Klausler 2021-12-02 12:34:37 -08:00
parent f1585a4b47
commit e337dc8bfe
2 changed files with 13 additions and 1 deletions

View File

@ -125,8 +125,10 @@ public:
template <typename INT> constexpr INT EXPONENT() const { template <typename INT> constexpr INT EXPONENT() const {
if (Exponent() == maxExponent) { if (Exponent() == maxExponent) {
return INT::HUGE(); return INT::HUGE();
} else if (IsZero()) {
return {0};
} else { } else {
return {UnbiasedExponent()}; return {UnbiasedExponent() + 1};
} }
} }
@ -308,6 +310,8 @@ public:
// Extracts unbiased exponent value. // Extracts unbiased exponent value.
// Corrects the exponent value of a subnormal number. // Corrects the exponent value of a subnormal number.
// Note that the result is one less than the EXPONENT intrinsic;
// UnbiasedExponent(1.0) is 0, not 1.
constexpr int UnbiasedExponent() const { constexpr int UnbiasedExponent() const {
int exponent{Exponent() - exponentBias}; int exponent{Exponent() - exponentBias};
if (IsSubnormal()) { if (IsSubnormal()) {

View File

@ -197,6 +197,14 @@ module m
logical, parameter :: test_tiny10 = tiny10 == ztiny10 logical, parameter :: test_tiny10 = tiny10 == ztiny10
logical, parameter :: test_tiny16 = tiny16 == ztiny16 logical, parameter :: test_tiny16 = tiny16 == ztiny16
logical, parameter :: test_exponent_0 = exponent(0.0) == 0
logical, parameter :: test_exponent_r8 = exponent(0.125) == -2
logical, parameter :: test_exponent_r4 = exponent(0.25) == -1
logical, parameter :: test_exponent_r2 = exponent(0.5) == 0
logical, parameter :: test_exponent_1 = exponent(1.0) == 1
logical, parameter :: test_exponent_4 = exponent(4.1) == 3
logical, parameter :: test_exponent_12 = exponent(12.9) == 4
integer, parameter :: & integer, parameter :: &
max2 = maxexponent(0._2), & max2 = maxexponent(0._2), &
max3 = maxexponent(0._3), & max3 = maxexponent(0._3), &