Skip to content

Commit

Permalink
Fixes to ctz on Windows Clang.
Browse files Browse the repository at this point in the history
  • Loading branch information
mjp41 committed Aug 26, 2020
1 parent edaa35f commit 8c66d33
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 12 deletions.
30 changes: 18 additions & 12 deletions src/ds/bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
#include <atomic>
#include <cstdint>
#include <type_traits>
#if defined(_WIN32) && defined(__GNUC__)
# define USE_CLZLL
#endif
#ifdef pause
# undef pause
#endif
Expand Down Expand Up @@ -76,10 +73,15 @@ namespace snmalloc

return BITS - index - 1;
# endif
#elif defined(USE_CLZLL)
return static_cast<size_t>(__builtin_clzll(x));
#else
return static_cast<size_t>(__builtin_clzl(x));
#else
if constexpr (std::is_same_v<unsigned long, std::size_t>)
{
return __builtin_clzl(x);
}
else if constexpr (std::is_same_v<unsigned long long, std::size_t>)
{
return __builtin_clzll(x);
}
#endif
}

Expand Down Expand Up @@ -142,17 +144,21 @@ namespace snmalloc

inline size_t ctz(size_t x)
{
#if __has_builtin(__builtin_ctzl)
return static_cast<size_t>(__builtin_ctzl(x));
#elif defined(_MSC_VER)
#if defined(_MSC_VER)
# ifdef SNMALLOC_VA_BITS_64
return _tzcnt_u64(x);
# else
return _tzcnt_u32((uint32_t)x);
# endif
#else
// Probably GCC at this point.
return static_cast<size_t>(__builtin_ctzl(x));
if constexpr (std::is_same_v<unsigned long, std::size_t>)
{
return __builtin_ctzl(x);
}
else if constexpr (std::is_same_v<unsigned long long, std::size_t>)
{
return __builtin_ctzll(x);
}
#endif
}

Expand Down
43 changes: 43 additions & 0 deletions src/test/func/bits/bits.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Unit tests for operations in bits.h
*/

#include <iostream>
#include <test/setup.h>
#include <ds/bits.h>

void
test_ctz()
{
for (size_t i = 0; i < sizeof(size_t) * 8; i++)
if (snmalloc::bits::ctz(snmalloc::bits::one_at_bit(i)) != i)
{
std::cout << "Failed with ctz(one_at_bit(i)) != i for i=" << i << std::endl;
abort();
}
}


void
test_clz()
{
const size_t PTRSIZE_LOG = sizeof(size_t) * 8;

for (size_t i = 0; i < sizeof(size_t) * 8; i++)
if (snmalloc::bits::clz(snmalloc::bits::one_at_bit(i)) != (PTRSIZE_LOG - i - 1))
{
std::cout << "Failed with clz(one_at_bit(i)) != (PTRSIZE_LOG - i - 1) for i=" << i << std::endl;
abort();
}
}

int main(int argc, char** argv)
{
UNUSED(argc);
UNUSED(argv);

setup();

test_clz();
test_ctz();
}

0 comments on commit 8c66d33

Please sign in to comment.