[libc-commits] [libc] 27aca97 - [libc][math] Fix broken compilation due to __builtin_inf/nan functions.

Kirill Okhotnikov via libc-commits libc-commits at lists.llvm.org
Fri Jun 24 16:39:55 PDT 2022


Author: Kirill Okhotnikov
Date: 2022-06-25T01:39:32+02:00
New Revision: 27aca975b6b6e9d5c7516c091f954884b28650ae

URL: https://github.com/llvm/llvm-project/commit/27aca975b6b6e9d5c7516c091f954884b28650ae
DIFF: https://github.com/llvm/llvm-project/commit/27aca975b6b6e9d5c7516c091f954884b28650ae.diff

LOG: [libc][math] Fix broken compilation due to __builtin_inf/nan functions.

Added: 
    

Modified: 
    libc/src/__support/FPUtil/FPBits.h
    libc/src/__support/FPUtil/builtin_wrappers.h
    libc/src/__support/FPUtil/generic/FMod.h
    libc/src/__support/FPUtil/generic/sqrt.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index a30e41f2d046..f972b97de1b0 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -135,6 +135,11 @@ template <typename T> struct FPBits {
     return (bits & FloatProp::EXP_MANT_MASK) > FloatProp::EXPONENT_MASK;
   }
 
+  bool is_quiet_nan() const {
+    return (bits & FloatProp::EXP_MANT_MASK) ==
+           (FloatProp::EXPONENT_MASK | FloatProp::QUIET_NAN_MASK);
+  }
+
   bool is_inf_or_nan() const {
     return (bits & FloatProp::EXPONENT_MASK) == FloatProp::EXPONENT_MASK;
   }

diff  --git a/libc/src/__support/FPUtil/builtin_wrappers.h b/libc/src/__support/FPUtil/builtin_wrappers.h
index 3924610bc716..fc524d24d623 100644
--- a/libc/src/__support/FPUtil/builtin_wrappers.h
+++ b/libc/src/__support/FPUtil/builtin_wrappers.h
@@ -65,22 +65,6 @@ template <typename T> static inline int unsafe_clz(T val) {
   return __internal::clz(val);
 }
 
-template <typename T> static inline bool isnan(T val) {
-  return __builtin_isnan(val);
-}
-
-template <typename T> static inline bool isinf(T val) {
-  return __builtin_isinf(val);
-}
-
-template <typename T> static inline bool isfinite(T val) {
-  return __builtin_isfinite(val);
-}
-
-inline float quiet_NaN(float) { return __builtin_nanf(""); }
-inline double quiet_NaN(double) { return __builtin_nan(""); }
-inline long double quiet_NaN(long double) { return __builtin_nanl(""); }
-
 } // namespace fputil
 } // namespace __llvm_libc
 

diff  --git a/libc/src/__support/FPUtil/generic/FMod.h b/libc/src/__support/FPUtil/generic/FMod.h
index 3a03f931657a..d33acea8bafb 100644
--- a/libc/src/__support/FPUtil/generic/FMod.h
+++ b/libc/src/__support/FPUtil/generic/FMod.h
@@ -115,28 +115,36 @@ namespace generic {
 //   https://man7.org/linux/man-pages/man3/fmod.3p.html
 // C standard for the function is not full, so not by default (although it can
 // be implemented in another handler.
+// Signaling NaN converted to quiet NaN with FE_INVALID exception.
+//    https://www.open-std.org/JTC1/SC22/WG14/www/docs/n1011.htm
 template <typename T> struct FModExceptionalInputHandler {
 
   static_assert(cpp::IsFloatingPointType<T>::Value,
                 "FModCStandardWrapper instantiated with invalid type.");
 
   static bool PreCheck(T x, T y, T &out) {
-    if (likely(y != 0 && fputil::isfinite(y) && fputil::isfinite(x))) {
+    using FPB = fputil::FPBits<T>;
+    const T quiet_NaN = FPB::build_nan(FPB::FloatProp::QUIET_NAN_MASK);
+    FPB sx(x), sy(y);
+    if (likely(!sy.is_zero() && !sy.is_inf_or_nan() && !sx.is_inf_or_nan())) {
       return false;
     }
 
-    if (fputil::isnan(x) || fputil::isnan(y)) {
-      out = fputil::quiet_NaN(T(0));
+    if (sx.is_nan() || sy.is_nan()) {
+      if ((sx.is_nan() && !sx.is_quiet_nan()) ||
+          (sy.is_nan() && !sy.is_quiet_nan()))
+        fputil::set_except(FE_INVALID);
+      out = quiet_NaN;
       return true;
     }
 
-    if (fputil::isinf(x) || y == 0) {
+    if (sx.is_inf() || sy.is_zero()) {
       fputil::set_except(FE_INVALID);
-      out = with_errno(fputil::quiet_NaN(T(0)), EDOM);
+      out = with_errno(quiet_NaN, EDOM);
       return true;
     }
 
-    if (fputil::isinf(y)) {
+    if (sy.is_inf()) {
       out = x;
       return true;
     }

diff  --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h
index 8761e8623de0..5f5d9bb00cde 100644
--- a/libc/src/__support/FPUtil/generic/sqrt.h
+++ b/libc/src/__support/FPUtil/generic/sqrt.h
@@ -51,8 +51,9 @@ inline void normalize<long double>(int &exponent, uint64_t &mantissa) {
 template <>
 inline void normalize<long double>(int &exponent, UInt128 &mantissa) {
   const uint64_t hi_bits = static_cast<uint64_t>(mantissa >> 64);
-  const int shift = hi_bits ? (unsafe_clz(hi_bits) - 15)
-                            : (unsafe_clz(static_cast<uint64_t>(mantissa)) + 49);
+  const int shift = hi_bits
+                        ? (unsafe_clz(hi_bits) - 15)
+                        : (unsafe_clz(static_cast<uint64_t>(mantissa)) + 49);
   exponent -= shift;
   mantissa <<= shift;
 }


        


More information about the libc-commits mailing list