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> 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> 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> 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> 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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) 266 TEST_F(LlvmLibcStrToFloatTest, EiselLemireFloat64AsLongDouble) { 267 eisel_lemire_test<long double>(123, 0, 0x1EC00000000000, 1029); 268 } 269 #elif defined(SPECIAL_X86_LONG_DOUBLE) 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 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. 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 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 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 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 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