1 //===-- Unittests for str_to_float ----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/CPP/UInt128.h"
10 #include "src/__support/FPUtil/FPBits.h"
11 #include "src/__support/str_to_float.h"
12 
13 #include "utils/UnitTest/Test.h"
14 
15 class LlvmLibcStrToFloatTest : public __llvm_libc::testing::Test {
16 public:
17   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)18   void clinger_fast_path_test(
19       const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,
20       const int32_t inputExp10,
21       const typename __llvm_libc::fputil::FPBits<T>::UIntType
22           expectedOutputMantissa,
23       const uint32_t expectedOutputExp2) {
24     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
25         0;
26     uint32_t actual_output_exp2 = 0;
27 
28     ASSERT_TRUE(__llvm_libc::internal::clinger_fast_path<T>(
29         inputMantissa, inputExp10, &actual_output_mantissa,
30         &actual_output_exp2));
31     EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa);
32     EXPECT_EQ(actual_output_exp2, expectedOutputExp2);
33   }
34 
35   template <class T>
clinger_fast_path_fails_test(const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,const int32_t inputExp10)36   void clinger_fast_path_fails_test(
37       const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,
38       const int32_t inputExp10) {
39     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
40         0;
41     uint32_t actual_output_exp2 = 0;
42 
43     ASSERT_FALSE(__llvm_libc::internal::clinger_fast_path<T>(
44         inputMantissa, inputExp10, &actual_output_mantissa,
45         &actual_output_exp2));
46   }
47 
48   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)49   void eisel_lemire_test(
50       const typename __llvm_libc::fputil::FPBits<T>::UIntType inputMantissa,
51       const int32_t inputExp10,
52       const typename __llvm_libc::fputil::FPBits<T>::UIntType
53           expectedOutputMantissa,
54       const uint32_t expectedOutputExp2) {
55     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
56         0;
57     uint32_t actual_output_exp2 = 0;
58 
59     ASSERT_TRUE(__llvm_libc::internal::eisel_lemire<T>(
60         inputMantissa, inputExp10, &actual_output_mantissa,
61         &actual_output_exp2));
62     EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa);
63     EXPECT_EQ(actual_output_exp2, expectedOutputExp2);
64   }
65 
66   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)67   void simple_decimal_conversion_test(
68       const char *__restrict numStart,
69       const typename __llvm_libc::fputil::FPBits<T>::UIntType
70           expectedOutputMantissa,
71       const uint32_t expectedOutputExp2, const int expectedErrno = 0) {
72     typename __llvm_libc::fputil::FPBits<T>::UIntType actual_output_mantissa =
73         0;
74     uint32_t actual_output_exp2 = 0;
75     errno = 0;
76 
77     __llvm_libc::internal::simple_decimal_conversion<T>(
78         numStart, &actual_output_mantissa, &actual_output_exp2);
79     EXPECT_EQ(actual_output_mantissa, expectedOutputMantissa);
80     EXPECT_EQ(actual_output_exp2, expectedOutputExp2);
81     EXPECT_EQ(errno, expectedErrno);
82   }
83 };
84 
TEST(LlvmLibcStrToFloatTest,LeadingZeroes)85 TEST(LlvmLibcStrToFloatTest, LeadingZeroes) {
86   uint64_t test_num64 = 1;
87   uint32_t num_of_zeroes = 63;
88   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(0), 64u);
89   for (; num_of_zeroes < 64; test_num64 <<= 1, num_of_zeroes--) {
90     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(test_num64),
91               num_of_zeroes);
92   }
93 
94   test_num64 = 3;
95   num_of_zeroes = 62;
96   for (; num_of_zeroes > 63; test_num64 <<= 1, num_of_zeroes--) {
97     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(test_num64),
98               num_of_zeroes);
99   }
100 
101   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(0xffffffffffffffff),
102             0u);
103 
104   test_num64 = 1;
105   num_of_zeroes = 63;
106   for (; num_of_zeroes > 63;
107        test_num64 = (test_num64 << 1) + 1, num_of_zeroes--) {
108     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint64_t>(test_num64),
109               num_of_zeroes);
110   }
111 
112   uint64_t test_num32 = 1;
113   num_of_zeroes = 31;
114   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint32_t>(0), 32u);
115   for (; num_of_zeroes < 32; test_num32 <<= 1, num_of_zeroes--) {
116     EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint32_t>(test_num32),
117               num_of_zeroes);
118   }
119 
120   EXPECT_EQ(__llvm_libc::internal::leading_zeroes<uint32_t>(0xffffffff), 0u);
121 }
122 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat64Simple)123 TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64Simple) {
124   clinger_fast_path_test<double>(123, 0, 0xEC00000000000, 1029);
125   clinger_fast_path_test<double>(1234567890123456, 1, 0x5ee2a2eb5a5c0, 1076);
126   clinger_fast_path_test<double>(1234567890, -10, 0xf9add3739635f, 1019);
127 }
128 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat64ExtendedExp)129 TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64ExtendedExp) {
130   clinger_fast_path_test<double>(1, 30, 0x93e5939a08cea, 1122);
131   clinger_fast_path_test<double>(1, 37, 0xe17b84357691b, 1145);
132   clinger_fast_path_fails_test<double>(10, 37);
133   clinger_fast_path_fails_test<double>(1, 100);
134 }
135 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat64NegativeExp)136 TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat64NegativeExp) {
137   clinger_fast_path_test<double>(1, -10, 0xb7cdfd9d7bdbb, 989);
138   clinger_fast_path_test<double>(1, -20, 0x79ca10c924223, 956);
139   clinger_fast_path_fails_test<double>(1, -25);
140 }
141 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat32Simple)142 TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32Simple) {
143   clinger_fast_path_test<float>(123, 0, 0x760000, 133);
144   clinger_fast_path_test<float>(1234567, 1, 0x3c6146, 150);
145   clinger_fast_path_test<float>(12345, -5, 0x7cd35b, 123);
146 }
147 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat32ExtendedExp)148 TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32ExtendedExp) {
149   clinger_fast_path_test<float>(1, 15, 0x635fa9, 176);
150   clinger_fast_path_test<float>(1, 17, 0x31a2bc, 183);
151   clinger_fast_path_fails_test<float>(10, 17);
152   clinger_fast_path_fails_test<float>(1, 50);
153 }
154 
TEST_F(LlvmLibcStrToFloatTest,ClingerFastPathFloat32NegativeExp)155 TEST_F(LlvmLibcStrToFloatTest, ClingerFastPathFloat32NegativeExp) {
156   clinger_fast_path_test<float>(1, -5, 0x27c5ac, 110);
157   clinger_fast_path_test<float>(1, -10, 0x5be6ff, 93);
158   clinger_fast_path_fails_test<float>(1, -15);
159 }
160 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat64Simple)161 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64Simple) {
162   eisel_lemire_test<double>(12345678901234567890u, 1, 0x1AC53A7E04BCDA, 1089);
163   eisel_lemire_test<double>(123, 0, 0x1EC00000000000, 1029);
164   eisel_lemire_test<double>(12345678901234568192u, 0, 0x156A95319D63E2, 1086);
165 }
166 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat64SpecificFailures)167 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64SpecificFailures) {
168   // These test cases have caused failures in the past.
169   eisel_lemire_test<double>(358416272, -33, 0x1BBB2A68C9D0B9, 941);
170   eisel_lemire_test<double>(2166568064000000238u, -9, 0x10246690000000, 1054);
171   eisel_lemire_test<double>(2794967654709307187u, 1, 0x183e132bc608c8, 1087);
172   eisel_lemire_test<double>(2794967654709307188u, 1, 0x183e132bc608c9, 1087);
173 }
174 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFallbackStates)175 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFallbackStates) {
176   // Check the fallback states for the algorithm:
177   uint32_t float_output_mantissa = 0;
178   uint64_t double_output_mantissa = 0;
179   uint32_t output_exp2 = 0;
180 
181   // This number can't be evaluated by Eisel-Lemire since it's exactly 1024 away
182   // from both of its closest floating point approximations
183   // (12345678901234548736 and 12345678901234550784)
184   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<double>(
185       12345678901234549760u, 0, &double_output_mantissa, &output_exp2));
186 
187   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<float>(
188       20040229, 0, &float_output_mantissa, &output_exp2));
189 }
190 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicWholeNumbers)191 TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicWholeNumbers) {
192   simple_decimal_conversion_test<double>("123456789012345678900",
193                                          0x1AC53A7E04BCDA, 1089);
194   simple_decimal_conversion_test<double>("123", 0x1EC00000000000, 1029);
195   simple_decimal_conversion_test<double>("12345678901234549760",
196                                          0x156A95319D63D8, 1086);
197 }
198 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicDecimals)199 TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicDecimals) {
200   simple_decimal_conversion_test<double>("1.2345", 0x13c083126e978d, 1023);
201   simple_decimal_conversion_test<double>(".2345", 0x1e04189374bc6a, 1020);
202   simple_decimal_conversion_test<double>(".299792458", 0x132fccb4aca314, 1021);
203 }
204 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicExponents)205 TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicExponents) {
206   simple_decimal_conversion_test<double>("1e10", 0x12a05f20000000, 1056);
207   simple_decimal_conversion_test<double>("1e-10", 0x1b7cdfd9d7bdbb, 989);
208   simple_decimal_conversion_test<double>("1e300", 0x17e43c8800759c, 2019);
209   simple_decimal_conversion_test<double>("1e-300", 0x156e1fc2f8f359, 26);
210 }
211 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64BasicSubnormals)212 TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64BasicSubnormals) {
213   simple_decimal_conversion_test<double>("1e-320", 0x7e8, 0, ERANGE);
214   simple_decimal_conversion_test<double>("1e-308", 0x730d67819e8d2, 0, ERANGE);
215   simple_decimal_conversion_test<double>("2.9e-308", 0x14da6df5e4bcc8, 1);
216 }
217 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion64SubnormalRounding)218 TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion64SubnormalRounding) {
219 
220   // Technically you can keep adding digits until you hit the truncation limit,
221   // but this is the shortest string that results in the maximum subnormal that
222   // I found.
223   simple_decimal_conversion_test<double>("2.225073858507201e-308",
224                                          0xfffffffffffff, 0, ERANGE);
225 
226   // Same here, if you were to extend the max subnormal out for another 800
227   // digits, incrementing any one of those digits would create a normal number.
228   simple_decimal_conversion_test<double>("2.2250738585072012e-308",
229                                          0x10000000000000, 1);
230 }
231 
TEST_F(LlvmLibcStrToFloatTest,SimpleDecimalConversion32SpecificFailures)232 TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion32SpecificFailures) {
233   simple_decimal_conversion_test<float>(
234       "1.4012984643248170709237295832899161312802619418765e-45", 0x1, 0,
235       ERANGE);
236   simple_decimal_conversion_test<float>(
237       "7."
238       "006492321624085354618647916449580656401309709382578858785341419448955413"
239       "42930300743319094181060791015625e-46",
240       0x0, 0, ERANGE);
241 }
242 
TEST(LlvmLibcStrToFloatTest,SimpleDecimalConversionExtraTypes)243 TEST(LlvmLibcStrToFloatTest, SimpleDecimalConversionExtraTypes) {
244   uint32_t float_output_mantissa = 0;
245   uint32_t output_exp2 = 0;
246 
247   errno = 0;
248   __llvm_libc::internal::simple_decimal_conversion<float>(
249       "123456789012345678900", &float_output_mantissa, &output_exp2);
250   EXPECT_EQ(float_output_mantissa, uint32_t(0xd629d4));
251   EXPECT_EQ(output_exp2, uint32_t(193));
252   EXPECT_EQ(errno, 0);
253 
254   uint64_t double_output_mantissa = 0;
255   output_exp2 = 0;
256 
257   errno = 0;
258   __llvm_libc::internal::simple_decimal_conversion<double>(
259       "123456789012345678900", &double_output_mantissa, &output_exp2);
260   EXPECT_EQ(double_output_mantissa, uint64_t(0x1AC53A7E04BCDA));
261   EXPECT_EQ(output_exp2, uint32_t(1089));
262   EXPECT_EQ(errno, 0);
263 }
264 
265 #if defined(LONG_DOUBLE_IS_DOUBLE)
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat64AsLongDouble)266 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64AsLongDouble) {
267   eisel_lemire_test<long double>(123, 0, 0x1EC00000000000, 1029);
268 }
269 #elif defined(SPECIAL_X86_LONG_DOUBLE)
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80Simple)270 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80Simple) {
271   eisel_lemire_test<long double>(123, 0, 0xf600000000000000, 16389);
272   eisel_lemire_test<long double>(12345678901234568192u, 0, 0xab54a98ceb1f0c00,
273                                  16446);
274 }
275 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80LongerMantissa)276 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80LongerMantissa) {
277   eisel_lemire_test<long double>((UInt128(0x1234567812345678) << 64) +
278                                      UInt128(0x1234567812345678),
279                                  0, 0x91a2b3c091a2b3c1, 16507);
280   eisel_lemire_test<long double>((UInt128(0x1234567812345678) << 64) +
281                                      UInt128(0x1234567812345678),
282                                  300, 0xd97757de56adb65c, 17503);
283   eisel_lemire_test<long double>((UInt128(0x1234567812345678) << 64) +
284                                      UInt128(0x1234567812345678),
285                                  -300, 0xc30feb9a7618457d, 15510);
286 }
287 
288 // These tests check numbers at the edge of the DETAILED_POWERS_OF_TEN table.
289 // This doesn't reach very far into the range for long doubles, since it's sized
290 // for doubles and their 11 exponent bits, and not for long doubles and their
291 // 15 exponent bits. This is a known tradeoff, and was made because a proper
292 // long double table would be approximately 16 times longer (specifically the
293 // maximum exponent would need to be about 5000, leading to a 10,000 entry
294 // table). This would have significant memory and storage costs all the time to
295 // speed up a relatively uncommon path.
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80TableLimits)296 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80TableLimits) {
297   eisel_lemire_test<long double>(1, 347, 0xd13eb46469447567, 17535);
298   eisel_lemire_test<long double>(1, -348, 0xfa8fd5a0081c0288, 15226);
299 }
300 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat80Fallback)301 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat80Fallback) {
302   uint32_t outputExp2 = 0;
303   UInt128 quadOutputMantissa = 0;
304 
305   // This number is halfway between two possible results, and the algorithm
306   // can't determine which is correct.
307   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
308       12345678901234567890u, 1, &quadOutputMantissa, &outputExp2));
309 
310   // These numbers' exponents are out of range for the current powers of ten
311   // table.
312   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
313       1, 1000, &quadOutputMantissa, &outputExp2));
314   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
315       1, -1000, &quadOutputMantissa, &outputExp2));
316 }
317 #else // Quad precision long double
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat128Simple)318 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128Simple) {
319   eisel_lemire_test<long double>(123, 0, (UInt128(0x1ec0000000000) << 64),
320                                  16389);
321   eisel_lemire_test<long double>(
322       12345678901234568192u, 0,
323       (UInt128(0x156a95319d63e) << 64) + UInt128(0x1800000000000000), 16446);
324 }
325 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat128LongerMantissa)326 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128LongerMantissa) {
327   eisel_lemire_test<long double>(
328       (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 0,
329       (UInt128(0x1234567812345) << 64) + UInt128(0x6781234567812345), 16507);
330   eisel_lemire_test<long double>(
331       (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), 300,
332       (UInt128(0x1b2eeafbcad5b) << 64) + UInt128(0x6cb8b4451dfcde19), 17503);
333   eisel_lemire_test<long double>(
334       (UInt128(0x1234567812345678) << 64) + UInt128(0x1234567812345678), -300,
335       (UInt128(0x1861fd734ec30) << 64) + UInt128(0x8afa7189f0f7595f), 15510);
336 }
337 
TEST_F(LlvmLibcStrToFloatTest,EiselLemireFloat128Fallback)338 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat128Fallback) {
339   uint32_t outputExp2 = 0;
340   UInt128 quadOutputMantissa = 0;
341 
342   ASSERT_FALSE(__llvm_libc::internal::eisel_lemire<long double>(
343       (UInt128(0x5ce0e9a56015fec5) << 64) + UInt128(0xaadfa328ae39b333), 1,
344       &quadOutputMantissa, &outputExp2));
345 }
346 #endif
347