Skip to content

Commit 204b0cb

Browse files
committed
1 parent 2cb82e2 commit 204b0cb

File tree

1 file changed

+60
-26
lines changed

1 file changed

+60
-26
lines changed

src/include/port/pg_bitutils.h

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,27 @@ static inline int
2626
pg_leftmost_one_pos32(uint32 word)
2727
{
2828
#ifdef HAVE__BUILTIN_CLZ
29-
Assert(word != 0);
29+
int bitscan_result;
30+
#endif
3031

31-
return 31 - __builtin_clz(word);
32-
#else
32+
#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING)
33+
int result;
3334
int shift = 32 - 8;
3435

3536
Assert(word != 0);
3637

3738
while ((word >> shift) == 0)
3839
shift -= 8;
3940

40-
return shift + pg_leftmost_one_pos[(word >> shift) & 255];
41+
result = shift + pg_leftmost_one_pos[(word >> shift) & 255];
42+
#endif
43+
44+
#if defined(HAVE__BUILTIN_CLZ)
45+
bitscan_result = 31 - __builtin_clz(word);
46+
Assert(bitscan_result == result);
47+
return bitscan_result;
48+
#else
49+
return result;
4150
#endif /* HAVE__BUILTIN_CLZ */
4251
}
4352

@@ -49,24 +58,33 @@ static inline int
4958
pg_leftmost_one_pos64(uint64 word)
5059
{
5160
#ifdef HAVE__BUILTIN_CLZ
52-
Assert(word != 0);
53-
54-
#if defined(HAVE_LONG_INT_64)
55-
return 63 - __builtin_clzl(word);
56-
#elif defined(HAVE_LONG_LONG_INT_64)
57-
return 63 - __builtin_clzll(word);
58-
#else
59-
#error must have a working 64-bit integer datatype
61+
int bitscan_result;
6062
#endif
61-
#else /* !HAVE__BUILTIN_CLZ */
63+
64+
#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING)
65+
int result;
6266
int shift = 64 - 8;
6367

6468
Assert(word != 0);
6569

6670
while ((word >> shift) == 0)
6771
shift -= 8;
6872

69-
return shift + pg_leftmost_one_pos[(word >> shift) & 255];
73+
result = shift + pg_leftmost_one_pos[(word >> shift) & 255];
74+
#endif
75+
76+
#if defined(HAVE__BUILTIN_CLZ)
77+
#if defined(HAVE_LONG_INT_64)
78+
bitscan_result = 63 - __builtin_clzl(word);
79+
#elif defined(HAVE_LONG_LONG_INT_64)
80+
bitscan_result = 63 - __builtin_clzll(word);
81+
#else
82+
#error must have a working 64-bit integer datatype
83+
#endif /* HAVE_LONG_INT_64 */
84+
Assert(bitscan_result == result);
85+
return bitscan_result;
86+
#else
87+
return result;
7088
#endif /* HAVE__BUILTIN_CLZ */
7189
}
7290

@@ -79,10 +97,11 @@ static inline int
7997
pg_rightmost_one_pos32(uint32 word)
8098
{
8199
#ifdef HAVE__BUILTIN_CTZ
82-
Assert(word != 0);
100+
const uint32 orig_word = word;
101+
int bitscan_result;
102+
#endif
83103

84-
return __builtin_ctz(word);
85-
#else
104+
#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING)
86105
int result = 0;
87106

88107
Assert(word != 0);
@@ -93,6 +112,13 @@ pg_rightmost_one_pos32(uint32 word)
93112
result += 8;
94113
}
95114
result += pg_rightmost_one_pos[word & 255];
115+
#endif
116+
117+
#if defined(HAVE__BUILTIN_CTZ)
118+
bitscan_result = __builtin_ctz(orig_word);
119+
Assert(bitscan_result == result);
120+
return bitscan_result;
121+
#else
96122
return result;
97123
#endif /* HAVE__BUILTIN_CTZ */
98124
}
@@ -105,16 +131,11 @@ static inline int
105131
pg_rightmost_one_pos64(uint64 word)
106132
{
107133
#ifdef HAVE__BUILTIN_CTZ
108-
Assert(word != 0);
109-
110-
#if defined(HAVE_LONG_INT_64)
111-
return __builtin_ctzl(word);
112-
#elif defined(HAVE_LONG_LONG_INT_64)
113-
return __builtin_ctzll(word);
114-
#else
115-
#error must have a working 64-bit integer datatype
134+
const uint64 orig_word = word;
135+
int bitscan_result;
116136
#endif
117-
#else /* !HAVE__BUILTIN_CTZ */
137+
138+
#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING)
118139
int result = 0;
119140

120141
Assert(word != 0);
@@ -125,6 +146,19 @@ pg_rightmost_one_pos64(uint64 word)
125146
result += 8;
126147
}
127148
result += pg_rightmost_one_pos[word & 255];
149+
#endif
150+
151+
#if defined(HAVE__BUILTIN_CTZ)
152+
#if defined(HAVE_LONG_INT_64)
153+
bitscan_result = __builtin_ctzl(orig_word);
154+
#elif defined(HAVE_LONG_LONG_INT_64)
155+
bitscan_result = __builtin_ctzll(orig_word);
156+
#else
157+
#error must have a working 64-bit integer datatype
158+
#endif /* HAVE_LONG_INT_64 */
159+
Assert(bitscan_result == result);
160+
return bitscan_result;
161+
#else
128162
return result;
129163
#endif /* HAVE__BUILTIN_CTZ */
130164
}

0 commit comments

Comments
 (0)