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