Skip to content

[libc][math][c23] Add {ldexp,scalbn,scalbln}f16 C23 math functions #94797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 21, 2024

Conversation

overmighty
Copy link
Member

Part of #93566.

@overmighty
Copy link
Member Author

cc @lntue

@llvmbot llvmbot added the libc label Jun 7, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 7, 2024

@llvm/pr-subscribers-libc

Author: OverMighty (overmighty)

Changes

Part of #93566.


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

24 Files Affected:

  • (modified) libc/config/linux/aarch64/entrypoints.txt (+3)
  • (modified) libc/config/linux/x86_64/entrypoints.txt (+3)
  • (modified) libc/docs/math/index.rst (+4-2)
  • (modified) libc/spec/stdc.td (+4)
  • (modified) libc/src/__support/FPUtil/ManipulationFunctions.h (+5-3)
  • (modified) libc/src/__support/FPUtil/dyadic_float.h (+5)
  • (modified) libc/src/math/CMakeLists.txt (+4)
  • (modified) libc/src/math/generic/CMakeLists.txt (+41)
  • (added) libc/src/math/generic/ldexpf16.cpp (+19)
  • (added) libc/src/math/generic/scalblnf16.cpp (+25)
  • (added) libc/src/math/generic/scalbnf16.cpp (+25)
  • (added) libc/src/math/ldexpf16.h (+20)
  • (added) libc/src/math/scalblnf16.h (+20)
  • (added) libc/src/math/scalbnf16.h (+20)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+41)
  • (modified) libc/test/src/math/smoke/LdExpTest.h (+22-11)
  • (modified) libc/test/src/math/smoke/ScalbnTest.h (+2-2)
  • (added) libc/test/src/math/smoke/ldexpf16_test.cpp (+13)
  • (added) libc/test/src/math/smoke/scalblnf16_test.cpp (+13)
  • (modified) libc/test/src/math/smoke/scalbn_test.cpp (+1-1)
  • (modified) libc/test/src/math/smoke/scalbnf128_test.cpp (+1-1)
  • (added) libc/test/src/math/smoke/scalbnf16_test.cpp (+13)
  • (modified) libc/test/src/math/smoke/scalbnf_test.cpp (+1-1)
  • (modified) libc/test/src/math/smoke/scalbnl_test.cpp (+1-1)
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 33ecff813a1fb..f73b5c2f355d3 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -517,6 +517,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.fminimum_numf16
     libc.src.math.fromfpf16
     libc.src.math.fromfpxf16
+    libc.src.math.ldexpf16
     libc.src.math.llrintf16
     libc.src.math.llroundf16
     libc.src.math.lrintf16
@@ -532,6 +533,8 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.rintf16
     libc.src.math.roundf16
     libc.src.math.roundevenf16
+    libc.src.math.scalblnf16
+    libc.src.math.scalbnf16
     libc.src.math.truncf16
     libc.src.math.ufromfpf16
     libc.src.math.ufromfpxf16
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e3ca544ae0185..2fd89386c084d 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -549,6 +549,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.fminimum_numf16
     libc.src.math.fromfpf16
     libc.src.math.fromfpxf16
+    libc.src.math.ldexpf16
     libc.src.math.llrintf16
     libc.src.math.llroundf16
     libc.src.math.lrintf16
@@ -561,6 +562,8 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.rintf16
     libc.src.math.roundf16
     libc.src.math.roundevenf16
+    libc.src.math.scalblnf16
+    libc.src.math.scalbnf16
     libc.src.math.truncf16
     libc.src.math.ufromfpf16
     libc.src.math.ufromfpxf16
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index b9507f0887cd7..fbcec72b0a1c7 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -170,7 +170,7 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | ilogb            | |check|          | |check|         | |check|                |                      | |check|                | 7.12.6.8               | F.10.3.8                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| ldexp            | |check|          | |check|         | |check|                |                      | |check|                | 7.12.6.9               | F.10.3.9                   |
+| ldexp            | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.6.9               | F.10.3.9                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | llogb            | |check|          | |check|         | |check|                |                      | |check|                | 7.12.6.10              | F.10.3.10                  |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
@@ -208,7 +208,9 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | roundeven        | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.9.8               | F.10.6.8                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| scalbn           | |check|          | |check|         | |check|                |                      | |check|                | 7.12.6.19              | F.10.3.19                  |
+| scalbln          |                  |                 |                        | |check|              |                        | 7.12.6.19              | F.10.3.19                  |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
+| scalbn           | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.6.19              | F.10.3.19                  |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | trunc            | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.9.9               | F.10.6.9                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 9a436c8ae38d2..ed3461bfeab53 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -525,6 +525,7 @@ def StdC : StandardSpec<"stdc"> {
           FunctionSpec<"ldexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
           FunctionSpec<"ldexpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
           FunctionSpec<"ldexpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>]>,
+          GuardedFunctionSpec<"ldexpf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT16">,
           GuardedFunctionSpec<"ldexpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT128">,
 
           FunctionSpec<"log10", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
@@ -682,9 +683,12 @@ def StdC : StandardSpec<"stdc"> {
           FunctionSpec<"asinhf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
           FunctionSpec<"atanhf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
 
+          GuardedFunctionSpec<"scalblnf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<LongType>], "LIBC_TYPES_HAS_FLOAT16">,
+
           FunctionSpec<"scalbn", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
           FunctionSpec<"scalbnf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
           FunctionSpec<"scalbnl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>]>,
+          GuardedFunctionSpec<"scalbnf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT16">,
           GuardedFunctionSpec<"scalbnf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntType>], "LIBC_TYPES_HAS_FLOAT128">,
 
           FunctionSpec<"nanf", RetValSpec<FloatType>, [ArgSpec<ConstCharPtr>]>,
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index a289c2ef70467..a9c64122d9311 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -143,7 +143,7 @@ LIBC_INLINE constexpr T logb(T x) {
 }
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE constexpr T ldexp(T x, int exp) {
+LIBC_INLINE constexpr T ldexp(T x, long exp) {
   FPBits<T> bits(x);
   if (LIBC_UNLIKELY((exp == 0) || bits.is_zero() || bits.is_inf_or_nan()))
     return x;
@@ -185,8 +185,10 @@ LIBC_INLINE constexpr T ldexp(T x, int exp) {
   }
 
   // For all other values, NormalFloat to T conversion handles it the right way.
-  DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
-  normal.exponent += exp;
+  DyadicFloat<cpp::max(FPBits<T>::STORAGE_LEN, 32)> normal(bits.get_val());
+  // Make sure that exp fits into an int when not taking the fast paths above.
+  static_assert(EXP_LIMIT <= INT_MAX && -EXP_LIMIT >= INT_MIN);
+  normal.exponent += static_cast<int>(exp);
   return static_cast<T>(normal);
 }
 
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 12a69228d36c7..f1791f9da56ad 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -14,6 +14,7 @@
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/big_int.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/properties/types.h" // float16
 
 #include <stddef.h>
 
@@ -183,6 +184,10 @@ template <size_t Bits> struct DyadicFloat {
     return r;
   }
 
+  LIBC_INLINE explicit constexpr operator float16() const {
+    return static_cast<float16>(static_cast<float>(*this));
+  }
+
   LIBC_INLINE explicit constexpr operator MantissaType() const {
     if (mantissa.is_zero())
       return 0;
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 7a349ddc53724..f7d3998fe318c 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -218,6 +218,7 @@ add_math_entrypoint_object(llogbf128)
 add_math_entrypoint_object(ldexp)
 add_math_entrypoint_object(ldexpf)
 add_math_entrypoint_object(ldexpl)
+add_math_entrypoint_object(ldexpf16)
 add_math_entrypoint_object(ldexpf128)
 
 add_math_entrypoint_object(log10)
@@ -329,9 +330,12 @@ add_math_entrypoint_object(roundevenl)
 add_math_entrypoint_object(roundevenf16)
 add_math_entrypoint_object(roundevenf128)
 
+add_math_entrypoint_object(scalblnf16)
+
 add_math_entrypoint_object(scalbn)
 add_math_entrypoint_object(scalbnf)
 add_math_entrypoint_object(scalbnl)
+add_math_entrypoint_object(scalbnf16)
 add_math_entrypoint_object(scalbnf128)
 
 add_math_entrypoint_object(sincos)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index b1d786fc6b29f..406afa6fa251a 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1448,6 +1448,19 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.manipulation_functions
 )
 
+add_entrypoint_object(
+  ldexpf16
+  SRCS
+    ldexpf16.cpp
+  HDRS
+    ../ldexpf16.h
+  COMPILE_OPTIONS
+    -O0 -ggdb3
+  DEPENDS
+    libc.src.__support.macros.properties.types
+    libc.src.__support.FPUtil.manipulation_functions
+)
+
 add_entrypoint_object(
   ldexpf128
   SRCS
@@ -3355,6 +3368,20 @@ add_entrypoint_object(
     libc.src.__support.macros.optimization
 )
 
+add_entrypoint_object(
+  scalblnf16
+  SRCS
+    scalblnf16.cpp
+  HDRS
+    ../scalblnf16.h
+  DEPENDS
+    libc.hdr.float_macros
+    libc.src.__support.macros.properties.types
+    libc.src.__support.FPUtil.manipulation_functions
+  COMPILE_OPTIONS
+    -O3
+)
+
 add_entrypoint_object(
   scalbn
   SRCS
@@ -3394,6 +3421,20 @@ add_entrypoint_object(
     -O3
 )
 
+add_entrypoint_object(
+  scalbnf16
+  SRCS
+    scalbnf16.cpp
+  HDRS
+    ../scalbnf16.h
+  DEPENDS
+    libc.hdr.float_macros
+    libc.src.__support.macros.properties.types
+    libc.src.__support.FPUtil.manipulation_functions
+  COMPILE_OPTIONS
+    -O3
+)
+
 add_entrypoint_object(
   scalbnf128
   SRCS
diff --git a/libc/src/math/generic/ldexpf16.cpp b/libc/src/math/generic/ldexpf16.cpp
new file mode 100644
index 0000000000000..ed15c4572edf5
--- /dev/null
+++ b/libc/src/math/generic/ldexpf16.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of ldexpf16 function -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/ldexpf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, ldexpf16, (float16 x, int exp)) {
+  return fputil::ldexp(x, exp);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/scalblnf16.cpp b/libc/src/math/generic/scalblnf16.cpp
new file mode 100644
index 0000000000000..844a071d754a6
--- /dev/null
+++ b/libc/src/math/generic/scalblnf16.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of scalblnf16 function -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/scalblnf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+#include "hdr/float_macros.h"
+
+#if FLT_RADIX != 2
+#error "FLT_RADIX != 2 is not supported."
+#endif
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, scalblnf16, (float16 x, long n)) {
+  return fputil::ldexp(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/scalbnf16.cpp b/libc/src/math/generic/scalbnf16.cpp
new file mode 100644
index 0000000000000..a42fdfffd569f
--- /dev/null
+++ b/libc/src/math/generic/scalbnf16.cpp
@@ -0,0 +1,25 @@
+//===-- Implementation of scalbnf16 function ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/scalbnf16.h"
+#include "src/__support/FPUtil/ManipulationFunctions.h"
+#include "src/__support/common.h"
+
+#include "hdr/float_macros.h"
+
+#if FLT_RADIX != 2
+#error "FLT_RADIX != 2 is not supported."
+#endif
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, scalbnf16, (float16 x, int n)) {
+  return fputil::ldexp(x, n);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/ldexpf16.h b/libc/src/math/ldexpf16.h
new file mode 100644
index 0000000000000..7303610b18dff
--- /dev/null
+++ b/libc/src/math/ldexpf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ldexpf16 ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_LDEXPF16_H
+#define LLVM_LIBC_SRC_MATH_LDEXPF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 ldexpf16(float16 x, int exp);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_LDEXPF16_H
diff --git a/libc/src/math/scalblnf16.h b/libc/src/math/scalblnf16.h
new file mode 100644
index 0000000000000..be93fab1bf68a
--- /dev/null
+++ b/libc/src/math/scalblnf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for scalblnf16 --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_SCALBLNF16_H
+#define LLVM_LIBC_SRC_MATH_SCALBLNF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 scalblnf16(float16 x, long n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_SCALBLNF16_H
diff --git a/libc/src/math/scalbnf16.h b/libc/src/math/scalbnf16.h
new file mode 100644
index 0000000000000..95e4862f38070
--- /dev/null
+++ b/libc/src/math/scalbnf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for scalbnf16 ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_SCALBNF16_H
+#define LLVM_LIBC_SRC_MATH_SCALBNF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 scalbnf16(float16 x, int n);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_SCALBNF16_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 110fa1de97d6d..a302e9d89511d 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1508,6 +1508,21 @@ add_fp_unittest(
     libc.src.__support.FPUtil.normal_float
 )
 
+add_fp_unittest(
+  ldexpf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    ldexpf16_test.cpp
+  HDRS
+    LdExpTest.h
+  DEPENDS
+    libc.src.math.ldexpf16
+    libc.src.__support.CPP.limits
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.normal_float
+)
+
 add_fp_unittest(
   ldexpf128_test
   SUITE
@@ -3291,6 +3306,19 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  scalblnf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    scalblnf16_test.cpp
+  HDRS
+    ScalbnTest.h
+  DEPENDS
+    libc.src.math.scalblnf16
+    libc.src.__support.FPUtil.fp_bits
+)
+
 add_fp_unittest(
   scalbn_test
   SUITE
@@ -3330,6 +3358,19 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  scalbnf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    scalbnf16_test.cpp
+  HDRS
+    ScalbnTest.h
+  DEPENDS
+    libc.src.math.scalbnf16
+    libc.src.__support.FPUtil.fp_bits
+)
+
 add_fp_unittest(
   scalbnf128_test
   SUITE
diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h
index 713d305c47494..231535a9a505e 100644
--- a/libc/test/src/math/smoke/LdExpTest.h
+++ b/libc/test/src/math/smoke/LdExpTest.h
@@ -18,7 +18,7 @@
 
 #include <stdint.h>
 
-template <typename T>
+template <typename T, typename U = int>
 class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
   using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
@@ -31,13 +31,13 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
   const T nan = FPBits::quiet_nan().get_val();
 
   // A normalized mantissa to be used with tests.
-  static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;
+  static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x123;
 
 public:
-  typedef T (*LdExpFunc)(T, int);
+  typedef T (*LdExpFunc)(T, U);
 
   void testSpecialNumbers(LdExpFunc func) {
-    int exp_array[5] = {-INT_MAX - 1, -10, 0, 10, INT_MAX};
+    int exp_array[5] = {INT_MIN, -10, 0, 10, INT_MAX};
     for (int exp : exp_array) {
       ASSERT_FP_EQ(zero, func(zero, exp));
       ASSERT_FP_EQ(neg_zero, func(neg_zero, exp));
@@ -45,6 +45,17 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
       ASSERT_FP_EQ(neg_inf, func(neg_inf, exp));
       ASSERT_FP_EQ(nan, func(nan, exp));
     }
+
+    if constexpr (sizeof(U) < sizeof(long) || sizeof(long) == sizeof(int))
+      return;
+    long long_exp_array[4] = {LONG_MIN, INT_MIN - 1L, INT_MAX + 1L, LONG_MAX};
+    for (long exp : long_exp_array) {
+      ASSERT_FP_EQ(zero, func(zero, exp));
+      ASSERT_FP_EQ(neg_zero, func(neg_zero, exp));
+      ASSERT_FP_EQ(inf, func(inf, exp));
+      ASSERT_FP_EQ(neg_inf, func(neg_inf, exp));
+      ASSERT_FP_EQ(nan, func(nan, exp));
+    }
   }
 
   void testPowersOfTwo(LdExpFunc func) {
@@ -60,7 +71,7 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
   void testOverflow(LdExpFunc func) {
     NormalFloat x(Sign::POS, FPBits::MAX_BIASED_EXPONENT - 10,
-                  NormalFloat::ONE + 0xF00BA);
+                  NormalFloat::ONE + 0xF00);
     for (int32_t exp = 10; exp < 100; ++exp) {
       ASSERT_FP_EQ(inf, func(T(x), exp));
       ASSERT_FP_EQ(neg_inf, func(-T(x), exp));
@@ -95,10 +106,10 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
   void testNormalOperation(LdExpFunc f...
[truncated]

static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;
static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x123;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x1234 is 13 bits, too large for float16's 10-bit fraction.

(Comment moved from #94758.)

Comment on lines 63 to 74
NormalFloat::ONE + 0xF00BA);
NormalFloat::ONE + 0xF00);
Copy link
Member Author

@overmighty overmighty Jun 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0xF00BA is 20 bits, too large for float16's 10-bit fraction.

(Comment moved from #94758.)

Wait, 0xF00 is also too large. Changed it again to 0xFB.

Comment on lines -98 to +112
NormalFloat(Sign::POS, 100, MANTISSA),
NormalFloat(Sign::POS, -100, MANTISSA),
NormalFloat(Sign::NEG, 100, MANTISSA),
NormalFloat(Sign::NEG, -100, MANTISSA),
NormalFloat(Sign::POS, 10, MANTISSA),
NormalFloat(Sign::POS, -10, MANTISSA),
NormalFloat(Sign::NEG, 10, MANTISSA),
NormalFloat(Sign::NEG, -10, MANTISSA),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exponents -100 and 100 are too large for float16.

(Comment moved from #94758.)

@overmighty
Copy link
Member Author

Rebased and resolved merge conflicts.

@overmighty overmighty force-pushed the libc-math-ldexpf16 branch from e4fa07a to 12445c3 Compare June 18, 2024 14:52
@overmighty
Copy link
Member Author

Rebased.

@overmighty overmighty force-pushed the libc-math-ldexpf16 branch from 1c8c91b to 33952e5 Compare June 21, 2024 12:40
@overmighty
Copy link
Member Author

Rebased and resolved merge conflicts.

@lntue lntue merged commit b5efd21 into llvm:main Jun 21, 2024
5 of 6 checks passed
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants