Skip to content

Commit 73dfc7b

Browse files
authored
[libc] Fix a bug in fx_bits.h due to integer promotion of bitwise ops. (#83647)
1 parent 06ac828 commit 73dfc7b

File tree

2 files changed

+64
-15
lines changed

2 files changed

+64
-15
lines changed

libc/src/__support/fixed_point/fx_bits.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ bit_not(T x) {
126126
using BitType = typename FXRep<T>::StorageType;
127127
BitType x_bit = cpp::bit_cast<BitType>(x);
128128
// For some reason, bit_cast cannot deduce BitType from the input.
129-
return cpp::bit_cast<T, BitType>(~x_bit);
129+
return cpp::bit_cast<T, BitType>(static_cast<BitType>(~x_bit));
130130
}
131131

132132
template <typename T> LIBC_INLINE constexpr T abs(T x) {

libc/test/src/__support/fixed_point/fx_bits_test.cpp

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,22 @@ using LIBC_NAMESPACE::operator""_u16;
2020
using LIBC_NAMESPACE::operator""_u32;
2121
using LIBC_NAMESPACE::operator""_u64;
2222

23+
class LlvmLibcFxBitsTest : public LIBC_NAMESPACE::testing::Test {
24+
public:
25+
template <typename T> void testBitwiseOps() {
26+
EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_and(T(0.75), T(0.375)), T(0.25));
27+
EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_or(T(0.75), T(0.375)), T(0.875));
28+
using StorageType = typename FXRep<T>::StorageType;
29+
StorageType a = LIBC_NAMESPACE::cpp::bit_cast<StorageType>(T(0.75));
30+
a = ~a;
31+
EXPECT_EQ(LIBC_NAMESPACE::fixed_point::bit_not(T(0.75)),
32+
FXBits<T>(a).get_val());
33+
}
34+
};
35+
2336
// -------------------------------- SHORT TESTS --------------------------------
2437

25-
TEST(LlvmLibcFxBitsTest, FXBits_UnsignedShortFract) {
38+
TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedShortFract) {
2639
auto bits_var = FXBits<unsigned short fract>(0b00000000_u8);
2740

2841
EXPECT_EQ(bits_var.get_sign(), false);
@@ -51,9 +64,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_UnsignedShortFract) {
5164
EXPECT_EQ(bits_var.get_sign(), false);
5265
EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
5366
EXPECT_EQ(bits_var.get_fraction(), 0xcd_u8);
67+
68+
// Bitwise ops
69+
testBitwiseOps<unsigned short fract>();
5470
}
5571

56-
TEST(LlvmLibcFxBitsTest, FXBits_UnsignedShortAccum) {
72+
TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedShortAccum) {
5773
auto bits_var = FXBits<unsigned short accum>(0b00000000'00000000_u16);
5874

5975
EXPECT_EQ(bits_var.get_sign(), false);
@@ -77,9 +93,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_UnsignedShortAccum) {
7793
EXPECT_EQ(bits_var.get_sign(), false);
7894
EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16);
7995
EXPECT_EQ(bits_var.get_fraction(), 0x00fe_u16);
96+
97+
// Bitwise ops
98+
testBitwiseOps<unsigned short accum>();
8099
}
81100

82-
TEST(LlvmLibcFxBitsTest, FXBits_ShortFract) {
101+
TEST_F(LlvmLibcFxBitsTest, FXBits_ShortFract) {
83102
auto bits_var = FXBits<short fract>(0b0'0000000_u8);
84103

85104
EXPECT_EQ(bits_var.get_sign(), false);
@@ -103,9 +122,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_ShortFract) {
103122
EXPECT_EQ(bits_var.get_sign(), true);
104123
EXPECT_EQ(bits_var.get_integral(), 0x00_u8);
105124
EXPECT_EQ(bits_var.get_fraction(), 0x4d_u8);
125+
126+
// Bitwise ops
127+
testBitwiseOps<short fract>();
106128
}
107129

108-
TEST(LlvmLibcFxBitsTest, FXBits_ShortAccum) {
130+
TEST_F(LlvmLibcFxBitsTest, FXBits_ShortAccum) {
109131
auto bits_var = FXBits<short accum>(0b0'00000000'0000000_u16);
110132

111133
EXPECT_EQ(bits_var.get_sign(), false);
@@ -129,9 +151,14 @@ TEST(LlvmLibcFxBitsTest, FXBits_ShortAccum) {
129151
EXPECT_EQ(bits_var.get_sign(), true);
130152
EXPECT_EQ(bits_var.get_integral(), 0x00cd_u16);
131153
EXPECT_EQ(bits_var.get_fraction(), 0x007e_u16);
154+
155+
// Bitwise ops
156+
testBitwiseOps<short accum>();
132157
}
133158

134-
TEST(LlvmLibcFxBitsTest, FXBits_UnsignedFract) {
159+
// -------------------------------- NORMAL TESTS -------------------------------
160+
161+
TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedFract) {
135162
auto bits_var = FXBits<unsigned fract>(0b0000000000000000_u16);
136163

137164
EXPECT_EQ(bits_var.get_sign(), false);
@@ -155,11 +182,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_UnsignedFract) {
155182
EXPECT_EQ(bits_var.get_sign(), false);
156183
EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
157184
EXPECT_EQ(bits_var.get_fraction(), 0xef12_u16);
158-
}
159185

160-
// -------------------------------- NORMAL TESTS -------------------------------
186+
// Bitwise ops
187+
testBitwiseOps<unsigned fract>();
188+
}
161189

162-
TEST(LlvmLibcFxBitsTest, FXBits_UnsignedAccum) {
190+
TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedAccum) {
163191
auto bits_var =
164192
FXBits<unsigned accum>(0b0000000000000000'0000000000000000_u32);
165193

@@ -184,9 +212,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_UnsignedAccum) {
184212
EXPECT_EQ(bits_var.get_sign(), false);
185213
EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32);
186214
EXPECT_EQ(bits_var.get_fraction(), 0x0000ef12_u32);
215+
216+
// Bitwise ops
217+
testBitwiseOps<unsigned accum>();
187218
}
188219

189-
TEST(LlvmLibcFxBitsTest, FXBits_Fract) {
220+
TEST_F(LlvmLibcFxBitsTest, FXBits_Fract) {
190221
auto bits_var = FXBits<fract>(0b0'000000000000000_u16);
191222

192223
EXPECT_EQ(bits_var.get_sign(), false);
@@ -210,9 +241,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_Fract) {
210241
EXPECT_EQ(bits_var.get_sign(), true);
211242
EXPECT_EQ(bits_var.get_integral(), 0x0000_u16);
212243
EXPECT_EQ(bits_var.get_fraction(), 0x6f12_u16);
244+
245+
// Bitwise ops
246+
testBitwiseOps<fract>();
213247
}
214248

215-
TEST(LlvmLibcFxBitsTest, FXBits_Accum) {
249+
TEST_F(LlvmLibcFxBitsTest, FXBits_Accum) {
216250
auto bits_var = FXBits<accum>(0b0'0000000000000000'000000000000000_u32);
217251

218252
EXPECT_EQ(bits_var.get_sign(), false);
@@ -236,11 +270,14 @@ TEST(LlvmLibcFxBitsTest, FXBits_Accum) {
236270
EXPECT_EQ(bits_var.get_sign(), true);
237271
EXPECT_EQ(bits_var.get_integral(), 0x0000abcd_u32);
238272
EXPECT_EQ(bits_var.get_fraction(), 0x00006f12_u32);
273+
274+
// Bitwise ops
275+
testBitwiseOps<accum>();
239276
}
240277

241278
// --------------------------------- LONG TESTS --------------------------------
242279

243-
TEST(LlvmLibcFxBitsTest, FXBits_UnsignedLongFract) {
280+
TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedLongFract) {
244281
auto bits_var =
245282
FXBits<unsigned long fract>(0b00000000000000000000000000000000_u32);
246283

@@ -265,9 +302,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_UnsignedLongFract) {
265302
EXPECT_EQ(bits_var.get_sign(), false);
266303
EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
267304
EXPECT_EQ(bits_var.get_fraction(), 0xfedcba98_u32);
305+
306+
// Bitwise ops
307+
testBitwiseOps<unsigned long fract>();
268308
}
269309

270-
TEST(LlvmLibcFxBitsTest, FXBits_UnsignedLongAccum) {
310+
TEST_F(LlvmLibcFxBitsTest, FXBits_UnsignedLongAccum) {
271311
auto bits_var = FXBits<unsigned long accum>(
272312
0b00000000000000000000000000000000'00000000000000000000000000000000_u64);
273313

@@ -292,9 +332,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_UnsignedLongAccum) {
292332
EXPECT_EQ(bits_var.get_sign(), false);
293333
EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64);
294334
EXPECT_EQ(bits_var.get_fraction(), 0x00000000fedcba98_u64);
335+
336+
// Bitwise ops
337+
testBitwiseOps<unsigned long accum>();
295338
}
296339

297-
TEST(LlvmLibcFxBitsTest, FXBits_LongFract) {
340+
TEST_F(LlvmLibcFxBitsTest, FXBits_LongFract) {
298341
auto bits_var = FXBits<long fract>(0b0'0000000000000000000000000000000_u32);
299342

300343
EXPECT_EQ(bits_var.get_sign(), false);
@@ -318,9 +361,12 @@ TEST(LlvmLibcFxBitsTest, FXBits_LongFract) {
318361
EXPECT_EQ(bits_var.get_sign(), true);
319362
EXPECT_EQ(bits_var.get_integral(), 0x00000000_u32);
320363
EXPECT_EQ(bits_var.get_fraction(), 0x7edcba98_u32);
364+
365+
// Bitwise ops
366+
testBitwiseOps<long fract>();
321367
}
322368

323-
TEST(LlvmLibcFxBitsTest, FXBits_LongAccum) {
369+
TEST_F(LlvmLibcFxBitsTest, FXBits_LongAccum) {
324370
auto bits_var = FXBits<long accum>(
325371
0b0'00000000000000000000000000000000'0000000000000000000000000000000_u64);
326372

@@ -345,4 +391,7 @@ TEST(LlvmLibcFxBitsTest, FXBits_LongAccum) {
345391
EXPECT_EQ(bits_var.get_sign(), true);
346392
EXPECT_EQ(bits_var.get_integral(), 0x00000000abcdef12_u64);
347393
EXPECT_EQ(bits_var.get_fraction(), 0x000000007edcba98_u64);
394+
395+
// Bitwise ops
396+
testBitwiseOps<long accum>();
348397
}

0 commit comments

Comments
 (0)