[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 {
if (Exponent() == maxExponent) {
return INT::HUGE();
} else if (IsZero()) {
return {0};
} else {
return {UnbiasedExponent()};
return {UnbiasedExponent() + 1};
}
}
@ -308,6 +310,8 @@ public:
// Extracts unbiased exponent value.
// 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 {
int exponent{Exponent() - exponentBias};
if (IsSubnormal()) {

View File

@ -197,6 +197,14 @@ module m
logical, parameter :: test_tiny10 = tiny10 == ztiny10
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 :: &
max2 = maxexponent(0._2), &
max3 = maxexponent(0._3), &