cpu_detect: Add BMI2 detection PiperOrigin-RevId: 936046570 Change-Id: Ib79a392eee5ed11898ef1d98e2d6bbdfb3c72eab
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 53bac42..ea4db17 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel
@@ -768,6 +768,20 @@ ) cc_test( + name = "cpu_detect_test", + size = "small", + srcs = ["internal/cpu_detect_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":config", + ":cpu_detect", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) + +cc_test( name = "low_level_alloc_test", size = "medium", srcs = ["internal/low_level_alloc_test.cc"],
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 8d5cf66..2a20d74 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt
@@ -637,6 +637,19 @@ absl_cc_test( NAME + cpu_detect_test + SRCS + "internal/cpu_detect_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::base_cpu_detect + absl::config + GTest::gtest_main +) + +absl_cc_test( + NAME low_level_alloc_test SRCS "internal/low_level_alloc_test.cc"
diff --git a/absl/base/internal/cpu_detect.cc b/absl/base/internal/cpu_detect.cc index c08637c..5275888 100644 --- a/absl/base/internal/cpu_detect.cc +++ b/absl/base/internal/cpu_detect.cc
@@ -253,6 +253,16 @@ bool SupportsArmCRC32PMULL() { return false; } +bool SupportsBmi2() { + int cpu_info[4]; + __cpuid(cpu_info, 0); + if (cpu_info[0] < 7) { + return false; + } + __cpuidex(cpu_info, 7, 0); + return (cpu_info[1] & (1 << 8)) != 0; +} + #elif defined(__aarch64__) && defined(__linux__) #ifndef HWCAP_CPUID @@ -322,6 +332,8 @@ #endif } +bool SupportsBmi2() { return false; } + #elif defined(__aarch64__) && defined(__APPLE__) CpuType GetCpuType() { return CpuType::kUnknown; } @@ -365,12 +377,16 @@ return true; } +bool SupportsBmi2() { return false; } + #else CpuType GetCpuType() { return CpuType::kUnknown; } bool SupportsArmCRC32PMULL() { return false; } +bool SupportsBmi2() { return false; } + #endif // Returns how many hardware contexts per CPU exist. Note: AMD CPUs prior to Zen
diff --git a/absl/base/internal/cpu_detect.h b/absl/base/internal/cpu_detect.h index 5ea76ec..43c7c38 100644 --- a/absl/base/internal/cpu_detect.h +++ b/absl/base/internal/cpu_detect.h
@@ -63,6 +63,9 @@ // tuning. bool SupportsArmCRC32PMULL(); +// Returns whether the host CPU supports BMI2 instructions. +bool SupportsBmi2(); + // Returns whether the host CPU supports simultaneous multithreading (SMT) and // if it is enabled. bool IsSMTEnabled();
diff --git a/absl/base/internal/cpu_detect_test.cc b/absl/base/internal/cpu_detect_test.cc new file mode 100644 index 0000000..80b8b87 --- /dev/null +++ b/absl/base/internal/cpu_detect_test.cc
@@ -0,0 +1,43 @@ +// Copyright 2026 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/base/internal/cpu_detect.h" + +#include "gtest/gtest.h" +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { +namespace { + +TEST(CpuDetectTest, SupportsBmi2) { +#if defined(__x86_64__) || defined(_M_X64) +#if ABSL_HAVE_BUILTIN(__builtin_cpu_supports) && defined(__linux__) + EXPECT_EQ(SupportsBmi2(), __builtin_cpu_supports("bmi2") != 0); +#else + // If __builtin_cpu_supports is not available, we just verify it doesn't + // crash. + (void)SupportsBmi2(); +#endif +#else + // On non-x86, SupportsBmi2() must return false. + EXPECT_FALSE(SupportsBmi2()); +#endif +} + +} // namespace +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl