diff options
| author | 2015-08-13 20:55:31 -0700 | |
|---|---|---|
| committer | 2015-08-13 21:29:48 -0700 | |
| commit | 51db2c217052fd6881b81f3ac5162fe88c36dbf0 (patch) | |
| tree | 14d724a828b5ba00889160c2b42095273b7d593c /runtime/base/bit_utils.h | |
| parent | 060841a3966afc7a5251134d1f1ef100849b1468 (diff) | |
ART: DCHECK zero case for CLZ/CTZ
Add a DCHECK_CONSTEXPR. All current callers have an explicit
zero check before hand and so we should not trip this at the
moment. Remove the TODO.
Add the check for T being unsigned for CLZ (trivial fix for
leb128.h). We use CTZ with signed types.
Change-Id: I7bbf0b1699eed21715c6cc20dbfe22b7da403b1a
Diffstat (limited to 'runtime/base/bit_utils.h')
| -rw-r--r-- | runtime/base/bit_utils.h | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/runtime/base/bit_utils.h b/runtime/base/bit_utils.h index 6f45dc8209..332012bda9 100644 --- a/runtime/base/bit_utils.h +++ b/runtime/base/bit_utils.h @@ -29,21 +29,28 @@ namespace art { template<typename T> static constexpr int CLZ(T x) { static_assert(std::is_integral<T>::value, "T must be integral"); - // TODO: assert unsigned. There is currently many uses with signed values. + static_assert(std::is_unsigned<T>::value, "T must be unsigned"); static_assert(sizeof(T) <= sizeof(long long), // NOLINT [runtime/int] [4] "T too large, must be smaller than long long"); - return (sizeof(T) == sizeof(uint32_t)) - ? __builtin_clz(x) // TODO: __builtin_clz[ll] has undefined behavior for x=0 - : __builtin_clzll(x); + return + DCHECK_CONSTEXPR(x != 0, "x must not be zero", T(0)) + (sizeof(T) == sizeof(uint32_t)) + ? __builtin_clz(x) + : __builtin_clzll(x); } template<typename T> static constexpr int CTZ(T x) { static_assert(std::is_integral<T>::value, "T must be integral"); - // TODO: assert unsigned. There is currently many uses with signed values. - return (sizeof(T) == sizeof(uint32_t)) - ? __builtin_ctz(x) - : __builtin_ctzll(x); + // A similar check to the above does not make sense. It isn't as non-intuitive to ask for + // trailing zeros in a negative number, and the quick backends do this for immediate encodings. + static_assert(sizeof(T) <= sizeof(long long), // NOLINT [runtime/int] [4] + "T too large, must be smaller than long long"); + return + DCHECK_CONSTEXPR(x != 0, "x must not be zero", T(0)) + (sizeof(T) == sizeof(uint32_t)) + ? __builtin_ctz(x) + : __builtin_ctzll(x); } template<typename T> |