[libc-commits] [libc] [libc] Float80 Emulation in LLVM libc (PR #214447)

via libc-commits libc-commits at lists.llvm.org
Thu Aug 20 08:52:20 PDT 2026


================
@@ -0,0 +1,118 @@
+//===-- Unittests for Float80 emulated type ------------------------------===//
+//
+// 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/limits_macros.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/float80.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::Sign;
+using LIBC_NAMESPACE::fputil::Float80;
+using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>;
+
+TEST(LlvmLibcFloat80Test, temp) { Float80 a(1.0f); }
+
+TEST(LlvmLibcFloat80Test, IntegerConversion) {
+  // Float80 to Integer conversion test
+  ASSERT_EQ(static_cast<int>(Float80(0.0f)), 0);
+  ASSERT_EQ(static_cast<int>(Float80(1.0f)), 1);
+  ASSERT_EQ(static_cast<long long>(Float80(1000000000.0)),
+            static_cast<long long>(1000000000));
+  ASSERT_EQ(static_cast<unsigned>(Float80(7.0f)), 7U);
+  ASSERT_EQ(static_cast<int>(Float80(1.9f)), 1);
+
+  // Border values
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(Float80(INT_MAX)), INT_MAX);
+  ASSERT_EQ(static_cast<long long>(Float80(LLONG_MAX)), LLONG_MAX);
+  ASSERT_EQ(static_cast<unsigned>(Float80(UINT_MAX)), UINT_MAX);
+  EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_INVALID), 0);
+
+  // FP exceptions
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(FPBits::quiet_nan().get_val()), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(FPBits::inf().get_val()), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  // Extreme values
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(Float80(1e300)), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(FPBits::inf(Sign::POS).get_val()), INT_MAX);
+  EXPECT_FP_EXCEPTION(FE_INVALID);
+
+  // Small values
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
+  ASSERT_EQ(static_cast<int>(Float80(1e-300)), 0);
+  ASSERT_EQ(static_cast<int>(Float80(0.5)), 0);
+  EXPECT_EQ(LIBC_NAMESPACE::fputil::test_except(FE_INVALID), 0);
+}
+
+#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+TEST(LlvmLibcFloat80Test, randomTest) {
+  using FPBitsL = LIBC_NAMESPACE::fputil::FPBits<long double>;
+
+  const FPBitsL::StorageType EDGE_CASES[] = {
+      FPBitsL::zero(Sign::POS).uintval(),
+      FPBitsL::zero(Sign::NEG).uintval(),
+      FPBitsL::inf(Sign::POS).uintval(),
+      FPBitsL::inf(Sign::NEG).uintval(),
+      FPBitsL::quiet_nan().uintval(),
+      FPBitsL::signaling_nan().uintval(),
+      FPBitsL::min_subnormal(Sign::POS).uintval(),
+      FPBitsL::min_subnormal(Sign::NEG).uintval(),
+      FPBitsL::max_subnormal(Sign::POS).uintval(),
+      FPBitsL::max_subnormal(Sign::NEG).uintval(),
+      FPBitsL::min_normal(Sign::POS).uintval(),
+      FPBitsL::min_normal(Sign::NEG).uintval(),
+      FPBitsL::max_normal(Sign::POS).uintval(),
+      FPBitsL::max_normal(Sign::NEG).uintval(),
+      FPBitsL::one(Sign::POS).uintval(),
+      FPBitsL::one(Sign::NEG).uintval(),
+  };
+
+  for (FPBitsL::StorageType bits : EDGE_CASES) {
+    if (FPBitsL(bits).is_signaling_nan())
+      continue;
----------------
overmighty wrote:

Should just remove `FPBitsL::signaling_nan().uintval(),` from `EDGE_CASES`.

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


More information about the libc-commits mailing list