[flang-commits] [flang] 68efe63 - [flang] Fix ICE for sqrt(0.0) evaluation
Mike Kashkarov via flang-commits
flang-commits at lists.llvm.org
Thu Apr 14 02:53:51 PDT 2022
Author: Mike Kashkarov
Date: 2022-04-14T12:53:46+03:00
New Revision: 68efe6356551237e967c23c1bf5fd01dc4a2fc90
URL: https://github.com/llvm/llvm-project/commit/68efe6356551237e967c23c1bf5fd01dc4a2fc90
DIFF: https://github.com/llvm/llvm-project/commit/68efe6356551237e967c23c1bf5fd01dc4a2fc90.diff
LOG: [flang] Fix ICE for sqrt(0.0) evaluation
During real range reduction to [0.5, 4) with
SQRT(2**(2a) * x) = SQRT(2**(2a)) * SQRT(x) = 2**a * SQRT(x)
we fall into inf. recursion if IsZero() == true.
Explicitly handle SQRT(0.0) instead of additional checks during folding. Also
add helpers for +0.0/-0.0 generation to clean up a bit.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D123131
Added:
Modified:
flang/include/flang/Evaluate/real.h
flang/lib/Evaluate/real.cpp
flang/test/Evaluate/folding28.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Evaluate/real.h b/flang/include/flang/Evaluate/real.h
index 14f26dfb52fff..2f4f7b2c47757 100644
--- a/flang/include/flang/Evaluate/real.h
+++ b/flang/include/flang/Evaluate/real.h
@@ -196,6 +196,10 @@ class Real : public common::RealDetails<PREC> {
.IBSET(significandBits - 2)};
}
+ static constexpr Real PositiveZero() { return Real{}; }
+
+ static constexpr Real NegativeZero() { return {Word{}.MASKL(1)}; }
+
static constexpr Real Infinity(bool negative) {
Word infinity{maxExponent};
infinity = infinity.SHIFTL(significandBits);
diff --git a/flang/lib/Evaluate/real.cpp b/flang/lib/Evaluate/real.cpp
index d273e76d70e1e..eb6bd148e341c 100644
--- a/flang/lib/Evaluate/real.cpp
+++ b/flang/lib/Evaluate/real.cpp
@@ -98,7 +98,7 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::Add(
if (order == Ordering::Equal) {
// x + (-x) -> +0.0 unless rounding is directed downwards
if (rounding.mode == common::RoundingMode::Down) {
- result.value.word_ = result.value.word_.IBSET(bits - 1); // -0.0
+ result.value = NegativeZero();
}
return result;
}
@@ -221,7 +221,7 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::Divide(
}
} else if (IsZero() || y.IsInfinite()) { // 0/x, x/Inf -> 0
if (isNegative) {
- result.value.word_ = result.value.word_.IBSET(bits - 1);
+ result.value = NegativeZero();
}
} else {
// dividend and divisor are both finite and nonzero numbers
@@ -272,13 +272,15 @@ ValueWithRealFlags<Real<W, P>> Real<W, P>::SQRT(Rounding rounding) const {
} else if (IsNegative()) {
if (IsZero()) {
// SQRT(-0) == -0 in IEEE-754.
- result.value.word_ = result.value.word_.IBSET(bits - 1);
+ result.value = NegativeZero();
} else {
result.value = NotANumber();
}
} else if (IsInfinite()) {
// SQRT(+Inf) == +Inf
result.value = Infinity(false);
+ } else if (IsZero()) {
+ result.value = PositiveZero();
} else {
int expo{UnbiasedExponent()};
if (expo < -1 || expo > 1) {
diff --git a/flang/test/Evaluate/folding28.f90 b/flang/test/Evaluate/folding28.f90
index 95db37abe8326..004c661692fee 100644
--- a/flang/test/Evaluate/folding28.f90
+++ b/flang/test/Evaluate/folding28.f90
@@ -44,4 +44,9 @@ module m
logical, parameter :: test_before_1 = sqrt_before_1 == before_1
real(4), parameter :: sq_sqrt_before_1 = sqrt_before_1 * sqrt_before_1
logical, parameter :: test_sq_before_1 = sq_sqrt_before_1 < before_1
+ ! ICE at 0.0
+ real(4), parameter :: sqrt_zero_4 = sqrt(0.0)
+ logical, parameter :: test_sqrt_zero_4 = sqrt_zero_4 == 0.0
+ real(8), parameter :: sqrt_zero_8 = sqrt(0.0)
+ logical, parameter :: test_sqrt_zero_8 = sqrt_zero_8 == 0.0
end module
More information about the flang-commits
mailing list