diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index b551efa42cc..046f8cd8675 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -114,6 +114,7 @@ add_benchmark(efficient_nonlocking_print src/efficient_nonlocking_print.cpp) add_benchmark(filesystem src/filesystem.cpp) add_benchmark(find_and_count src/find_and_count.cpp) add_benchmark(find_first_of src/find_first_of.cpp) +add_benchmark(has_single_bit src/has_single_bit.cpp) add_benchmark(iota src/iota.cpp) add_benchmark(locale_classic src/locale_classic.cpp) add_benchmark(minmax_element src/minmax_element.cpp) diff --git a/benchmarks/src/has_single_bit.cpp b/benchmarks/src/has_single_bit.cpp new file mode 100644 index 00000000000..7f2519e0a1c --- /dev/null +++ b/benchmarks/src/has_single_bit.cpp @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +#include + +using namespace std; + +template +void bm_has_single_bit_if(benchmark::State& state) { + const auto random_v = random_vector(8); + for (auto _ : state) { + benchmark::DoNotOptimize(random_v); + unsigned int count_true = 0; + unsigned int count_false = 0; + for (const auto& x : random_v) { + if (has_single_bit(x)) { + benchmark::DoNotOptimize(++count_true); + } else { + benchmark::DoNotOptimize(++count_false); + } + } + } +} + +template +void bm_has_single_bit(benchmark::State& state) { + const auto random_v = random_vector(8); + for (auto _ : state) { + benchmark::DoNotOptimize(random_v); + unsigned int r = 0; + for (const auto& x : random_v) { + r += has_single_bit(x); + } + benchmark::DoNotOptimize(r); + } +} + +BENCHMARK(bm_has_single_bit_if); +BENCHMARK(bm_has_single_bit_if); +BENCHMARK(bm_has_single_bit_if); +BENCHMARK(bm_has_single_bit_if); + +BENCHMARK(bm_has_single_bit); +BENCHMARK(bm_has_single_bit); +BENCHMARK(bm_has_single_bit); +BENCHMARK(bm_has_single_bit); + +BENCHMARK_MAIN(); diff --git a/stl/inc/bit b/stl/inc/bit index 9a73c616375..6d82d9bc106 100644 --- a/stl/inc/bit +++ b/stl/inc/bit @@ -84,7 +84,7 @@ _NODISCARD constexpr int countl_zero(_Ty _Val) noexcept; _EXPORT_STD template <_Standard_unsigned_integral _Ty> _NODISCARD constexpr bool has_single_bit(const _Ty _Val) noexcept { - return _Val != 0 && (_Val & (_Val - 1)) == 0; + return (_Val ^ (_Val - 1)) > _Val - 1; } inline void _Precondition_violation_in_bit_ceil() noexcept {}