Skip to content
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

[libc][math][c23] Add exp2f16 C23 math function #101217

Merged
merged 1 commit into from
Aug 6, 2024

Conversation

overmighty
Copy link
Member

Part of #95250.

@overmighty overmighty requested a review from lntue July 30, 2024 18:32
@llvmbot llvmbot added the libc label Jul 30, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 30, 2024

@llvm/pr-subscribers-libc

Author: OverMighty (overmighty)

Changes

Part of #95250.


Full diff: https://github.com/llvm/llvm-project/pull/101217.diff

13 Files Affected:

  • (modified) libc/config/linux/x86_64/entrypoints.txt (+1)
  • (modified) libc/docs/math/index.rst (+1-1)
  • (modified) libc/spec/stdc.td (+1)
  • (modified) libc/src/math/CMakeLists.txt (+1)
  • (added) libc/src/math/exp2f16.h (+21)
  • (modified) libc/src/math/generic/CMakeLists.txt (+22)
  • (added) libc/src/math/generic/exp2f16.cpp (+134)
  • (modified) libc/test/src/math/CMakeLists.txt (+21-10)
  • (added) libc/test/src/math/exp2f16_test.cpp (+40)
  • (modified) libc/test/src/math/performance_testing/CMakeLists.txt (+11)
  • (added) libc/test/src/math/performance_testing/exp2f16_perf.cpp (+22)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+21-9)
  • (added) libc/test/src/math/smoke/exp2f16_test.cpp (+65)
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0eb1690172a8e..f022d271235eb 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -564,6 +564,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.canonicalizef16
     libc.src.math.ceilf16
     libc.src.math.copysignf16
+    libc.src.math.exp2f16
     libc.src.math.expf16
     libc.src.math.f16add
     libc.src.math.f16addf
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 0448f8f36d2c2..c587ddc2372a9 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -290,7 +290,7 @@ Higher Math Functions
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | exp10m1   |                  |                 |                        |                      |                        | 7.12.6.3               | F.10.3.3                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| exp2      | |check|          | |check|         |                        |                      |                        | 7.12.6.4               | F.10.3.4                   |
+| exp2      | |check|          | |check|         |                        | |check|              |                        | 7.12.6.4               | F.10.3.4                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | exp2m1    | |check|          |                 |                        |                      |                        | 7.12.6.5               | F.10.3.5                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 788b9581cb2ab..a3fc9db64e046 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -577,6 +577,7 @@ def StdC : StandardSpec<"stdc"> {
 
           FunctionSpec<"exp2", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
           FunctionSpec<"exp2f", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
+          GuardedFunctionSpec<"exp2f16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
 
           FunctionSpec<"exp2m1f", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index eb33532826ab8..7d80e48c7c6b6 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -101,6 +101,7 @@ add_math_entrypoint_object(expf16)
 
 add_math_entrypoint_object(exp2)
 add_math_entrypoint_object(exp2f)
+add_math_entrypoint_object(exp2f16)
 
 add_math_entrypoint_object(exp2m1f)
 
diff --git a/libc/src/math/exp2f16.h b/libc/src/math/exp2f16.h
new file mode 100644
index 0000000000000..71361b997ae8e
--- /dev/null
+++ b/libc/src/math/exp2f16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for exp2f16 -----------------------*- 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_EXP2F16_H
+#define LLVM_LIBC_SRC_MATH_EXP2F16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float16 exp2f16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_EXP2F16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index f118742bddd68..f0e5c12760b08 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1305,6 +1305,28 @@ add_entrypoint_object(
     -O3
 )
 
+add_entrypoint_object(
+  exp2f16
+  SRCS
+    exp2f16.cpp
+  HDRS
+    ../exp2f16.h
+  DEPENDS
+    libc.hdr.errno_macros
+    libc.hdr.fenv_macros
+    libc.src.__support.CPP.array
+    libc.src.__support.FPUtil.except_value_utils
+    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.multiply_add
+    libc.src.__support.FPUtil.nearest_integer
+    libc.src.__support.FPUtil.polyeval
+    libc.src.__support.FPUtil.rounding_mode
+    libc.src.__support.macros.optimization
+  COMPILE_OPTIONS
+    -O3
+)
+
 add_entrypoint_object(
   exp2m1f
   SRCS
diff --git a/libc/src/math/generic/exp2f16.cpp b/libc/src/math/generic/exp2f16.cpp
new file mode 100644
index 0000000000000..3f18ab9166a85
--- /dev/null
+++ b/libc/src/math/generic/exp2f16.cpp
@@ -0,0 +1,134 @@
+//===-- Half-precision 2^x 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/exp2f16.h"
+#include "hdr/errno_macros.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/FPUtil/nearest_integer.h"
+#include "src/__support/FPUtil/rounding_mode.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{
+    // (input, RZ output, RU offset, RD offset, RN offset)
+    // x = 0x1.714p-11, exp2f16(x) = 0x1p+0 (RZ)
+    {0x11c5U, 0x3c00U, 1U, 0U, 1U},
+    // x = -0x1.558p-4, exp2f16(x) = 0x1.e34p-1 (RZ)
+    {0xad56U, 0x3b8dU, 1U, 0U, 0U},
+    // x = -0x1.d5cp-4, exp2f16(x) = 0x1.d8cp-1 (RZ)
+    {0xaf57U, 0x3b63U, 1U, 0U, 0U},
+}};
+
+// Generated by Sollya with the following commands:
+//   > display = hexadecimal;
+//   > for i from 0 to 7 do printsingle(round(2^(i * 2^-3), SG, RN));
+static constexpr cpp::array<uint32_t, 8> EXP2_MID_BITS = {
+    0x3f80'0000U, 0x3f8b'95c2U, 0x3f98'37f0U, 0x3fa5'fed7U,
+    0x3fb5'04f3U, 0x3fc5'672aU, 0x3fd7'44fdU, 0x3fea'c0c7U,
+};
+
+LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
+  using FPBits = fputil::FPBits<float16>;
+  FPBits x_bits(x);
+
+  uint16_t x_u = x_bits.uintval();
+  uint16_t x_abs = x_u & 0x7fffU;
+
+  // When |x| >= 16, or x is NaN.
+  if (LIBC_UNLIKELY(x_abs >= 0x4c00U)) {
+    // exp2(NaN) = NaN
+    if (x_bits.is_nan()) {
+      if (x_bits.is_signaling_nan()) {
+        fputil::raise_except_if_required(FE_INVALID);
+        return FPBits::quiet_nan().get_val();
+      }
+
+      return x;
+    }
+
+    // When x >= 16.
+    if (x_bits.is_pos()) {
+      // exp2(+inf) = +inf
+      if (x_bits.is_inf())
+        return FPBits::inf().get_val();
+
+      switch (fputil::quick_get_round()) {
+      case FE_TONEAREST:
+      case FE_UPWARD:
+        fputil::set_errno_if_required(ERANGE);
+        fputil::raise_except_if_required(FE_OVERFLOW);
+        return FPBits::inf().get_val();
+      default:
+        return FPBits::max_normal().get_val();
+      }
+    }
+
+    // When x <= -25.
+    if (x_u >= 0xce40U) {
+      // exp2(-inf) = +0
+      if (x_bits.is_inf())
+        return FPBits::zero().get_val();
+
+      fputil::set_errno_if_required(ERANGE);
+      fputil::raise_except_if_required(FE_UNDERFLOW | FE_INEXACT);
+
+      if (fputil::fenv_is_round_up())
+        return FPBits::min_subnormal().get_val();
+      return FPBits::zero().get_val();
+    }
+  }
+
+  if (auto r = EXP2F16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
+    return r.value();
+
+  // For -25 < x < 16, to compute 2^x, we perform the following range reduction:
+  // find hi, mid, lo, such that:
+  //   x = hi + mid + lo, in which
+  //     hi is an integer,
+  //     mid * 2^3 is an integer,
+  //     -2^(-4) <= lo < 2^(-4).
+  // In particular,
+  //   hi + mid = round(x * 2^3) * 2^(-3).
+  // Then,
+  //   2^x = 2^(hi + mid + lo) = 2^hi * 2^mid * 2^lo.
+  // We store 2^mid in the lookup table EXP2_MID_BITS, and compute 2^hi * 2^mid
+  // by adding hi to the exponent field of 2^mid.  2^lo is computed using a
+  // degree-3 minimax polynomial generated by Sollya.
+
+  float xf = x;
+  float kf = fputil::nearest_integer(xf * 0x1.0p+3f);
+  int x_hi_mid = static_cast<int>(kf);
+  int x_hi = x_hi_mid >> 3;
+  int x_mid = x_hi_mid & 0x7;
+  // lo = x - (hi + mid) = round(x * 2^3) * (-2^(-3)) + x
+  float lo = fputil::multiply_add(kf, -0x1.0p-3f, xf);
+
+  uint32_t exp2_hi_mid_bits =
+      EXP2_MID_BITS[x_mid] +
+      static_cast<uint32_t>(x_hi << fputil::FPBits<float>::FRACTION_LEN);
+  float exp2_hi_mid = fputil::FPBits<float>(exp2_hi_mid_bits).get_val();
+  // Degree-3 minimax polynomial generated by Sollya with the following
+  // commands:
+  //   > display = hexadecimal;
+  //   > P = fpminimax((2^x - 1)/x, 2, [|SG...|], [-2^-4, 2^-4]);
+  //   > 1 + x * P;
+  float exp2_lo = fputil::polyeval(lo, 0x1p+0f, 0x1.62e43p-1f, 0x1.ec0aa6p-3f,
+                                   0x1.c6b4a6p-5f);
+  return static_cast<float16>(exp2_hi_mid * exp2_lo);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 56b27b0952b58..ebaabcb0dffe3 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -925,6 +925,19 @@ add_fp_unittest(
     libc.src.math.expf16
 )
 
+add_fp_unittest(
+  exp2_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    exp2_test.cpp
+  DEPENDS
+    libc.src.errno.errno
+    libc.src.math.exp2
+    libc.src.__support.FPUtil.fp_bits
+)
+
 add_fp_unittest(
   exp2f_test
   NEED_MPFR
@@ -939,16 +952,14 @@ add_fp_unittest(
 )
 
 add_fp_unittest(
- exp2_test
- NEED_MPFR
- SUITE
-   libc-math-unittests
- SRCS
-   exp2_test.cpp
- DEPENDS
-   libc.src.errno.errno
-   libc.src.math.exp2
-   libc.src.__support.FPUtil.fp_bits
+  exp2f16_test
+  NEED_MPFR
+  SUITE
+    libc-math-unittests
+  SRCS
+    exp2f16_test.cpp
+  DEPENDS
+    libc.src.math.exp2f16
 )
 
 add_fp_unittest(
diff --git a/libc/test/src/math/exp2f16_test.cpp b/libc/test/src/math/exp2f16_test.cpp
new file mode 100644
index 0000000000000..503d8c2d89d94
--- /dev/null
+++ b/libc/test/src/math/exp2f16_test.cpp
@@ -0,0 +1,40 @@
+//===-- Exhaustive test for exp2f16 ---------------------------------------===//
+//
+// 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/exp2f16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+using LlvmLibcExp2f16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+// Range: [0, Inf];
+static constexpr uint16_t POS_START = 0x0000U;
+static constexpr uint16_t POS_STOP = 0x7c00U;
+
+// Range: [-Inf, 0];
+static constexpr uint16_t NEG_START = 0x8000U;
+static constexpr uint16_t NEG_STOP = 0xfc00U;
+
+TEST_F(LlvmLibcExp2f16Test, PositiveRange) {
+  for (uint16_t v = POS_START; v <= POS_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
+                                   LIBC_NAMESPACE::exp2f16(x), 0.5);
+  }
+}
+
+TEST_F(LlvmLibcExp2f16Test, NegativeRange) {
+  for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) {
+    float16 x = FPBits(v).get_val();
+    EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
+                                   LIBC_NAMESPACE::exp2f16(x), 0.5);
+  }
+}
diff --git a/libc/test/src/math/performance_testing/CMakeLists.txt b/libc/test/src/math/performance_testing/CMakeLists.txt
index b43d21a242f35..09211537d93f4 100644
--- a/libc/test/src/math/performance_testing/CMakeLists.txt
+++ b/libc/test/src/math/performance_testing/CMakeLists.txt
@@ -164,6 +164,17 @@ add_perf_binary(
     -fno-builtin
 )
 
+add_perf_binary(
+  exp2f16_perf
+  SRCS
+    exp2f16_perf.cpp
+  DEPENDS
+    .single_input_single_output_diff
+    libc.src.math.exp2f16
+  COMPILE_OPTIONS
+    -fno-builtin
+)
+
 add_perf_binary(
   expf_perf
   SRCS
diff --git a/libc/test/src/math/performance_testing/exp2f16_perf.cpp b/libc/test/src/math/performance_testing/exp2f16_perf.cpp
new file mode 100644
index 0000000000000..aa58de2476f1a
--- /dev/null
+++ b/libc/test/src/math/performance_testing/exp2f16_perf.cpp
@@ -0,0 +1,22 @@
+//===-- Performance test for exp2f16 --------------------------------------===//
+//
+// 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 "SingleInputSingleOutputPerf.h"
+
+#include "src/math/exp2f16.h"
+
+// LLVM libc might be the only libc implementation with support for float16 math
+// functions currently. We can't compare our float16 functions against the
+// system libc, so we compare them against this placeholder function.
+static float16 placeholderf16(float16 x) { return x; }
+
+int main() {
+  SINGLE_INPUT_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::exp2f16,
+                                     ::placeholderf16, 20'000,
+                                     "exp2f16_perf.log")
+}
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index a59af91d76736..b49f6e0fa5663 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -977,6 +977,18 @@ add_fp_unittest(
     libc.src.math.expf16
 )
 
+add_fp_unittest(
+  exp2_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    exp2_test.cpp
+  DEPENDS
+    libc.src.errno.errno
+    libc.src.math.exp2
+    libc.src.__support.FPUtil.fp_bits
+)
+
 add_fp_unittest(
   exp2f_test
   SUITE
@@ -990,15 +1002,15 @@ add_fp_unittest(
 )
 
 add_fp_unittest(
- exp2_test
- SUITE
-   libc-math-smoke-tests
- SRCS
-   exp2_test.cpp
- DEPENDS
-   libc.src.errno.errno
-   libc.src.math.exp2
-   libc.src.__support.FPUtil.fp_bits
+  exp2f16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    exp2f16_test.cpp
+  DEPENDS
+    libc.hdr.fenv_macros
+    libc.src.errno.errno
+    libc.src.math.exp2f16
 )
 
 add_fp_unittest(
diff --git a/libc/test/src/math/smoke/exp2f16_test.cpp b/libc/test/src/math/smoke/exp2f16_test.cpp
new file mode 100644
index 0000000000000..cd87e6134557a
--- /dev/null
+++ b/libc/test/src/math/smoke/exp2f16_test.cpp
@@ -0,0 +1,65 @@
+//===-- Unittests for exp2f16 ---------------------------------------------===//
+//
+// 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 "hdr/fenv_macros.h"
+#include "src/errno/libc_errno.h"
+#include "src/math/exp2f16.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcExp2f16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
+
+TEST_F(LlvmLibcExp2f16Test, SpecialNumbers) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::exp2f16(aNaN));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::exp2f16(sNaN), FE_INVALID);
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::exp2f16(inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(static_cast<float16>(zero),
+                            LIBC_NAMESPACE::exp2f16(neg_inf));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(static_cast<float16>(1.0f),
+                            LIBC_NAMESPACE::exp2f16(zero));
+  EXPECT_MATH_ERRNO(0);
+
+  EXPECT_FP_EQ_ALL_ROUNDING(static_cast<float16>(1.0f),
+                            LIBC_NAMESPACE::exp2f16(neg_zero));
+  EXPECT_MATH_ERRNO(0);
+}
+
+TEST_F(LlvmLibcExp2f16Test, Overflow) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::exp2f16(max_normal),
+                              FE_OVERFLOW);
+  EXPECT_MATH_ERRNO(ERANGE);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(
+      inf, LIBC_NAMESPACE::exp2f16(static_cast<float16>(16.0)), FE_OVERFLOW);
+  EXPECT_MATH_ERRNO(ERANGE);
+}
+
+TEST_F(LlvmLibcExp2f16Test, Underflow) {
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(zero, LIBC_NAMESPACE::exp2f16(neg_max_normal),
+                              FE_UNDERFLOW | FE_INEXACT);
+  EXPECT_MATH_ERRNO(ERANGE);
+
+  EXPECT_FP_EQ_WITH_EXCEPTION(
+      zero, LIBC_NAMESPACE::exp2f16(static_cast<float16>(-25.0)),
+      FE_UNDERFLOW | FE_INEXACT);
+  EXPECT_MATH_ERRNO(ERANGE);
+}

@overmighty
Copy link
Member Author

I didn't enable exp2f16 for AArch64 yet due to the issue with FE_INVALID we just had there with expf16.

Comment on lines +174 to +175
COMPILE_OPTIONS
-fno-builtin
Copy link
Member Author

Choose a reason for hiding this comment

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

This shouldn't change anything yet. I added it now so that we don't forget it when the day comes that we remove the placeholderf16 function and benchmark against the system libc's function.

Copy link
Contributor

Choose a reason for hiding this comment

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

What's this testing exactly? And if we want to disable a single builtin it's better to just do -fno-builtin-exp2f16 if that's what it's called.

Copy link
Member Author

Choose a reason for hiding this comment

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

All the math performance tests, except one, benchmark LLVM libc functions against respective system libc functions, so all of them except that one have -fno-builtin. I don't know why fine-grained -fno-builtin-<function> flags weren't used.

In this case, since the system libc shouldn't have float16 math functions yet, I benchmark against a placeholder function for now. It would probably be better if at some point we just rewrote our performance testing code to use Google Benchmark, and also allow us to benchmark a single function instead of comparing two, while we're at it.

@overmighty overmighty merged commit 936515c into llvm:main Aug 6, 2024
9 checks passed
@overmighty
Copy link
Member Author

Looks like I forgot to send the performance test results for this one.

On i7-13700H:

  • With Clang 18, without -march=native:

     Performance tests with inputs in denormal range:
    -- My function --
         Total time      : 1608372749 ns 
         Average runtime : 78.6106 ns/op 
         Ops per second  : 12720931 op/s 
    -- Other function --
         Total time      : 21779603 ns 
         Average runtime : 1.0645 ns/op 
         Ops per second  : 939411062 op/s 
    -- Average runtime ratio --
         Mine / Other's  : 73.8477 
    
     Performance tests with inputs in normal range:
    -- My function --
         Total time      : 23050495413 ns 
         Average runtime : 37.5183 ns/op 
         Ops per second  : 26653657 op/s 
    -- Other function --
         Total time      : 648715741 ns 
         Average runtime : 1.05589 ns/op 
         Ops per second  : 947071207 op/s 
    -- Average runtime ratio --
         Mine / Other's  : 35.5325 
    
  • With Clang 18, with -march=native:

     Performance tests with inputs in denormal range:
    -- My function --
         Total time      : 326212337 ns 
         Average runtime : 15.9439 ns/op 
         Ops per second  : 62719884 op/s 
    -- Other function --
         Total time      : 27113650 ns 
         Average runtime : 1.3252 ns/op 
         Ops per second  : 754601464 op/s 
    -- Average runtime ratio --
         Mine / Other's  : 12.0313 
    
     Performance tests with inputs in normal range:
    -- My function --
         Total time      : 22112635381 ns 
         Average runtime : 35.9918 ns/op 
         Ops per second  : 27784114 op/s 
    -- Other function --
         Total time      : 810631359 ns 
         Average runtime : 1.31943 ns/op 
         Ops per second  : 757903075 op/s 
    -- Average runtime ratio --
         Mine / Other's  : 27.2783 
    

banach-space pushed a commit to banach-space/llvm-project that referenced this pull request Aug 7, 2024
kstoimenov pushed a commit to kstoimenov/llvm-project that referenced this pull request Aug 15, 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.

4 participants