[libc-commits] [libc] [libc] Fix #124812 issue (PR #133326)

via libc-commits libc-commits at lists.llvm.org
Thu Mar 27 14:58:17 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: wldfngrs (wldfngrs)

<details>
<summary>Changes</summary>

Add tests for signaling NaNs, and fix function behavior for handling signaling NaN input
https://github.com/llvm/llvm-project/issues/124812#

---

Patch is 59.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/133326.diff


80 Files Affected:

- (modified) libc/src/math/generic/CMakeLists.txt (+3) 
- (modified) libc/src/math/generic/acosf.cpp (+7) 
- (modified) libc/src/math/generic/asinf.cpp (+6) 
- (modified) libc/src/math/generic/asinhf.cpp (+7-1) 
- (modified) libc/src/math/generic/atan2.cpp (+5-1) 
- (modified) libc/src/math/generic/atan2f.cpp (+6-1) 
- (modified) libc/src/math/generic/atanhf.cpp (+4) 
- (modified) libc/src/math/generic/cos.cpp (+5-1) 
- (modified) libc/src/math/generic/cosf.cpp (+5) 
- (modified) libc/src/math/generic/cosf16.cpp (+5) 
- (modified) libc/src/math/generic/cospif.cpp (+5) 
- (modified) libc/src/math/generic/cospif16.cpp (+4) 
- (modified) libc/src/math/generic/erff.cpp (+4) 
- (modified) libc/src/math/generic/log1p.cpp (+6-1) 
- (modified) libc/src/math/generic/logf.cpp (+5) 
- (modified) libc/src/math/generic/pow.cpp (+6-1) 
- (modified) libc/src/math/generic/powf.cpp (+5) 
- (modified) libc/src/math/generic/sin.cpp (+5) 
- (modified) libc/src/math/generic/sincos.cpp (+7-1) 
- (modified) libc/src/math/generic/sincosf.cpp (+6) 
- (modified) libc/src/math/generic/sinf.cpp (+5) 
- (modified) libc/src/math/generic/sinf16.cpp (+5) 
- (modified) libc/src/math/generic/sinpif.cpp (+5) 
- (modified) libc/src/math/generic/sinpif16.cpp (+4) 
- (modified) libc/src/math/generic/tan.cpp (+4) 
- (modified) libc/src/math/generic/tanf.cpp (+5) 
- (modified) libc/src/math/generic/tanf16.cpp (+4) 
- (modified) libc/src/math/generic/tanpif16.cpp (+6-1) 
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+1) 
- (modified) libc/test/src/math/smoke/acosf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/acoshf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/asinf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/asinhf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/atan2_test.cpp (+9) 
- (modified) libc/test/src/math/smoke/atan2f_test.cpp (+9) 
- (modified) libc/test/src/math/smoke/atan_test.cpp (+3-1) 
- (modified) libc/test/src/math/smoke/atanf_test.cpp (+2) 
- (modified) libc/test/src/math/smoke/atanhf_test.cpp (+2-1) 
- (modified) libc/test/src/math/smoke/cbrt_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/cbrtf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/cos_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/cosf16_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/cosf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/coshf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/cospif16_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/cospif_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/erff_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/exp10_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/exp10f_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/exp10m1f_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/exp2_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/exp2f_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/exp2m1f_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/exp_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/expf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/expm1_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/expm1f_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/log10_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/log10f_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/log1p_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/log1pf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/log2_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/log2f_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/log_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/logf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/pow_test.cpp (+22-1) 
- (modified) libc/test/src/math/smoke/powf_test.cpp (+23-1) 
- (modified) libc/test/src/math/smoke/sin_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/sincos_test.cpp (+5) 
- (modified) libc/test/src/math/smoke/sincosf_test.cpp (+5) 
- (modified) libc/test/src/math/smoke/sinf16_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/sinf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/sinhf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/sinpif16_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/sinpif_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/tan_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/tanf16_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/tanf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/tanhf_test.cpp (+3) 
- (modified) libc/test/src/math/smoke/tanpif16_test.cpp (+3) 


``````````diff
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 77c6244c5e5da..056f3e61b7e62 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -4129,7 +4129,9 @@ add_entrypoint_object(
     atan2f_float.h
   DEPENDS
     .inv_trigf_utils
+    libc.hdr.fenv_macros
     libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.multiply_add
     libc.src.__support.FPUtil.nearest_integer
@@ -4147,6 +4149,7 @@ add_entrypoint_object(
   DEPENDS
     .atan_utils
     libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.multiply_add
     libc.src.__support.FPUtil.nearest_integer
diff --git a/libc/src/math/generic/acosf.cpp b/libc/src/math/generic/acosf.cpp
index 509a5ebc4973e..87a154e6f7b2f 100644
--- a/libc/src/math/generic/acosf.cpp
+++ b/libc/src/math/generic/acosf.cpp
@@ -84,10 +84,17 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
                           0x1.921fb6p+1f)
                     : /* x == 1.0f */ 0.0f;
 
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    
+    // |x| <= +/-inf
     if (x_abs <= 0x7f80'0000U) {
       fputil::set_errno_if_required(EDOM);
       fputil::raise_except_if_required(FE_INVALID);
     }
+    
     return x + FPBits::quiet_nan().get_val();
   }
 
diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp
index da854417e85fe..2172171c3b6c9 100644
--- a/libc/src/math/generic/asinf.cpp
+++ b/libc/src/math/generic/asinf.cpp
@@ -108,10 +108,16 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
 
   // |x| > 1, return NaNs.
   if (LIBC_UNLIKELY(x_abs > 0x3f80'0000U)) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    
     if (x_abs <= 0x7f80'0000U) {
       fputil::set_errno_if_required(EDOM);
       fputil::raise_except_if_required(FE_INVALID);
     }
+    
     return FPBits::quiet_nan().get_val();
   }
 
diff --git a/libc/src/math/generic/asinhf.cpp b/libc/src/math/generic/asinhf.cpp
index 37b87a821222a..817a4d4b6a24a 100644
--- a/libc/src/math/generic/asinhf.cpp
+++ b/libc/src/math/generic/asinhf.cpp
@@ -61,8 +61,14 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
   };
 
   if (LIBC_UNLIKELY(x_abs >= 0x4bdd'65a5U)) {
-    if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
+    if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits_t::quiet_nan().get_val();
+      }
+
       return x;
+    }
 
     // Exceptional cases when x > 2^24.
     switch (x_abs) {
diff --git a/libc/src/math/generic/atan2.cpp b/libc/src/math/generic/atan2.cpp
index 8adfe3321a9ee..c757b744a91fc 100644
--- a/libc/src/math/generic/atan2.cpp
+++ b/libc/src/math/generic/atan2.cpp
@@ -8,6 +8,7 @@
 
 #include "src/math/atan2.h"
 #include "atan_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/double_double.h"
 #include "src/__support/FPUtil/multiply_add.h"
@@ -111,8 +112,11 @@ LLVM_LIBC_FUNCTION(double, atan2, (double y, double x)) {
   // Check for exceptional cases, whether inputs are 0, inf, nan, or close to
   // overflow, or close to underflow.
   if (LIBC_UNLIKELY(max_exp > 0x7ffU - 128U || min_exp < 128U)) {
-    if (x_bits.is_nan() || y_bits.is_nan())
+    if (x_bits.is_nan() || y_bits.is_nan()) {
+      if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan())
+	      fputil::raise_except_if_required(FE_INVALID);
       return FPBits::quiet_nan().get_val();
+    }
     unsigned x_except = x == 0.0 ? 0 : (FPBits(x_abs).is_inf() ? 2 : 1);
     unsigned y_except = y == 0.0 ? 0 : (FPBits(y_abs).is_inf() ? 2 : 1);
 
diff --git a/libc/src/math/generic/atan2f.cpp b/libc/src/math/generic/atan2f.cpp
index 726cae9c8462b..9b3397f2446a5 100644
--- a/libc/src/math/generic/atan2f.cpp
+++ b/libc/src/math/generic/atan2f.cpp
@@ -7,7 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/atan2f.h"
+#include "hdr/fenv_macros.h"
 #include "inv_trigf_utils.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/PolyEval.h"
 #include "src/__support/FPUtil/double_double.h"
@@ -264,8 +266,11 @@ LLVM_LIBC_FUNCTION(float, atan2f, (float y, float x)) {
   double den_d = static_cast<double>(den_f);
 
   if (LIBC_UNLIKELY(max_abs >= 0x7f80'0000U || num_d == 0.0)) {
-    if (x_bits.is_nan() || y_bits.is_nan())
+    if (x_bits.is_nan() || y_bits.is_nan()) {
+      if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan())
+	      fputil::raise_except_if_required(FE_INVALID);
       return FPBits::quiet_nan().get_val();
+    }
     double x_d = static_cast<double>(x);
     double y_d = static_cast<double>(y);
     size_t x_except = (x_d == 0.0) ? 0 : (x_abs == 0x7f80'0000 ? 2 : 1);
diff --git a/libc/src/math/generic/atanhf.cpp b/libc/src/math/generic/atanhf.cpp
index a2051bd3e3e67..f0a7529af79d8 100644
--- a/libc/src/math/generic/atanhf.cpp
+++ b/libc/src/math/generic/atanhf.cpp
@@ -24,6 +24,10 @@ LLVM_LIBC_FUNCTION(float, atanhf, (float x)) {
   // |x| >= 1.0
   if (LIBC_UNLIKELY(x_abs >= 0x3F80'0000U)) {
     if (xbits.is_nan()) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
       return x;
     }
     // |x| == 1.0
diff --git a/libc/src/math/generic/cos.cpp b/libc/src/math/generic/cos.cpp
index b60082bf9c308..1cda012280d5d 100644
--- a/libc/src/math/generic/cos.cpp
+++ b/libc/src/math/generic/cos.cpp
@@ -65,7 +65,11 @@ LLVM_LIBC_FUNCTION(double, cos, (double x)) {
   } else {
     // Inf or NaN
     if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
-      // sin(+-Inf) = NaN
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
+      // cos(+-Inf) = NaN
       if (xbits.get_mantissa() == 0) {
         fputil::set_errno_if_required(EDOM);
         fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp
index 6ea24f9ccd3fa..b0b573aaf3a66 100644
--- a/libc/src/math/generic/cosf.cpp
+++ b/libc/src/math/generic/cosf.cpp
@@ -117,6 +117,11 @@ LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
 
   // x is inf or nan.
   if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    
     if (x_abs == 0x7f80'0000U) {
       fputil::set_errno_if_required(EDOM);
       fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/cosf16.cpp b/libc/src/math/generic/cosf16.cpp
index 4d42db981ce71..3d0145e44ff98 100644
--- a/libc/src/math/generic/cosf16.cpp
+++ b/libc/src/math/generic/cosf16.cpp
@@ -67,6 +67,11 @@ LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) {
 
   // cos(+/-inf) = NaN, and cos(NaN) = NaN
   if (xbits.is_inf_or_nan()) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    
     if (xbits.is_inf()) {
       fputil::set_errno_if_required(EDOM);
       fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/cospif.cpp b/libc/src/math/generic/cospif.cpp
index 29566f4fceacf..cfa7de6064a6e 100644
--- a/libc/src/math/generic/cospif.cpp
+++ b/libc/src/math/generic/cospif.cpp
@@ -66,6 +66,11 @@ LLVM_LIBC_FUNCTION(float, cospif, (float x)) {
 
     // x is inf or nan.
     if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
+      
       if (x_abs == 0x7f80'0000U) {
         fputil::set_errno_if_required(EDOM);
         fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/cospif16.cpp b/libc/src/math/generic/cospif16.cpp
index ee74bdb4a3693..67157a6a65fcc 100644
--- a/libc/src/math/generic/cospif16.cpp
+++ b/libc/src/math/generic/cospif16.cpp
@@ -54,6 +54,10 @@ LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) {
 
     // Check for NaN or infintiy values
     if (LIBC_UNLIKELY(x_abs >= 0x7c00)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
       // If value is equal to infinity
       if (x_abs == 0x7c00) {
         fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/erff.cpp b/libc/src/math/generic/erff.cpp
index 016afe4a68140..b5e7d0773f11b 100644
--- a/libc/src/math/generic/erff.cpp
+++ b/libc/src/math/generic/erff.cpp
@@ -135,6 +135,10 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
     int sign = xbits.is_neg() ? 1 : 0;
 
     if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
       return (x_abs > 0x7f80'0000) ? x : ONE[sign];
     }
 
diff --git a/libc/src/math/generic/log1p.cpp b/libc/src/math/generic/log1p.cpp
index 058409fed081d..c97904008e5f7 100644
--- a/libc/src/math/generic/log1p.cpp
+++ b/libc/src/math/generic/log1p.cpp
@@ -910,7 +910,12 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) {
           return FPBits_t::quiet_nan().get_val();
         }
         // x is +Inf or NaN
-        return x;
+	if (xbits.is_inf() && xbits.is_pos())
+	  return x;
+
+        if (xbits.is_signaling_nan())
+              fputil::raise_except_if_required(FE_INVALID);
+        return FPBits_t::quiet_nan().get_val();
       }
       x_dd.hi = x;
     } else {
diff --git a/libc/src/math/generic/logf.cpp b/libc/src/math/generic/logf.cpp
index 032d658a941be..29247e366ca57 100644
--- a/libc/src/math/generic/logf.cpp
+++ b/libc/src/math/generic/logf.cpp
@@ -132,6 +132,11 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
         return FPBits::quiet_nan().get_val();
       }
       // x is +inf or nan
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
+
       return x;
     }
   }
diff --git a/libc/src/math/generic/pow.cpp b/libc/src/math/generic/pow.cpp
index 8a12934f6c4ba..45d7fbd581398 100644
--- a/libc/src/math/generic/pow.cpp
+++ b/libc/src/math/generic/pow.cpp
@@ -217,7 +217,12 @@ LLVM_LIBC_FUNCTION(double, pow, (double x, double y)) {
   uint64_t sign = 0;
 
   ///////// BEGIN - Check exceptional cases ////////////////////////////////////
-
+  // If x or y is signaling NaN
+  if (x_abs.is_signaling_nan() || y_abs.is_signaling_nan()) {
+    fputil::raise_except_if_required(FE_INVALID);
+    return FPBits::quiet_nan().get_val();
+  }
+  
   // The double precision number that is closest to 1 is (1 - 2^-53), which has
   //   log2(1 - 2^-53) ~ -1.715...p-53.
   // So if |y| > |1075 / log2(1 - 2^-53)|, and x is finite:
diff --git a/libc/src/math/generic/powf.cpp b/libc/src/math/generic/powf.cpp
index 2d7deca3c77bb..2df1c57ed2d34 100644
--- a/libc/src/math/generic/powf.cpp
+++ b/libc/src/math/generic/powf.cpp
@@ -657,6 +657,11 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
   uint32_t y_abs = ybits.abs().uintval();
 
   ///////// BEGIN - Check exceptional cases ////////////////////////////////////
+  // if x or y is signaling NaN
+  if (xbits.is_signaling_nan() || ybits.is_signaling_nan()) {
+    fputil::raise_except_if_required(FE_INVALID);
+    return FloatBits::quiet_nan().get_val();
+  }
 
   // The single precision number that is closest to 1 is (1 - 2^-24), which has
   //   log2(1 - 2^-24) ~ -1.715...p-24.
diff --git a/libc/src/math/generic/sin.cpp b/libc/src/math/generic/sin.cpp
index 4a58dcf4b173f..64cd8a6072981 100644
--- a/libc/src/math/generic/sin.cpp
+++ b/libc/src/math/generic/sin.cpp
@@ -77,6 +77,11 @@ LLVM_LIBC_FUNCTION(double, sin, (double x)) {
     // Inf or NaN
     if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
       // sin(+-Inf) = NaN
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
+      
       if (xbits.get_mantissa() == 0) {
         fputil::set_errno_if_required(EDOM);
         fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/sincos.cpp b/libc/src/math/generic/sincos.cpp
index 0ac2f7f997527..42b0ade465880 100644
--- a/libc/src/math/generic/sincos.cpp
+++ b/libc/src/math/generic/sincos.cpp
@@ -85,7 +85,13 @@ LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) {
   } else {
     // Inf or NaN
     if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
-      // sin(+-Inf) = NaN
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+        *sin_x = *cos_x = FPBits::quiet_nan().get_val();
+	return;
+      }
+
+      // sin(+-Inf) = NaN 
       if (xbits.get_mantissa() == 0) {
         fputil::set_errno_if_required(EDOM);
         fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/sincosf.cpp b/libc/src/math/generic/sincosf.cpp
index 623ef636afb1e..8b23b60103256 100644
--- a/libc/src/math/generic/sincosf.cpp
+++ b/libc/src/math/generic/sincosf.cpp
@@ -145,6 +145,12 @@ LLVM_LIBC_FUNCTION(void, sincosf, (float x, float *sinp, float *cosp)) {
 
   // x is inf or nan.
   if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      *sinp = *cosp = FPBits::quiet_nan().get_val();
+      return;
+    }
+    
     if (x_abs == 0x7f80'0000U) {
       fputil::set_errno_if_required(EDOM);
       fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/sinf.cpp b/libc/src/math/generic/sinf.cpp
index d27ce843a2c92..bc4858c22eef2 100644
--- a/libc/src/math/generic/sinf.cpp
+++ b/libc/src/math/generic/sinf.cpp
@@ -136,6 +136,11 @@ LLVM_LIBC_FUNCTION(float, sinf, (float x)) {
 #endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    
     if (x_abs == 0x7f80'0000U) {
       fputil::set_errno_if_required(EDOM);
       fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/sinf16.cpp b/libc/src/math/generic/sinf16.cpp
index 85e55a614588a..da02683997326 100644
--- a/libc/src/math/generic/sinf16.cpp
+++ b/libc/src/math/generic/sinf16.cpp
@@ -87,6 +87,11 @@ LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) {
   }
 
   if (xbits.is_inf_or_nan()) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
+    
     if (xbits.is_inf()) {
       fputil::set_errno_if_required(EDOM);
       fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/sinpif.cpp b/libc/src/math/generic/sinpif.cpp
index f572ded06b25a..b78032310b023 100644
--- a/libc/src/math/generic/sinpif.cpp
+++ b/libc/src/math/generic/sinpif.cpp
@@ -83,6 +83,11 @@ LLVM_LIBC_FUNCTION(float, sinpif, (float x)) {
 
     // check for NaN values
     if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
+      
       if (x_abs == 0x7f80'0000U) {
         fputil::set_errno_if_required(EDOM);
         fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/sinpif16.cpp b/libc/src/math/generic/sinpif16.cpp
index 51ea595653b4d..48f8c3fae4f2b 100644
--- a/libc/src/math/generic/sinpif16.cpp
+++ b/libc/src/math/generic/sinpif16.cpp
@@ -50,6 +50,10 @@ LLVM_LIBC_FUNCTION(float16, sinpif16, (float16 x)) {
   if (LIBC_UNLIKELY(x_abs >= 0x6400)) {
     // Check for NaN or infinity values
     if (LIBC_UNLIKELY(x_abs >= 0x7c00)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
       // If value is equal to infinity
       if (x_abs == 0x7c00) {
         fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/tan.cpp b/libc/src/math/generic/tan.cpp
index a899a2128d384..1228d2153990e 100644
--- a/libc/src/math/generic/tan.cpp
+++ b/libc/src/math/generic/tan.cpp
@@ -163,6 +163,10 @@ LLVM_LIBC_FUNCTION(double, tan, (double x)) {
   } else {
     // Inf or NaN
     if (LIBC_UNLIKELY(x_e > 2 * FPBits::EXP_BIAS)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      }
       // tan(+-Inf) = NaN
       if (xbits.get_mantissa() == 0) {
         fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/tanf.cpp b/libc/src/math/generic/tanf.cpp
index a15aa9796cbd8..974ad69ef8395 100644
--- a/libc/src/math/generic/tanf.cpp
+++ b/libc/src/math/generic/tanf.cpp
@@ -113,6 +113,11 @@ LLVM_LIBC_FUNCTION(float, tanf, (float x)) {
   if (LIBC_UNLIKELY(x_abs > 0x4d56'd354U)) {
     // Inf or NaN
     if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
+      if (xbits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+	return FPBits::quiet_nan().get_val();
+      } 
+     
       if (x_abs == 0x7f80'0000U) {
         fputil::set_errno_if_required(EDOM);
         fputil::raise_except_if_required(FE_INVALID);
diff --git a/libc/src/math/generic/tanf16.cpp b/libc/src/math/generic/tanf16.cpp
index 97d201b65bbe6..229f4a363670b 100644
--- a/libc/src/math/generic/tanf16.cpp
+++ b/libc/src/math/generic/tanf16.cpp
@@ -84,6 +84,10 @@ LLVM_LIBC_FUNCTION(float16, tanf16, (float16 x)) {
 
   // tan(+/-inf) = NaN, and tan(NaN) = NaN
   if (LIBC_UNLIKELY(x_abs >= 0x7c00)) {
+    if (xbits.is_signaling_nan()) {
+      fputil::raise_except_if_required(FE_INVALID);
+      return FPBits::quiet_nan().get_val();
+    }
     // x = +/-inf
     if (x_abs == 0x7c00) {
       fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/tanpif16.cpp b/libc/src/math/generic/tanpif16.cpp
index 71cf25c9741a1..aeb41719b9a42 100644
--- a/libc/src/math/generic/tanpif16.cpp
+++ b/libc/src/math/generic/tanpif16.cpp
@@ -63,7 +63,12 @@ LLVM_LIBC_FUNCTION(float16, tanpif16, (float16 x)) {
   if (LIBC_UNLIKELY(x_abs >= 0x6400)) {
     // Check for NaN or infinity values
     if (LIBC_UNLIKELY(x_abs >= 0x7c00)) {
-      if (x_abs == 0x7c00) {
+     if (xbits.is_signaling_nan()) {
+       fputil::raise_except_if_required(FE_INVALID);
+       return FPBits::quiet_nan().get_val();
+     } 
+     // is inf 
+     if (x_abs == 0x7c00) {
         fputil::set_errno_if_required(EDOM);
         fputil::raise_except_if_required(FE_INVALID);
       }
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 660b68687d63c..54f5e40cdce11 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -4228,6 +4228,7 @@ add_fp_unittest(
   SRCS
     pow_test.cpp
   DEPENDS
+    libc.src.errno.errno
     libc.hdr.fenv_macros
     libc.src.math.pow
 )
diff --git a/libc/test/src/math/smoke/acosf_test.cpp b/libc/test/src/math/smoke/acosf_test.cpp
index e5d56c70f2722..74f68e00011aa 100644
--- a/libc/test/src/math/smoke/acosf_test.cpp
+++ b/libc/test/src/math/smoke/acosf_test.cpp
@@ -20,6 +20,9 @@ using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>;
 TEST_F(LlvmLibcAcosfTest, SpecialNumbers) {
   LIBC_NAMESPACE::libc_errno = 0;
 
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acosf(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
   EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acosf(aNaN));
   EXPECT_MATH_ERRNO(0);
 
diff --git a/libc/test/src/math/smoke/acoshf_test.cpp b/libc/test/src/math/smoke/acoshf_test.cpp
index c4e88259919c3..c5ba88055ac57 100644
--- a/libc/test/src/math/smoke/acoshf_test.cpp
+++ b/libc/test/src/math/smoke/acoshf_test.cpp
@@ ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/133326


More information about the libc-commits mailing list