Skip to content

Commit 7c1c07c

Browse files
authored
[libc][math][c23] Fix X86_Binary80 special cases for canonicalize functions. (#86924)
Updates the special case of pseudo infinty as pointed in #85940
1 parent 6b95747 commit 7c1c07c

File tree

3 files changed

+54
-56
lines changed

3 files changed

+54
-56
lines changed

libc/src/__support/FPUtil/BasicOperations.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -185,27 +185,28 @@ LIBC_INLINE int canonicalize(T &cx, const T &x) {
185185
// More precisely :
186186
// Exponent | Significand | Meaning
187187
// | Bits 63-62 | Bits 61-0 |
188-
// All Ones | 00 | Zero | Pseudo Infinity, Value = Infinty
188+
// All Ones | 00 | Zero | Pseudo Infinity, Value = SNaN
189189
// All Ones | 00 | Non-Zero | Pseudo NaN, Value = SNaN
190190
// All Ones | 01 | Anything | Pseudo NaN, Value = SNaN
191191
// | Bit 63 | Bits 62-0 |
192192
// All zeroes | One | Anything | Pseudo Denormal, Value =
193193
// | | | (−1)**s × m × 2**−16382
194-
// All Other | Zero | Anything | Unnormal, Value =
195-
// Values | | | (−1)**s × m × 2**−16382
194+
// All Other | Zero | Anything | Unnormal, Value = SNaN
195+
// Values | | |
196196
bool bit63 = sx.get_implicit_bit();
197197
UInt128 mantissa = sx.get_explicit_mantissa();
198198
bool bit62 = static_cast<bool>((mantissa & (1ULL << 62)) >> 62);
199199
int exponent = sx.get_biased_exponent();
200200
if (exponent == 0x7FFF) {
201201
if (!bit63 && !bit62) {
202-
if (mantissa == 0)
203-
cx = FPBits<T>::inf(sx.sign()).get_val();
204-
else {
202+
if (mantissa == 0) {
205203
cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
206204
raise_except_if_required(FE_INVALID);
207205
return 1;
208206
}
207+
cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
208+
raise_except_if_required(FE_INVALID);
209+
return 1;
209210
} else if (!bit63 && bit62) {
210211
cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
211212
raise_except_if_required(FE_INVALID);
@@ -219,9 +220,11 @@ LIBC_INLINE int canonicalize(T &cx, const T &x) {
219220
cx = x;
220221
} else if (exponent == 0 && bit63)
221222
cx = FPBits<T>::make_value(mantissa, 0).get_val();
222-
else if (exponent != 0 && !bit63)
223-
cx = FPBits<T>::make_value(mantissa, 0).get_val();
224-
else if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
223+
else if (exponent != 0 && !bit63) {
224+
cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
225+
raise_except_if_required(FE_INVALID);
226+
return 1;
227+
} else if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
225228
cx =
226229
FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa()).get_val();
227230
raise_except_if_required(FE_INVALID);

libc/test/src/math/smoke/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ add_fp_unittest(
178178
libc.src.math.canonicalize
179179
libc.src.__support.FPUtil.fp_bits
180180
libc.src.__support.FPUtil.fenv_impl
181+
libc.src.__support.integer_literals
181182
)
182183

183184
add_fp_unittest(
@@ -193,6 +194,7 @@ add_fp_unittest(
193194
libc.src.math.canonicalizef
194195
libc.src.__support.FPUtil.fp_bits
195196
libc.src.__support.FPUtil.fenv_impl
197+
libc.src.__support.integer_literals
196198
)
197199

198200
add_fp_unittest(
@@ -208,6 +210,7 @@ add_fp_unittest(
208210
libc.src.math.canonicalizef128
209211
libc.src.__support.FPUtil.fp_bits
210212
libc.src.__support.FPUtil.fenv_impl
213+
libc.src.__support.integer_literals
211214
)
212215

213216
add_fp_unittest(
@@ -223,6 +226,7 @@ add_fp_unittest(
223226
libc.src.math.canonicalizel
224227
libc.src.__support.FPUtil.fp_bits
225228
libc.src.__support.FPUtil.fenv_impl
229+
libc.src.__support.integer_literals
226230
)
227231

228232
add_fp_unittest(

libc/test/src/math/smoke/CanonicalizeTest.h

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
1111

1212
#include "src/__support/FPUtil/FPBits.h"
13+
#include "src/__support/integer_literals.h"
1314
#include "test/UnitTest/FPMatcher.h"
1415
#include "test/UnitTest/Test.h"
1516

@@ -22,6 +23,8 @@
2223

2324
#define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, 0)
2425

26+
using LIBC_NAMESPACE::operator""_u128;
27+
2528
template <typename T>
2629
class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
2730

@@ -55,57 +58,54 @@ class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
5558
T cx;
5659
// Exponent | Significand | Meaning
5760
// | Bits 63-62 | Bits 61-0 |
58-
// All Ones | 00 | Zero | Pseudo Infinity, Value = Infinty
59-
60-
FPBits test1((UInt128(0x7FFF) << 64) + UInt128(0x0000000000000000));
61+
// All Ones | 00 | Zero | Pseudo Infinity, Value = SNaN
62+
FPBits test1(0x00000000'00007FFF'00000000'00000000_u128);
6163
const T test1_val = test1.get_val();
62-
TEST_SPECIAL(cx, test1_val, 0, 0);
63-
EXPECT_FP_EQ(cx, inf);
64+
TEST_SPECIAL(cx, test1_val, 1, FE_INVALID);
65+
EXPECT_FP_EQ(cx, aNaN);
6466

6567
// Exponent | Significand | Meaning
6668
// | Bits 63-62 | Bits 61-0 |
6769
// All Ones | 00 | Non-Zero | Pseudo NaN, Value = SNaN
68-
69-
FPBits test2_1((UInt128(0x7FFF) << 64) + UInt128(0x0000000000000001));
70+
FPBits test2_1(0x000000000'00007FFF'00000000'00000001_u128);
7071
const T test2_1_val = test2_1.get_val();
7172
TEST_SPECIAL(cx, test2_1_val, 1, FE_INVALID);
7273
EXPECT_FP_EQ(cx, aNaN);
7374

74-
FPBits test2_2((UInt128(0x7FFF) << 64) + UInt128(0x0000004270000001));
75+
FPBits test2_2(0x000000000'00007FFF'00000042'70000001_u128);
7576
const T test2_2_val = test2_2.get_val();
7677
TEST_SPECIAL(cx, test2_2_val, 1, FE_INVALID);
7778
EXPECT_FP_EQ(cx, aNaN);
7879

79-
FPBits test2_3((UInt128(0x7FFF) << 64) + UInt128(0x0000000008261001));
80+
FPBits test2_3(0x000000000'00007FFF'00000000'08261001_u128);
8081
const T test2_3_val = test2_3.get_val();
8182
TEST_SPECIAL(cx, test2_3_val, 1, FE_INVALID);
8283
EXPECT_FP_EQ(cx, aNaN);
8384

84-
FPBits test2_4((UInt128(0x7FFF) << 64) + UInt128(0x0000780008261001));
85+
FPBits test2_4(0x000000000'00007FFF'00007800'08261001_u128);
8586
const T test2_4_val = test2_4.get_val();
8687
TEST_SPECIAL(cx, test2_4_val, 1, FE_INVALID);
8788
EXPECT_FP_EQ(cx, aNaN);
8889

8990
// Exponent | Significand | Meaning
9091
// | Bits 63-62 | Bits 61-0 |
9192
// All Ones | 01 | Anything | Pseudo NaN, Value = SNaN
92-
93-
FPBits test3_1((UInt128(0x7FFF) << 64) + UInt128(0x4000000000000000));
93+
FPBits test3_1(0x00000000'00007FFF'40000000'00000000_u128);
9494
const T test3_1_val = test3_1.get_val();
9595
TEST_SPECIAL(cx, test3_1_val, 1, FE_INVALID);
9696
EXPECT_FP_EQ(cx, aNaN);
9797

98-
FPBits test3_2((UInt128(0x7FFF) << 64) + UInt128(0x4000004270000001));
98+
FPBits test3_2(0x00000000'00007FFF'40000042'70000001_u128);
9999
const T test3_2_val = test3_2.get_val();
100100
TEST_SPECIAL(cx, test3_2_val, 1, FE_INVALID);
101101
EXPECT_FP_EQ(cx, aNaN);
102102

103-
FPBits test3_3((UInt128(0x7FFF) << 64) + UInt128(0x4000000008261001));
103+
FPBits test3_3(0x00000000'00007FFF'40000000'08261001_u128);
104104
const T test3_3_val = test3_3.get_val();
105105
TEST_SPECIAL(cx, test3_3_val, 1, FE_INVALID);
106106
EXPECT_FP_EQ(cx, aNaN);
107107

108-
FPBits test3_4((UInt128(0x7FFF) << 64) + UInt128(0x4007800008261001));
108+
FPBits test3_4(0x00000000'00007FFF'40007800'08261001_u128);
109109
const T test3_4_val = test3_4.get_val();
110110
TEST_SPECIAL(cx, test3_4_val, 1, FE_INVALID);
111111
EXPECT_FP_EQ(cx, aNaN);
@@ -114,65 +114,56 @@ class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
114114
// | Bit 63 | Bits 62-0 |
115115
// All zeroes | One | Anything | Pseudo Denormal, Value =
116116
// | | | (−1)**s × m × 2**−16382
117-
118-
FPBits test4_1((UInt128(0x0000) << 64) + UInt128(0x8000000000000000));
117+
FPBits test4_1(0x00000000'00000000'80000000'00000000_u128);
119118
const T test4_1_val = test4_1.get_val();
120119
TEST_SPECIAL(cx, test4_1_val, 0, 0);
121120
EXPECT_FP_EQ(
122121
cx, FPBits::make_value(test4_1.get_explicit_mantissa(), 0).get_val());
123122

124-
FPBits test4_2((UInt128(0x0000) << 64) + UInt128(0x8000004270000001));
123+
FPBits test4_2(0x00000000'00000000'80000042'70000001_u128);
125124
const T test4_2_val = test4_2.get_val();
126125
TEST_SPECIAL(cx, test4_2_val, 0, 0);
127126
EXPECT_FP_EQ(
128127
cx, FPBits::make_value(test4_2.get_explicit_mantissa(), 0).get_val());
129-
130-
FPBits test4_3((UInt128(0x0000) << 64) + UInt128(0x8000000008261001));
128+
FPBits test4_3(0x00000000'00000000'80000000'08261001_u128);
131129
const T test4_3_val = test4_3.get_val();
132130
TEST_SPECIAL(cx, test4_3_val, 0, 0);
133131
EXPECT_FP_EQ(
134132
cx, FPBits::make_value(test4_3.get_explicit_mantissa(), 0).get_val());
135133

136134
// Exponent | Significand | Meaning
137135
// | Bit 63 | Bits 62-0 |
138-
// All Other | Zero | Anything | Unnormal, Value =
139-
// Values | | | (−1)**s × m × 2**−16382
140-
141-
FPBits test5_1(UInt128(0x0000000000000001));
136+
// All Other | Zero | Anything | Unnormal, Value = SNaN
137+
// Values | | |
138+
FPBits test5_1(0x00000000'00000040'00000000'00000001_u128);
142139
const T test5_1_val = test5_1.get_val();
143-
TEST_SPECIAL(cx, test5_1_val, 0, 0);
144-
EXPECT_FP_EQ(
145-
cx, FPBits::make_value(test5_1.get_explicit_mantissa(), 0).get_val());
140+
TEST_SPECIAL(cx, test5_1_val, 1, FE_INVALID);
141+
EXPECT_FP_EQ(cx, aNaN);
146142

147-
FPBits test5_2(UInt128(0x0000004270000001));
143+
FPBits test5_2(0x00000000'00000230'00000042'70000001_u128);
148144
const T test5_2_val = test5_2.get_val();
149-
TEST_SPECIAL(cx, test5_2_val, 0, 0);
150-
EXPECT_FP_EQ(
151-
cx, FPBits::make_value(test5_2.get_explicit_mantissa(), 0).get_val());
145+
TEST_SPECIAL(cx, test5_2_val, 1, FE_INVALID);
146+
EXPECT_FP_EQ(cx, aNaN);
152147

153-
FPBits test5_3(UInt128(0x0000000008261001));
148+
FPBits test5_3(0x00000000'00000560'00000000'08261001_u128);
154149
const T test5_3_val = test5_3.get_val();
155-
TEST_SPECIAL(cx, test5_3_val, 0, 0);
156-
EXPECT_FP_EQ(
157-
cx, FPBits::make_value(test5_3.get_explicit_mantissa(), 0).get_val());
150+
TEST_SPECIAL(cx, test5_3_val, 1, FE_INVALID);
151+
EXPECT_FP_EQ(cx, aNaN);
158152

159-
FPBits test5_4(UInt128(0x0000002816000000));
153+
FPBits test5_4(0x00000000'00000780'00000028'16000000_u128);
160154
const T test5_4_val = test5_4.get_val();
161-
TEST_SPECIAL(cx, test5_4_val, 0, 0);
162-
EXPECT_FP_EQ(
163-
cx, FPBits::make_value(test5_4.get_explicit_mantissa(), 0).get_val());
155+
TEST_SPECIAL(cx, test5_4_val, 1, FE_INVALID);
156+
EXPECT_FP_EQ(cx, aNaN);
164157

165-
FPBits test5_5(UInt128(0x0000004270000001));
158+
FPBits test5_5(0x00000000'00000900'00000042'70000001_u128);
166159
const T test5_5_val = test5_5.get_val();
167-
TEST_SPECIAL(cx, test5_5_val, 0, 0);
168-
EXPECT_FP_EQ(
169-
cx, FPBits::make_value(test5_5.get_explicit_mantissa(), 0).get_val());
160+
TEST_SPECIAL(cx, test5_5_val, 1, FE_INVALID);
161+
EXPECT_FP_EQ(cx, aNaN);
170162

171-
FPBits test5_6(UInt128(0x0000000008261001));
163+
FPBits test5_6(0x00000000'00000AB0'00000000'08261001_u128);
172164
const T test5_6_val = test5_6.get_val();
173-
TEST_SPECIAL(cx, test5_6_val, 0, 0);
174-
EXPECT_FP_EQ(
175-
cx, FPBits::make_value(test5_6.get_explicit_mantissa(), 0).get_val());
165+
TEST_SPECIAL(cx, test5_6_val, 1, FE_INVALID);
166+
EXPECT_FP_EQ(cx, aNaN);
176167
}
177168
}
178169

0 commit comments

Comments
 (0)