diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h index a49a9c03d92..a5df4f1a355 100644 --- a/src/include/port/pg_bitutils.h +++ b/src/include/port/pg_bitutils.h @@ -26,10 +26,11 @@ static inline int pg_leftmost_one_pos32(uint32 word) { #ifdef HAVE__BUILTIN_CLZ - Assert(word != 0); + int bitscan_result; +#endif - return 31 - __builtin_clz(word); -#else +#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING) + int result; int shift = 32 - 8; Assert(word != 0); @@ -37,7 +38,15 @@ pg_leftmost_one_pos32(uint32 word) while ((word >> shift) == 0) shift -= 8; - return shift + pg_leftmost_one_pos[(word >> shift) & 255]; + result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; +#endif + +#if defined(HAVE__BUILTIN_CLZ) + bitscan_result = 31 - __builtin_clz(word); + Assert(bitscan_result == result); + return bitscan_result; +#else + return result; #endif /* HAVE__BUILTIN_CLZ */ } @@ -49,16 +58,11 @@ static inline int pg_leftmost_one_pos64(uint64 word) { #ifdef HAVE__BUILTIN_CLZ - Assert(word != 0); - -#if defined(HAVE_LONG_INT_64) - return 63 - __builtin_clzl(word); -#elif defined(HAVE_LONG_LONG_INT_64) - return 63 - __builtin_clzll(word); -#else -#error must have a working 64-bit integer datatype + int bitscan_result; #endif -#else /* !HAVE__BUILTIN_CLZ */ + +#if !defined(HAVE__BUILTIN_CLZ) || defined(USE_ASSERT_CHECKING) + int result; int shift = 64 - 8; Assert(word != 0); @@ -66,7 +70,21 @@ pg_leftmost_one_pos64(uint64 word) while ((word >> shift) == 0) shift -= 8; - return shift + pg_leftmost_one_pos[(word >> shift) & 255]; + result = shift + pg_leftmost_one_pos[(word >> shift) & 255]; +#endif + +#if defined(HAVE__BUILTIN_CLZ) +#if defined(HAVE_LONG_INT_64) + bitscan_result = 63 - __builtin_clzl(word); +#elif defined(HAVE_LONG_LONG_INT_64) + bitscan_result = 63 - __builtin_clzll(word); +#else +#error must have a working 64-bit integer datatype +#endif /* HAVE_LONG_INT_64 */ + Assert(bitscan_result == result); + return bitscan_result; +#else + return result; #endif /* HAVE__BUILTIN_CLZ */ } @@ -79,10 +97,11 @@ static inline int pg_rightmost_one_pos32(uint32 word) { #ifdef HAVE__BUILTIN_CTZ - Assert(word != 0); + const uint32 orig_word = word; + int bitscan_result; +#endif - return __builtin_ctz(word); -#else +#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING) int result = 0; Assert(word != 0); @@ -93,6 +112,13 @@ pg_rightmost_one_pos32(uint32 word) result += 8; } result += pg_rightmost_one_pos[word & 255]; +#endif + +#if defined(HAVE__BUILTIN_CTZ) + bitscan_result = __builtin_ctz(orig_word); + Assert(bitscan_result == result); + return bitscan_result; +#else return result; #endif /* HAVE__BUILTIN_CTZ */ } @@ -105,16 +131,11 @@ static inline int pg_rightmost_one_pos64(uint64 word) { #ifdef HAVE__BUILTIN_CTZ - Assert(word != 0); - -#if defined(HAVE_LONG_INT_64) - return __builtin_ctzl(word); -#elif defined(HAVE_LONG_LONG_INT_64) - return __builtin_ctzll(word); -#else -#error must have a working 64-bit integer datatype + const uint64 orig_word = word; + int bitscan_result; #endif -#else /* !HAVE__BUILTIN_CTZ */ + +#if !defined(HAVE__BUILTIN_CTZ) || defined(USE_ASSERT_CHECKING) int result = 0; Assert(word != 0); @@ -125,6 +146,19 @@ pg_rightmost_one_pos64(uint64 word) result += 8; } result += pg_rightmost_one_pos[word & 255]; +#endif + +#if defined(HAVE__BUILTIN_CTZ) +#if defined(HAVE_LONG_INT_64) + bitscan_result = __builtin_ctzl(orig_word); +#elif defined(HAVE_LONG_LONG_INT_64) + bitscan_result = __builtin_ctzll(orig_word); +#else +#error must have a working 64-bit integer datatype +#endif /* HAVE_LONG_INT_64 */ + Assert(bitscan_result == result); + return bitscan_result; +#else return result; #endif /* HAVE__BUILTIN_CTZ */ }