[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