Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libc / test / src / stdlib / strtold_test.cpp
blob680a93188c76d1d7ff71497331a9e3554ddec272
1 //===-- Unittests for strtold ---------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "src/__support/FPUtil/FPBits.h"
10 #include "src/__support/UInt128.h"
11 #include "src/errno/libc_errno.h"
12 #include "src/stdlib/strtold.h"
14 #include "test/UnitTest/Test.h"
16 #include <limits.h>
17 #include <stddef.h>
19 #if defined(LONG_DOUBLE_IS_DOUBLE)
20 #define SELECT_CONST(val, _, __) val
21 #elif defined(SPECIAL_X86_LONG_DOUBLE)
22 #define SELECT_CONST(_, val, __) val
23 #else
24 #define SELECT_CONST(_, __, val) val
25 #endif
27 class LlvmLibcStrToLDTest : public LIBC_NAMESPACE::testing::Test {
28 public:
29 #if defined(LONG_DOUBLE_IS_DOUBLE)
30 void run_test(const char *inputString, const ptrdiff_t expectedStrLen,
31 const uint64_t expectedRawData, const int expectedErrno = 0)
32 #else
33 void run_test(const char *inputString, const ptrdiff_t expectedStrLen,
34 const UInt128 expectedRawData, const int expectedErrno = 0)
35 #endif
37 // expectedRawData64 is the expected long double result as a uint64_t,
38 // organized according to the IEEE754 double precision format:
40 // +-- 1 Sign Bit +-- 52 Mantissa bits
41 // | |
42 // | +-------------------------+------------------------+
43 // | | |
44 // SEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
45 // | |
46 // +----+----+
47 // |
48 // +-- 11 Exponent Bits
50 // expectedRawData80 is the expected long double result as a UInt128,
51 // organized according to the x86 extended precision format:
53 // +-- 1 Sign Bit
54 // |
55 // | +-- 1 Integer part bit (1 unless this is a subnormal)
56 // | |
57 // SEEEEEEEEEEEEEEEIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM...M
58 // | | | |
59 // +------+------+ +---------------------------+--------------------------+
60 // | |
61 // +-- 15 Exponent Bits +-- 63 Mantissa bits
63 // expectedRawData128 is the expected long double result as a UInt128,
64 // organized according to IEEE754 quadruple precision format:
66 // +-- 1 Sign Bit +-- 112 Mantissa bits
67 // | |
68 // | +----------------------------+--------------------------+
69 // | | |
70 // SEEEEEEEEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM...M
71 // | |
72 // +------+------+
73 // |
74 // +-- 15 Exponent Bits
75 char *str_end = nullptr;
77 LIBC_NAMESPACE::fputil::FPBits<long double> expected_fp =
78 LIBC_NAMESPACE::fputil::FPBits<long double>(expectedRawData);
79 const int expected_errno = expectedErrno;
81 libc_errno = 0;
82 long double result = LIBC_NAMESPACE::strtold(inputString, &str_end);
84 LIBC_NAMESPACE::fputil::FPBits<long double> actual_fp =
85 LIBC_NAMESPACE::fputil::FPBits<long double>();
86 actual_fp = LIBC_NAMESPACE::fputil::FPBits<long double>(result);
88 EXPECT_EQ(str_end - inputString, expectedStrLen);
90 EXPECT_EQ(actual_fp.bits, expected_fp.bits);
91 EXPECT_EQ(actual_fp.get_sign(), expected_fp.get_sign());
92 EXPECT_EQ(actual_fp.get_exponent(), expected_fp.get_exponent());
93 EXPECT_EQ(actual_fp.get_mantissa(), expected_fp.get_mantissa());
94 EXPECT_EQ(libc_errno, expected_errno);
98 TEST_F(LlvmLibcStrToLDTest, SimpleTest) {
99 run_test("123", 3,
100 SELECT_CONST(uint64_t(0x405ec00000000000),
101 UInt128(0x4005f60000) << 40,
102 UInt128(0x4005ec0000000000) << 64));
104 // This should fail on Eisel-Lemire, forcing a fallback to simple decimal
105 // conversion.
106 run_test("12345678901234549760", 20,
107 SELECT_CONST(uint64_t(0x43e56a95319d63d8),
108 (UInt128(0x403eab54a9) << 40) + UInt128(0x8ceb1ec400),
109 (UInt128(0x403e56a95319d63d) << 64) +
110 UInt128(0x8800000000000000)));
112 // Found while looking for difficult test cases here:
113 // https://github.com/nigeltao/parse-number-fxx-test-data/blob/main/more-test-cases/golang-org-issue-36657.txt
114 run_test("1090544144181609348835077142190", 31,
115 SELECT_CONST(uint64_t(0x462b8779f2474dfb),
116 (UInt128(0x4062dc3bcf) << 40) + UInt128(0x923a6fd402),
117 (UInt128(0x4062b8779f2474df) << 64) +
118 UInt128(0xa804bfd8c6d5c000)));
120 run_test("0x123", 5,
121 SELECT_CONST(uint64_t(0x4072300000000000),
122 (UInt128(0x4007918000) << 40),
123 (UInt128(0x4007230000000000) << 64)));
126 // These are tests that have caused problems for doubles in the past.
127 TEST_F(LlvmLibcStrToLDTest, Float64SpecificFailures) {
128 run_test("3E70000000000000", 16,
129 SELECT_CONST(uint64_t(0x7FF0000000000000),
130 (UInt128(0x7fff800000) << 40),
131 (UInt128(0x7fff000000000000) << 64)),
132 ERANGE);
133 run_test("358416272e-33", 13,
134 SELECT_CONST(uint64_t(0x3adbbb2a68c9d0b9),
135 (UInt128(0x3fadddd953) << 40) + UInt128(0x464e85c400),
136 (UInt128(0x3fadbbb2a68c9d0b) << 64) +
137 UInt128(0x8800e7969e1c5fc8)));
138 run_test("2.16656806400000023841857910156251e9", 36,
139 SELECT_CONST(uint64_t(0x41e0246690000001),
140 (UInt128(0x401e812334) << 40) + UInt128(0x8000000400),
141 (UInt128(0x401e024669000000) << 64) +
142 UInt128(0x800000000000018)));
143 run_test("27949676547093071875", 20,
144 SELECT_CONST(uint64_t(0x43f83e132bc608c9),
145 (UInt128(0x403fc1f099) << 40) + UInt128(0x5e30464402),
146 (UInt128(0x403f83e132bc608c) << 64) +
147 UInt128(0x8803000000000000)));
150 TEST_F(LlvmLibcStrToLDTest, Float80SpecificFailures) {
151 run_test("7777777777777777777777777777777777777777777777777777777777777777777"
152 "777777777777777777777777777777777",
153 100,
154 SELECT_CONST(uint64_t(0x54ac729b8fcaf734),
155 (UInt128(0x414ae394dc) << 40) + UInt128(0x7e57b9a0c2),
156 (UInt128(0x414ac729b8fcaf73) << 64) +
157 UInt128(0x4184a3d793224129)));
160 TEST_F(LlvmLibcStrToLDTest, MaxSizeNumbers) {
161 run_test("1.1897314953572317650e4932", 26,
162 SELECT_CONST(uint64_t(0x7FF0000000000000),
163 (UInt128(0x7ffeffffff) << 40) + UInt128(0xffffffffff),
164 (UInt128(0x7ffeffffffffffff) << 64) +
165 UInt128(0xfffd57322e3f8675)),
166 SELECT_CONST(ERANGE, 0, 0));
167 run_test("1.18973149535723176508e4932", 27,
168 SELECT_CONST(uint64_t(0x7FF0000000000000),
169 (UInt128(0x7fff800000) << 40),
170 (UInt128(0x7ffeffffffffffff) << 64) +
171 UInt128(0xffffd2478338036c)),
172 SELECT_CONST(ERANGE, ERANGE, 0));
175 // These tests check subnormal behavior for 80 bit and 128 bit floats. They will
176 // be too small for 64 bit floats.
177 TEST_F(LlvmLibcStrToLDTest, SubnormalTests) {
178 run_test("1e-4950", 7,
179 SELECT_CONST(uint64_t(0), (UInt128(0x00000000000000000003)),
180 (UInt128(0x000000000000000000057c9647e1a018))),
181 ERANGE);
182 run_test("1.89e-4951", 10,
183 SELECT_CONST(uint64_t(0), (UInt128(0x00000000000000000001)),
184 (UInt128(0x0000000000000000000109778a006738))),
185 ERANGE);
186 run_test("4e-4966", 7,
187 SELECT_CONST(uint64_t(0), (UInt128(0)),
188 (UInt128(0x00000000000000000000000000000001))),
189 ERANGE);
192 TEST_F(LlvmLibcStrToLDTest, SmallNormalTests) {
193 run_test("3.37e-4932", 10,
194 SELECT_CONST(
195 uint64_t(0), (UInt128(0x1804cf7) << 40) + UInt128(0x908850712),
196 (UInt128(0x10099ee12110a) << 64) + UInt128(0xe24b75c0f50dc0c)),
197 SELECT_CONST(ERANGE, 0, 0));
200 TEST_F(LlvmLibcStrToLDTest, ComplexHexadecimalTests) {
201 run_test("0x1p16383", 9,
202 SELECT_CONST(0x7ff0000000000000, (UInt128(0x7ffe800000) << 40),
203 (UInt128(0x7ffe000000000000) << 64)),
204 SELECT_CONST(ERANGE, 0, 0));
205 run_test("0x123456789abcdef", 17,
206 SELECT_CONST(0x43723456789abcdf,
207 (UInt128(0x403791a2b3) << 40) + UInt128(0xc4d5e6f780),
208 (UInt128(0x403723456789abcd) << 64) +
209 UInt128(0xef00000000000000)));
210 run_test("0x123456789abcdef0123456789ABCDEF", 33,
211 SELECT_CONST(0x47723456789abcdf,
212 (UInt128(0x407791a2b3) << 40) + UInt128(0xc4d5e6f781),
213 (UInt128(0x407723456789abcd) << 64) +
214 UInt128(0xef0123456789abce)));
217 TEST_F(LlvmLibcStrToLDTest, InfTests) {
218 run_test("INF", 3,
219 SELECT_CONST(0x7ff0000000000000, (UInt128(0x7fff800000) << 40),
220 (UInt128(0x7fff000000000000) << 64)));
221 run_test("INFinity", 8,
222 SELECT_CONST(0x7ff0000000000000, (UInt128(0x7fff800000) << 40),
223 (UInt128(0x7fff000000000000) << 64)));
224 run_test("-inf", 4,
225 SELECT_CONST(0xfff0000000000000, (UInt128(0xffff800000) << 40),
226 (UInt128(0xffff000000000000) << 64)));
229 TEST_F(LlvmLibcStrToLDTest, NaNTests) {
230 run_test("NaN", 3,
231 SELECT_CONST(0x7ff8000000000000, (UInt128(0x7fffc00000) << 40),
232 (UInt128(0x7fff800000000000) << 64)));
233 run_test("-nAn", 4,
234 SELECT_CONST(0xfff8000000000000, (UInt128(0xffffc00000) << 40),
235 (UInt128(0xffff800000000000) << 64)));
236 run_test("NaN()", 5,
237 SELECT_CONST(0x7ff8000000000000, (UInt128(0x7fffc00000) << 40),
238 (UInt128(0x7fff800000000000) << 64)));
239 run_test("NaN(1234)", 9,
240 SELECT_CONST(0x7ff80000000004d2,
241 (UInt128(0x7fffc00000) << 40) + UInt128(0x4d2),
242 (UInt128(0x7fff800000000000) << 64) + UInt128(0x4d2)));
243 run_test("NaN(0xffffffffffff)", 19,
244 SELECT_CONST(0x7ff8ffffffffffff,
245 (UInt128(0x7fffc000ff) << 40) + UInt128(0xffffffffff),
246 (UInt128(0x7fff800000000000) << 64) +
247 UInt128(0xffffffffffff)));
248 run_test("NaN(0xfffffffffffff)", 20,
249 SELECT_CONST(0x7fffffffffffffff,
250 (UInt128(0x7fffc00fff) << 40) + UInt128(0xffffffffff),
251 (UInt128(0x7fff800000000000) << 64) +
252 UInt128(0xfffffffffffff)));
253 run_test("NaN(0xffffffffffffffff)", 23,
254 SELECT_CONST(0x7fffffffffffffff,
255 (UInt128(0x7fffffffff) << 40) + UInt128(0xffffffffff),
256 (UInt128(0x7fff800000000000) << 64) +
257 UInt128(0xffffffffffffffff)));
258 run_test("NaN( 1234)", 3,
259 SELECT_CONST(0x7ff8000000000000, (UInt128(0x7fffc00000) << 40),
260 (UInt128(0x7fff800000000000) << 64)));