From: Marco Bettini Date: Mon, 29 Nov 2021 14:00:41 +0000 (+0100) Subject: bits_is_power_of_two() Replace signed expression with __builtin_popcountl() X-Git-Tag: 2.3.18~102 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bf9c2cb8b5864cc58193237ce861b588ba0bd9cf;p=thirdparty%2Fdovecot%2Fcore.git bits_is_power_of_two() Replace signed expression with __builtin_popcountl() Found by code analysis tool --- diff --git a/src/lib/bits.h b/src/lib/bits.h index 586b166e76..3b761f11b6 100644 --- a/src/lib/bits.h +++ b/src/lib/bits.h @@ -20,14 +20,15 @@ /* Returns x, such that x is the smallest power of 2 >= num. */ size_t nearest_power(size_t num) ATTR_CONST; +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) + /* Returns TRUE if 2^x=num, i.e. if num has only a single bit set to 1. */ static inline bool ATTR_CONST bits_is_power_of_two(uint64_t num) { - return num > 0 && (num & (num - 1)) == 0; + return __builtin_popcountll(num) == 1; } -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) static inline unsigned int ATTR_CONST bits_required32(uint32_t num) { @@ -44,7 +45,16 @@ bits_required64(uint64_t num) { return num == 0 ? 0 : 64 - __builtin_clzll(num); } + #else + +/* Returns TRUE if 2^x=num, i.e. if num has only a single bit set to 1. */ +static inline bool ATTR_CONST +bits_is_power_of_two(uint64_t num) +{ + return num != 0 && (num & (num + ~0ULL)) == 0; +} + unsigned int bits_required8(uint8_t num) ATTR_CONST; static inline @@ -65,6 +75,7 @@ unsigned int bits_required64(uint64_t num) return (num <= 0xffffffff) ? bits_required32(num) : 32 + bits_required32(num >> 32); } + #endif static inline uint64_t ATTR_NO_SANITIZE_INTEGER diff --git a/src/lib/test-bits.c b/src/lib/test-bits.c index 5bdd5a50b8..c43209aa6b 100644 --- a/src/lib/test-bits.c +++ b/src/lib/test-bits.c @@ -50,6 +50,7 @@ static void test_bits_is_power_of_two(void) } test_assert(!bits_is_power_of_two(0)); test_assert(!bits_is_power_of_two(0xffffffffffffffffULL)); + test_assert( bits_is_power_of_two(0x8000000000000000ULL)); test_end(); }