187c01607SMichael Jones //===-- Unittests for str_to_float ----------------------------------------===//
287c01607SMichael Jones //
387c01607SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
487c01607SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
587c01607SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
687c01607SMichael Jones //
787c01607SMichael Jones //===----------------------------------------------------------------------===//
887c01607SMichael Jones 
9*300f8da8SSiva Chandra Reddy #include "src/__support/CPP/UInt128.h"
1087c01607SMichael Jones #include "src/__support/FPUtil/FPBits.h"
1187c01607SMichael Jones #include "src/__support/str_to_float.h"
1287c01607SMichael Jones 
1387c01607SMichael Jones #include "utils/UnitTest/Test.h"
1487c01607SMichael Jones 
1587c01607SMichael Jones class LlvmLibcStrToFloatTest : public __llvm_libc::testing::Test {
1687c01607SMichael Jones public:
1787c01607SMichael Jones   template <class T>
clinger_fast_path_test(const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,const int32_t inputExp10,const typename __llvm_libc::fputil::FPBits<T>::UIntType expectedOutputMantissa,const uint32_t expectedOutputExp2)1825226f3eSMichael Jones   void clinger_fast_path_test(
1962c187cbSMichael Jones       const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,
2062c187cbSMichael Jones       const int32_t inputExp10,
2162c187cbSMichael Jones       const typename __llvm_libc::fputil::FPBits<T>::UIntType
2262c187cbSMichael Jones           expectedOutputMantissa,
2362c187cbSMichael Jones       const uint32_t expectedOutputExp2) {
2425226f3eSMichael Jones     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
2525226f3eSMichael Jones         0;
2625226f3eSMichael Jones     uint32_t actual_output_exp2 = 0;
2762c187cbSMichael Jones 
281c92911eSMichael Jones     ASSERT_TRUE(__llvm_libc::internal::clinger_fast_path<T>(
2925226f3eSMichael Jones         inputMantissa, inputExp10, &actual_output_mantissa,
3025226f3eSMichael Jones         &actual_output_exp2));
3125226f3eSMichael Jones     EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa);
3225226f3eSMichael Jones     EXPECT_EQ(actual_output_exp2, expectedOutputExp2);
3362c187cbSMichael Jones   }
3462c187cbSMichael Jones 
3562c187cbSMichael Jones   template <class T>
clinger_fast_path_fails_test(const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,const int32_t inputExp10)3625226f3eSMichael Jones   void clinger_fast_path_fails_test(
3762c187cbSMichael Jones       const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,
3862c187cbSMichael Jones       const int32_t inputExp10) {
3925226f3eSMichael Jones     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
4025226f3eSMichael Jones         0;
4125226f3eSMichael Jones     uint32_t actual_output_exp2 = 0;
4262c187cbSMichael Jones 
431c92911eSMichael Jones     ASSERT_FALSE(__llvm_libc::internal::clinger_fast_path<T>(
4425226f3eSMichael Jones         inputMantissa, inputExp10, &actual_output_mantissa,
4525226f3eSMichael Jones         &actual_output_exp2));
4662c187cbSMichael Jones   }
4762c187cbSMichael Jones 
4862c187cbSMichael Jones   template <class T>
eisel_lemire_test(const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,const int32_t inputExp10,const typename __llvm_libc::fputil::FPBits<T>::UIntType expectedOutputMantissa,const uint32_t expectedOutputExp2)4925226f3eSMichael Jones   void eisel_lemire_test(
5087c01607SMichael Jones       const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,
5187c01607SMichael Jones       const int32_t inputExp10,
5287c01607SMichael Jones       const typename __llvm_libc::fputil::FPBits<T>::UIntType
5387c01607SMichael Jones           expectedOutputMantissa,
5487c01607SMichael Jones       const uint32_t expectedOutputExp2) {
5525226f3eSMichael Jones     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
5625226f3eSMichael Jones         0;
5725226f3eSMichael Jones     uint32_t actual_output_exp2 = 0;
5887c01607SMichael Jones 
591c92911eSMichael Jones     ASSERT_TRUE(__llvm_libc::internal::eisel_lemire<T>(
6025226f3eSMichael Jones         inputMantissa, inputExp10, &actual_output_mantissa,
6125226f3eSMichael Jones         &actual_output_exp2));
6225226f3eSMichael Jones     EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa);
6325226f3eSMichael Jones     EXPECT_EQ(actual_output_exp2, expectedOutputExp2);
6487c01607SMichael Jones   }
6587c01607SMichael Jones 
6687c01607SMichael Jones   template <class T>
simple_decimal_conversion_test(const char * __restrict numStart,const typename __llvm_libc::fputil::FPBits<T>::UIntType expectedOutputMantissa,const uint32_t expectedOutputExp2,const int expectedErrno=0)6725226f3eSMichael Jones   void simple_decimal_conversion_test(
6887c01607SMichael Jones       const char *__restrict numStart,
6987c01607SMichael Jones       const typename __llvm_libc::fputil::FPBits<T>::UIntType
7087c01607SMichael Jones           expectedOutputMantissa,
7187c01607SMichael Jones       const uint32_t expectedOutputExp2, const int expectedErrno = 0) {
7225226f3eSMichael Jones     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
7325226f3eSMichael Jones         0;
7425226f3eSMichael Jones     uint32_t actual_output_exp2 = 0;
7587c01607SMichael Jones     errno = 0;
7687c01607SMichael Jones 
771c92911eSMichael Jones     __llvm_libc::internal::simple_decimal_conversion<T>(
7825226f3eSMichael Jones         numStart, &actual_output_mantissa, &actual_output_exp2);
7925226f3eSMichael Jones     EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa);
8025226f3eSMichael Jones     EXPECT_EQ(actual_output_exp2, expectedOutputExp2);
8187c01607SMichael Jones     EXPECT_EQ(errno, expectedErrno);
8287c01607SMichael Jones   }
8387c01607SMichael Jones };
8487c01607SMichael Jones 
TEST(LlvmLibcStrToFloatTest,LeadingZeroes)8587c01607SMichael Jones TEST(LlvmLibcStrToFloatTest, LeadingZeroes) {
8625226f3eSMichael Jones   uint64_t test_num64 = 1;
8725226f3eSMichael Jones   uint32_t num_of_zeroes = 63;
881c92911eSMichael Jones   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(0), 64u);
8925226f3eSMichael Jones   for (; num_of_zeroes < 64; test_num64 <<= 1, num_of_zeroes--) {
9025226f3eSMichael Jones     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(test_num64),
9125226f3eSMichael Jones               num_of_zeroes);
9287c01607SMichael Jones   }
9387c01607SMichael Jones 
9425226f3eSMichael Jones   test_num64 = 3;
9525226f3eSMichael Jones   num_of_zeroes = 62;
9625226f3eSMichael Jones   for (; num_of_zeroes > 63; test_num64 <<= 1, num_of_zeroes--) {
9725226f3eSMichael Jones     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(test_num64),
9825226f3eSMichael Jones               num_of_zeroes);
9987c01607SMichael Jones   }
10087c01607SMichael Jones 
1011c92911eSMichael Jones   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(0xffffffffffffffff),
10287c01607SMichael Jones             0u);
10387c01607SMichael Jones 
10425226f3eSMichael Jones   test_num64 = 1;
10525226f3eSMichael Jones   num_of_zeroes = 63;
10625226f3eSMichael Jones   for (; num_of_zeroes > 63;
10725226f3eSMichael Jones        test_num64 = (test_num64 << 1) + 1, num_of_zeroes--) {
10825226f3eSMichael Jones     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(test_num64),
10925226f3eSMichael Jones               num_of_zeroes);
11087c01607SMichael Jones   }
11187c01607SMichael Jones 
11225226f3eSMichael Jones   uint64_t test_num32 = 1;
11325226f3eSMichael Jones   num_of_zeroes = 31;
1141c92911eSMichael Jones   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint32_t>(0), 32u);
11525226f3eSMichael Jones   for (; num_of_zeroes < 32; test_num32 <<= 1, num_of_zeroes--) {
11625226f3eSMichael Jones     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint32_t>(test_num32),
11725226f3eSMichael Jones               num_of_zeroes);
11887c01607SMichael Jones   }
11987c01607SMichael Jones 
1201c92911eSMichael Jones   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint32_t>(0xffffffff), 0u);
12187c01607SMichael Jones }
12287c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat64Simple)12362c187cbSMichael Jones TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64Simple) {
12425226f3eSMichael Jones   clinger_fast_path_test<double>(123, 0, 0xEC00000000000, 1029);
12525226f3eSMichael Jones   clinger_fast_path_test<double>(1234567890123456, 1, 0x5ee2a2eb5a5c0, 1076);
12625226f3eSMichael Jones   clinger_fast_path_test<double>(1234567890, -10, 0xf9add3739635f, 1019);
12762c187cbSMichael Jones }
12862c187cbSMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat64ExtendedExp)12962c187cbSMichael Jones TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64ExtendedExp) {
13025226f3eSMichael Jones   clinger_fast_path_test<double>(1, 30, 0x93e5939a08cea, 1122);
13125226f3eSMichael Jones   clinger_fast_path_test<double>(1, 37, 0xe17b84357691b, 1145);
13225226f3eSMichael Jones   clinger_fast_path_fails_test<double>(10, 37);
13325226f3eSMichael Jones   clinger_fast_path_fails_test<double>(1, 100);
13462c187cbSMichael Jones }
13562c187cbSMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat64NegativeExp)13662c187cbSMichael Jones TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64NegativeExp) {
13725226f3eSMichael Jones   clinger_fast_path_test<double>(1, -10, 0xb7cdfd9d7bdbb, 989);
13825226f3eSMichael Jones   clinger_fast_path_test<double>(1, -20, 0x79ca10c924223, 956);
13925226f3eSMichael Jones   clinger_fast_path_fails_test<double>(1, -25);
14062c187cbSMichael Jones }
14162c187cbSMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat32Simple)14262c187cbSMichael Jones TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32Simple) {
14325226f3eSMichael Jones   clinger_fast_path_test<float>(123, 0, 0x760000, 133);
14425226f3eSMichael Jones   clinger_fast_path_test<float>(1234567, 1, 0x3c6146, 150);
14525226f3eSMichael Jones   clinger_fast_path_test<float>(12345, -5, 0x7cd35b, 123);
14662c187cbSMichael Jones }
14762c187cbSMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat32ExtendedExp)14862c187cbSMichael Jones TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32ExtendedExp) {
14925226f3eSMichael Jones   clinger_fast_path_test<float>(1, 15, 0x635fa9, 176);
15025226f3eSMichael Jones   clinger_fast_path_test<float>(1, 17, 0x31a2bc, 183);
15125226f3eSMichael Jones   clinger_fast_path_fails_test<float>(10, 17);
15225226f3eSMichael Jones   clinger_fast_path_fails_test<float>(1, 50);
15362c187cbSMichael Jones }
15462c187cbSMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat32NegativeExp)15562c187cbSMichael Jones TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32NegativeExp) {
15625226f3eSMichael Jones   clinger_fast_path_test<float>(1, -5, 0x27c5ac, 110);
15725226f3eSMichael Jones   clinger_fast_path_test<float>(1, -10, 0x5be6ff, 93);
15825226f3eSMichael Jones   clinger_fast_path_fails_test<float>(1, -15);
15962c187cbSMichael Jones }
16062c187cbSMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat64Simple)16187c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64Simple) {
16225226f3eSMichael Jones   eisel_lemire_test<double>(12345678901234567890u, 1, 0x1AC53A7E04BCDA, 1089);
16325226f3eSMichael Jones   eisel_lemire_test<double>(123, 0, 0x1EC00000000000, 1029);
16425226f3eSMichael Jones   eisel_lemire_test<double>(12345678901234568192u, 0, 0x156A95319D63E2, 1086);
16587c01607SMichael Jones }
16687c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat64SpecificFailures)16787c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64SpecificFailures) {
16887c01607SMichael Jones   // These test cases have caused failures in the past.
16925226f3eSMichael Jones   eisel_lemire_test<double>(358416272, -33, 0x1BBB2A68C9D0B9, 941);
17025226f3eSMichael Jones   eisel_lemire_test<double>(2166568064000000238u, -9, 0x10246690000000, 1054);
17125226f3eSMichael Jones   eisel_lemire_test<double>(2794967654709307187u, 1, 0x183e132bc608c8, 1087);
17225226f3eSMichael Jones   eisel_lemire_test<double>(2794967654709307188u, 1, 0x183e132bc608c9, 1087);
17387c01607SMichael Jones }
17487c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFallbackStates)17587c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFallbackStates) {
17687c01607SMichael Jones   // Check the fallback states for the algorithm:
17725226f3eSMichael Jones   uint32_t float_output_mantissa = 0;
17825226f3eSMichael Jones   uint64_t double_output_mantissa = 0;
17925226f3eSMichael Jones   uint32_t output_exp2 = 0;
18087c01607SMichael Jones 
18187c01607SMichael Jones   // This number can't be evaluated by Eisel-Lemire since it's exactly 1024 away
18287c01607SMichael Jones   // from both of its closest floating point approximations
18387c01607SMichael Jones   // (12345678901234548736 and 12345678901234550784)
1841c92911eSMichael Jones   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<double>(
18525226f3eSMichael Jones       12345678901234549760u, 0, &double_output_mantissa, &output_exp2));
18687c01607SMichael Jones 
1871c92911eSMichael Jones   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<float>(
18825226f3eSMichael Jones       20040229, 0, &float_output_mantissa, &output_exp2));
18987c01607SMichael Jones }
19087c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicWholeNumbers)19187c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicWholeNumbers) {
19225226f3eSMichael Jones   simple_decimal_conversion_test<double>("123456789012345678900",
19325226f3eSMichael Jones                                          0x1AC53A7E04BCDA, 1089);
19425226f3eSMichael Jones   simple_decimal_conversion_test<double>("123", 0x1EC00000000000, 1029);
19525226f3eSMichael Jones   simple_decimal_conversion_test<double>("12345678901234549760",
19625226f3eSMichael Jones                                          0x156A95319D63D8, 1086);
19787c01607SMichael Jones }
19887c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicDecimals)19987c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicDecimals) {
20025226f3eSMichael Jones   simple_decimal_conversion_test<double>("1.2345", 0x13c083126e978d, 1023);
20125226f3eSMichael Jones   simple_decimal_conversion_test<double>(".2345", 0x1e04189374bc6a, 1020);
20225226f3eSMichael Jones   simple_decimal_conversion_test<double>(".299792458", 0x132fccb4aca314, 1021);
20387c01607SMichael Jones }
20487c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicExponents)20587c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicExponents) {
20625226f3eSMichael Jones   simple_decimal_conversion_test<double>("1e10", 0x12a05f20000000, 1056);
20725226f3eSMichael Jones   simple_decimal_conversion_test<double>("1e-10", 0x1b7cdfd9d7bdbb, 989);
20825226f3eSMichael Jones   simple_decimal_conversion_test<double>("1e300", 0x17e43c8800759c, 2019);
20925226f3eSMichael Jones   simple_decimal_conversion_test<double>("1e-300", 0x156e1fc2f8f359, 26);
21087c01607SMichael Jones }
21187c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicSubnormals)21287c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicSubnormals) {
21325226f3eSMichael Jones   simple_decimal_conversion_test<double>("1e-320", 0x7e8, 0, ERANGE);
21425226f3eSMichael Jones   simple_decimal_conversion_test<double>("1e-308", 0x730d67819e8d2, 0, ERANGE);
21525226f3eSMichael Jones   simple_decimal_conversion_test<double>("2.9e-308", 0x14da6df5e4bcc8, 1);
21687c01607SMichael Jones }
21787c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64SubnormalRounding)21887c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64SubnormalRounding) {
21987c01607SMichael Jones 
22087c01607SMichael Jones   // Technically you can keep adding digits until you hit the truncation limit,
22187c01607SMichael Jones   // but this is the shortest string that results in the maximum subnormal that
22287c01607SMichael Jones   // I found.
22325226f3eSMichael Jones   simple_decimal_conversion_test<double>("2.225073858507201e-308",
22425226f3eSMichael Jones                                          0xfffffffffffff, 0, ERANGE);
22587c01607SMichael Jones 
22687c01607SMichael Jones   // Same here, if you were to extend the max subnormal out for another 800
22787c01607SMichael Jones   // digits, incrementing any one of those digits would create a normal number.
22825226f3eSMichael Jones   simple_decimal_conversion_test<double>("2.2250738585072012e-308",
22987c01607SMichael Jones                                          0x10000000000000, 1);
23087c01607SMichael Jones }
23187c01607SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion32SpecificFailures)23287c01607SMichael Jones TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion32SpecificFailures) {
23325226f3eSMichael Jones   simple_decimal_conversion_test<float>(
2344cdf9884SMichael Jones       "1.4012984643248170709237295832899161312802619418765e-45", 0x1, 0,
2354cdf9884SMichael Jones       ERANGE);
23664724218STue Ly   simple_decimal_conversion_test<float>(
23764724218STue Ly       "7."
23864724218STue Ly       "006492321624085354618647916449580656401309709382578858785341419448955413"
23964724218STue Ly       "42930300743319094181060791015625e-46",
24064724218STue Ly       0x0, 0, ERANGE);
24187c01607SMichael Jones }
24287c01607SMichael Jones 
TEST(LlvmLibcStrToFloatTest,SimpleDecimalConversionExtraTypes)24387c01607SMichael Jones TEST(LlvmLibcStrToFloatTest, SimpleDecimalConversionExtraTypes) {
24425226f3eSMichael Jones   uint32_t float_output_mantissa = 0;
24525226f3eSMichael Jones   uint32_t output_exp2 = 0;
24687c01607SMichael Jones 
24787c01607SMichael Jones   errno = 0;
2481c92911eSMichael Jones   __llvm_libc::internal::simple_decimal_conversion<float>(
24925226f3eSMichael Jones       "123456789012345678900", &float_output_mantissa, &output_exp2);
25025226f3eSMichael Jones   EXPECT_EQ(float_output_mantissa, uint32_t(0xd629d4));
25125226f3eSMichael Jones   EXPECT_EQ(output_exp2, uint32_t(193));
25287c01607SMichael Jones   EXPECT_EQ(errno, 0);
25387c01607SMichael Jones 
25425226f3eSMichael Jones   uint64_t double_output_mantissa = 0;
25525226f3eSMichael Jones   output_exp2 = 0;
25687c01607SMichael Jones 
25787c01607SMichael Jones   errno = 0;
2581c92911eSMichael Jones   __llvm_libc::internal::simple_decimal_conversion<double>(
25925226f3eSMichael Jones       "123456789012345678900", &double_output_mantissa, &output_exp2);
26025226f3eSMichael Jones   EXPECT_EQ(double_output_mantissa, uint64_t(0x1AC53A7E04BCDA));
26125226f3eSMichael Jones   EXPECT_EQ(output_exp2, uint32_t(1089));
26287c01607SMichael Jones   EXPECT_EQ(errno, 0);
26387c01607SMichael Jones }
2649b397371SMichael Jones 
2659b397371SMichael Jones #if defined(LONG_DOUBLE_IS_DOUBLE)
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat64AsLongDouble)2669b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64AsLongDouble) {
2679b397371SMichael Jones   eisel_lemire_test<long double>(123, 0, 0x1EC00000000000, 1029);
2689b397371SMichael Jones }
2699b397371SMichael Jones #elif defined(SPECIAL_X86_LONG_DOUBLE)
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80Simple)2709b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80Simple) {
2719b397371SMichael Jones   eisel_lemire_test<long double>(123, 0, 0xf600000000000000, 16389);
2729b397371SMichael Jones   eisel_lemire_test<long double>(12345678901234568192u, 0, 0xab54a98ceb1f0c00,
2739b397371SMichael Jones                                  16446);
2749b397371SMichael Jones }
2759b397371SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80LongerMantissa)2769b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80LongerMantissa) {
277*300f8da8SSiva Chandra Reddy   eisel_lemire_test<long double>((UInt128(0x1234567812345678) << 64) +
278*300f8da8SSiva Chandra Reddy                                      UInt128(0x1234567812345678),
2799b397371SMichael Jones                                  0, 0x91a2b3c091a2b3c1, 16507);
280*300f8da8SSiva Chandra Reddy   eisel_lemire_test<long double>((UInt128(0x1234567812345678) << 64) +
281*300f8da8SSiva Chandra Reddy                                      UInt128(0x1234567812345678),
2829b397371SMichael Jones                                  300, 0xd97757de56adb65c, 17503);
283*300f8da8SSiva Chandra Reddy   eisel_lemire_test<long double>((UInt128(0x1234567812345678) << 64) +
284*300f8da8SSiva Chandra Reddy                                      UInt128(0x1234567812345678),
2859b397371SMichael Jones                                  -300, 0xc30feb9a7618457d, 15510);
2869b397371SMichael Jones }
2879b397371SMichael Jones 
2889b397371SMichael Jones // These tests check numbers at the edge of the DETAILED_POWERS_OF_TEN table.
2899b397371SMichael Jones // This doesn't reach very far into the range for long doubles, since it's sized
2909b397371SMichael Jones // for doubles and their 11 exponent bits, and not for long doubles and their
2919b397371SMichael Jones // 15 exponent bits. This is a known tradeoff, and was made because a proper
2929b397371SMichael Jones // long double table would be approximately 16 times longer (specifically the
2939b397371SMichael Jones // maximum exponent would need to be about 5000, leading to a 10,000 entry
2949b397371SMichael Jones // table). This would have significant memory and storage costs all the time to
2959b397371SMichael Jones // speed up a relatively uncommon path.
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80TableLimits)2969b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80TableLimits) {
2979b397371SMichael Jones   eisel_lemire_test<long double>(1, 347, 0xd13eb46469447567, 17535);
2989b397371SMichael Jones   eisel_lemire_test<long double>(1, -348, 0xfa8fd5a0081c0288, 15226);
2999b397371SMichael Jones }
3009b397371SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80Fallback)3019b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80Fallback) {
3029b397371SMichael Jones   uint32_t outputExp2 = 0;
303*300f8da8SSiva Chandra Reddy   UInt128 quadOutputMantissa = 0;
3049b397371SMichael Jones 
3059b397371SMichael Jones   // This number is halfway between two possible results, and the algorithm
3069b397371SMichael Jones   // can't determine which is correct.
3079b397371SMichael Jones   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
3089b397371SMichael Jones       12345678901234567890u, 1, &quadOutputMantissa, &outputExp2));
3099b397371SMichael Jones 
3109b397371SMichael Jones   // These numbers' exponents are out of range for the current powers of ten
3119b397371SMichael Jones   // table.
3129b397371SMichael Jones   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
3139b397371SMichael Jones       1, 1000, &quadOutputMantissa, &outputExp2));
3149b397371SMichael Jones   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
3159b397371SMichael Jones       1, -1000, &quadOutputMantissa, &outputExp2));
3169b397371SMichael Jones }
317*300f8da8SSiva Chandra Reddy #else // Quad precision long double
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat128Simple)3189b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128Simple) {
319*300f8da8SSiva Chandra Reddy   eisel_lemire_test<long double>(123, 0, (UInt128(0x1ec0000000000) << 64),
3209b397371SMichael Jones                                  16389);
321*300f8da8SSiva Chandra Reddy   eisel_lemire_test<long double>(
322*300f8da8SSiva Chandra Reddy       12345678901234568192u, 0,
323*300f8da8SSiva Chandra Reddy       (UInt128(0x156a95319d63e) << 64) + UInt128(0x1800000000000000), 16446);
3249b397371SMichael Jones }
3259b397371SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat128LongerMantissa)3269b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128LongerMantissa) {
3279b397371SMichael Jones   eisel_lemire_test<long double>(
328*300f8da8SSiva Chandra Reddy       (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 0,
329*300f8da8SSiva Chandra Reddy       (UInt128(0x1234567812345) << 64) + UInt128(0x6781234567812345), 16507);
3309b397371SMichael Jones   eisel_lemire_test<long double>(
331*300f8da8SSiva Chandra Reddy       (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 300,
332*300f8da8SSiva Chandra Reddy       (UInt128(0x1b2eeafbcad5b) << 64) + UInt128(0x6cb8b4451dfcde19), 17503);
3339b397371SMichael Jones   eisel_lemire_test<long double>(
334*300f8da8SSiva Chandra Reddy       (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), -300,
335*300f8da8SSiva Chandra Reddy       (UInt128(0x1861fd734ec30) << 64) + UInt128(0x8afa7189f0f7595f), 15510);
3369b397371SMichael Jones }
3379b397371SMichael Jones 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat128Fallback)3389b397371SMichael Jones TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128Fallback) {
3399b397371SMichael Jones   uint32_t outputExp2 = 0;
340*300f8da8SSiva Chandra Reddy   UInt128 quadOutputMantissa = 0;
3419b397371SMichael Jones 
3429b397371SMichael Jones   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
343*300f8da8SSiva Chandra Reddy       (UInt128(0x5ce0e9a56015fec5) << 64) + UInt128(0xaadfa328ae39b333), 1,
344*300f8da8SSiva Chandra Reddy       &quadOutputMantissa, &outputExp2));
3459b397371SMichael Jones }
3469b397371SMichael Jones #endif
347