diff options
author | Pauli Nieminen <[email protected]> | 2010-02-14 14:16:20 +0200 |
---|---|---|
committer | Pauli Nieminen <[email protected]> | 2010-02-14 19:55:58 +0200 |
commit | 6e958832afe9544973528bed78dd3a340b8686f3 (patch) | |
tree | a4e63d1468fc8854649bfc3afc33d04eb4b36fc4 /src | |
parent | 7344e20ce4a333bfd8ab142cfdf98098e16b001d (diff) |
mesa: Don't pass paramter to __builtin_clz which would hve undefined result.
__builtin_clz with parameter 0 has undefined value. When
using -O3 optimizing this would result to too large next
power of two value.
Fix is to check if passed value is 1 and modify formula
for that case.
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/main/imports.h | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 3843f50036c..e3d2ac9b427 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -412,13 +412,19 @@ _mesa_is_pow_two(int x) * Source for the fallback implementation is * Sean Eron Anderson's webpage "Bit Twiddling Hacks" * http://graphics.stanford.edu/~seander/bithacks.html + * + * When using builtin function have to do some work + * for case when passed values 1 to prevent hiting + * undefined result from __builtin_clz. Undefined + * results would be different depending on optimization + * level used for build. */ static INLINE int32_t _mesa_next_pow_two_32(uint32_t x) { #ifdef __GNUC__ - x--; - return 1 << ((__builtin_clz(x) ^ 31) + 1); + uint32_t y = (x != 1); + return (1 + y) << ((__builtin_clz(x - y) ^ 31) ); #else x--; x |= x >> 1; @@ -435,11 +441,11 @@ static INLINE int64_t _mesa_next_pow_two_64(uint64_t x) { #ifdef __GNUC__ - x--; + uint64_t y = (x != 1); if (sizeof(x) == sizeof(long)) - return 1 << ((__builtin_clzl(x) ^ 63) + 1); + return (1 + y) << ((__builtin_clzl(x - y) ^ 63)); else - return 1 << ((__builtin_clzll(x) ^ 63) + 1); + return (1 + y) << ((__builtin_clzll(x - y) ^ 63)); #else x--; x |= x >> 1; |