[libc-commits] [PATCH] D117590: [libc] Implement correct rounding with all rounding modes for hypot functions.

Tue Ly via Phabricator via libc-commits libc-commits at lists.llvm.org
Tue Jan 18 11:12:43 PST 2022


lntue created this revision.
lntue added reviewers: michaelrj, sivachandra, zimmermann6.
Herald added subscribers: ecnelises, tschuett.
Herald added a project: libc-project.
lntue requested review of this revision.

Update the rounding logic for generic hypot function so that it will round correctly with all rounding modes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D117590

Files:
  libc/src/__support/FPUtil/Hypot.h
  libc/test/src/math/HypotTest.h


Index: libc/test/src/math/HypotTest.h
===================================================================
--- libc/test/src/math/HypotTest.h
+++ libc/test/src/math/HypotTest.h
@@ -62,9 +62,9 @@
             y = -y;
           }
 
-          T result = func(x, y);
           mpfr::BinaryInput<T> input{x, y};
-          ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
+          ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Hypot, input,
+                                         func(x, y), 0.5);
         }
       }
     }
@@ -85,9 +85,9 @@
           y = -y;
         }
 
-        T result = func(x, y);
         mpfr::BinaryInput<T> input{x, y};
-        ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
+        ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Hypot, input,
+                                       func(x, y), 0.5);
       }
     }
   }
Index: libc/src/__support/FPUtil/Hypot.h
===================================================================
--- libc/src/__support/FPUtil/Hypot.h
+++ libc/src/__support/FPUtil/Hypot.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_HYPOT_H
 
 #include "BasicOperations.h"
+#include "FEnvImpl.h"
 #include "FPBits.h"
 #include "src/__support/CPP/TypeTraits.h"
 
@@ -143,11 +144,18 @@
   if ((x_bits.get_unbiased_exponent() >=
        y_bits.get_unbiased_exponent() + MantissaWidth<T>::VALUE + 2) ||
       (y == 0)) {
+    if ((y != 0) && (get_round() == FE_UPWARD)) {
+      UIntType out_bits = FPBits_t(abs(x)).uintval();
+      return T(FPBits_t(++out_bits));
+    }
     return abs(x);
   } else if ((y_bits.get_unbiased_exponent() >=
               x_bits.get_unbiased_exponent() + MantissaWidth<T>::VALUE + 2) ||
              (x == 0)) {
-    y_bits.set_sign(0);
+    if ((x != 0) && (get_round() == FE_UPWARD)) {
+      UIntType out_bits = FPBits_t(abs(y)).uintval();
+      return T(FPBits_t(++out_bits));
+    }
     return abs(y);
   }
 
@@ -250,8 +258,16 @@
   y_new >>= 1;
 
   // Round to the nearest, tie to even.
-  if (round_bit && (lsb || sticky_bits || (r != 0))) {
-    ++y_new;
+  switch (get_round()) {
+  case FE_TONEAREST:
+    // Round to nearest, ties to even
+    if (round_bit && (lsb || sticky_bits || (r != 0)))
+      ++y_new;
+    break;
+  case FE_UPWARD:
+    if (round_bit || sticky_bits || (r != 0))
+      ++y_new;
+    break;
   }
 
   if (y_new >= (ONE >> 1)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117590.400919.patch
Type: text/x-patch
Size: 2399 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20220118/37faf845/attachment-0001.bin>


More information about the libc-commits mailing list