[libc-commits] [libc] [llvm] Revert "[libc][NFC] Remove __support/bit.h and use __support/CPP/bit.h instead" (PR #74444)

via libc-commits libc-commits at lists.llvm.org
Tue Dec 5 02:26:01 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Guillaume Chatelet (gchatelet)

<details>
<summary>Changes</summary>

Reverts llvm/llvm-project#<!-- -->73939

This broke libc-aarch64-ubuntu build bot 
https://lab.llvm.org/buildbot/#/builders/138/builds/56186

---

Patch is 46.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74444.diff


31 Files Affected:

- (modified) libc/src/__support/CMakeLists.txt (+4-5) 
- (modified) libc/src/__support/FPUtil/CMakeLists.txt (+2) 
- (modified) libc/src/__support/FPUtil/FPBits.h (+2-1) 
- (modified) libc/src/__support/FPUtil/Hypot.h (+4-7) 
- (modified) libc/src/__support/FPUtil/generic/CMakeLists.txt (+3-2) 
- (modified) libc/src/__support/FPUtil/generic/FMA.h (+4-4) 
- (modified) libc/src/__support/FPUtil/generic/FMod.h (+4-4) 
- (modified) libc/src/__support/FPUtil/generic/sqrt.h (+7-6) 
- (modified) libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h (+3-3) 
- (modified) libc/src/__support/HashTable/CMakeLists.txt (+6-6) 
- (modified) libc/src/__support/HashTable/bitmask.h (+2-2) 
- (modified) libc/src/__support/HashTable/table.h (+3-4) 
- (modified) libc/src/__support/UInt.h (+2-2) 
- (added) libc/src/__support/bit.h (+117) 
- (modified) libc/src/__support/hash.h (+4-5) 
- (modified) libc/src/__support/integer_utils.h (+1) 
- (modified) libc/src/__support/memory_size.h (+3-14) 
- (modified) libc/src/__support/str_to_float.h (+3-2) 
- (modified) libc/src/math/generic/CMakeLists.txt (+1) 
- (modified) libc/src/math/generic/powf.cpp (+3-2) 
- (modified) libc/src/string/memory_utils/op_builtin.h (+9-13) 
- (modified) libc/src/string/memory_utils/utils.h (+39-8) 
- (modified) libc/test/src/__support/CMakeLists.txt (+13) 
- (modified) libc/test/src/__support/HashTable/table_test.cpp (+1-2) 
- (added) libc/test/src/__support/bit_test.cpp (+67) 
- (modified) libc/test/src/__support/memory_size_test.cpp (-11) 
- (modified) libc/test/src/search/hsearch_test.cpp (+2-2) 
- (modified) libc/test/src/string/memory_utils/utils_test.cpp (+60) 
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+17-2) 
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel (+6) 
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/libc_math_test_rules.bzl (+1) 


``````````diff
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 502bf72ae9906..d6dbad661cb73 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -135,13 +135,13 @@ add_header_library(
     .str_to_num_result
     .uint128
     libc.src.__support.common
-    libc.src.__support.CPP.bit
     libc.src.__support.CPP.limits
     libc.src.__support.CPP.optional
     libc.src.__support.FPUtil.dyadic_float
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.rounding_mode
+    libc.src.__support.bit
     libc.src.errno.errno
 )
 
@@ -188,10 +188,10 @@ add_header_library(
   HDRS
     integer_utils.h
   DEPENDS
+    .bit
     .math_extras
     .number_pair
     libc.src.__support.common
-    libc.src.__support.CPP.bit
     libc.src.__support.CPP.type_traits
 )
 
@@ -200,11 +200,11 @@ add_header_library(
   HDRS
     UInt.h
   DEPENDS
+    .bit
     .integer_utils
     .math_extras
     .number_pair
     libc.src.__support.CPP.array
-    libc.src.__support.CPP.bit
     libc.src.__support.CPP.type_traits
     libc.src.__support.macros.optimization
 )
@@ -231,9 +231,8 @@ add_header_library(
   HDRS
     hash.h
   DEPENDS
+    .bit
     .uint128
-    libc.src.__support.CPP.bit
-    libc.src.__support.CPP.limits
     libc.src.__support.macros.attributes
 )
 
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 3d6d712fc2058..58a182eaa797b 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -41,6 +41,7 @@ add_header_library(
     libc.src.__support.common
     libc.src.__support.CPP.bit
     libc.src.__support.CPP.type_traits
+    libc.src.__support.bit
 )
 
 add_header_library(
@@ -145,6 +146,7 @@ add_header_library(
     libc.src.__support.common
     libc.src.__support.CPP.bit
     libc.src.__support.CPP.type_traits
+    libc.src.__support.bit
     libc.src.__support.uint128
 )
 
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index ca98aa7126249..f5b73440de215 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -11,6 +11,7 @@
 
 #include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
+#include "src/__support/bit.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/attributes.h" // LIBC_INLINE
 
@@ -221,7 +222,7 @@ template <typename T> struct FPBits {
   LIBC_INLINE static constexpr FPBits<T> make_value(UIntType number, int ep) {
     FPBits<T> result;
     // offset: +1 for sign, but -1 for implicit first bit
-    int lz = cpp::countl_zero(number) - FloatProp::EXPONENT_WIDTH;
+    int lz = unsafe_clz(number) - FloatProp::EXPONENT_WIDTH;
     number <<= lz;
     ep -= lz;
 
diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h
index 8a6eb4b920acd..db2a62fbdf2a1 100644
--- a/libc/src/__support/FPUtil/Hypot.h
+++ b/libc/src/__support/FPUtil/Hypot.h
@@ -16,6 +16,7 @@
 #include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/UInt128.h"
+#include "src/__support/bit.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
@@ -27,7 +28,7 @@ template <typename T>
 LIBC_INLINE T find_leading_one(T mant, int &shift_length) {
   shift_length = 0;
   if (mant > 0) {
-    shift_length = (sizeof(mant) * 8) - 1 - cpp::countl_zero(mant);
+    shift_length = (sizeof(mant) * 8) - 1 - unsafe_clz(mant);
   }
   return T(1) << shift_length;
 }
@@ -36,13 +37,9 @@ LIBC_INLINE T find_leading_one(T mant, int &shift_length) {
 
 template <typename T> struct DoubleLength;
 
-template <> struct DoubleLength<uint16_t> {
-  using Type = uint32_t;
-};
+template <> struct DoubleLength<uint16_t> { using Type = uint32_t; };
 
-template <> struct DoubleLength<uint32_t> {
-  using Type = uint64_t;
-};
+template <> struct DoubleLength<uint32_t> { using Type = uint64_t; };
 
 template <> struct DoubleLength<uint64_t> {
   using Type = UInt128;
diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt
index b17f325210473..c799d502b47d6 100644
--- a/libc/src/__support/FPUtil/generic/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt
@@ -11,6 +11,7 @@ add_header_library(
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.rounding_mode
+    libc.src.__support.bit
     libc.src.__support.uint128
 )
 
@@ -20,13 +21,13 @@ add_header_library(
     FMA.h
   DEPENDS
     libc.src.__support.common
-    libc.src.__support.CPP.bit
     libc.src.__support.CPP.type_traits
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.float_properties
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.macros.optimization
+    libc.src.__support.bit
     libc.src.__support.uint128
 )
 
@@ -36,12 +37,12 @@ add_header_library(
     FMod.h
   DEPENDS
     libc.src.__support.common
-    libc.src.__support.CPP.bit
     libc.src.__support.CPP.type_traits
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.float_properties
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.macros.optimization
+    libc.src.__support.bit
     libc.src.math.generic.math_utils
 )
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index 4a825f2f4942c..5a856d1447330 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -9,13 +9,13 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_FMA_H
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_FMA_H
 
-#include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/FloatProperties.h"
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/UInt128.h"
+#include "src/__support/bit.h"
 #include "src/__support/macros/attributes.h"   // LIBC_INLINE
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
@@ -209,9 +209,9 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
   // Normalize the result.
   if (prod_mant != 0) {
     uint64_t prod_hi = static_cast<uint64_t>(prod_mant >> 64);
-    int lead_zeros =
-        prod_hi ? cpp::countl_zero(prod_hi)
-                : 64 + cpp::countl_zero(static_cast<uint64_t>(prod_mant));
+    int lead_zeros = prod_hi
+                         ? unsafe_clz(prod_hi)
+                         : 64 + unsafe_clz(static_cast<uint64_t>(prod_mant));
     // Move the leading 1 to the most significant bit.
     prod_mant <<= lead_zeros;
     // The lower 64 bits are always sticky bits after moving the leading 1 to
diff --git a/libc/src/__support/FPUtil/generic/FMod.h b/libc/src/__support/FPUtil/generic/FMod.h
index 0e71b039d5c06..6f934cd4a87bd 100644
--- a/libc/src/__support/FPUtil/generic/FMod.h
+++ b/libc/src/__support/FPUtil/generic/FMod.h
@@ -9,11 +9,11 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_FMOD_H
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_FMOD_H
 
-#include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/limits.h"
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/bit.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 #include "src/math/generic/math_utils.h"
 
@@ -229,7 +229,7 @@ class FMod {
 
     if (LIBC_LIKELY(sx.uintval() <= sy.uintval())) {
       if (sx.uintval() < sy.uintval())
-        return sx;             // |x|<|y| return x
+        return sx;        // |x|<|y| return x
       return FPB(FPB::zero()); // |x|=|y| return 0.0
     }
 
@@ -264,11 +264,11 @@ class FMod {
       e_y--;
     } else {
       m_y = sy.get_mantissa();
-      lead_zeros_m_y = cpp::countl_zero(m_y);
+      lead_zeros_m_y = unsafe_clz(m_y);
     }
 
     // Assume hy != 0
-    int tail_zeros_m_y = cpp::countr_zero(m_y);
+    int tail_zeros_m_y = unsafe_ctz(m_y);
     int sides_zeroes_count = lead_zeros_m_y + tail_zeros_m_y;
     // n > 0 by conditions above
     int exp_diff = e_x - e_y;
diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h
index 6ae2171bacf7b..b93fa7a35f826 100644
--- a/libc/src/__support/FPUtil/generic/sqrt.h
+++ b/libc/src/__support/FPUtil/generic/sqrt.h
@@ -10,12 +10,13 @@
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_SQRT_H
 
 #include "sqrt_80_bit_long_double.h"
-#include "src/__support/CPP/bit.h" // countl_zero
+#include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/UInt128.h"
+#include "src/__support/bit.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
@@ -36,7 +37,7 @@ template <> struct SpecialLongDouble<long double> {
 template <typename T>
 LIBC_INLINE void normalize(int &exponent,
                            typename FPBits<T>::UIntType &mantissa) {
-  const int shift = cpp::countl_zero(mantissa) -
+  const int shift = unsafe_clz(mantissa) -
                     (8 * sizeof(mantissa) - 1 - MantissaWidth<T>::VALUE);
   exponent -= shift;
   mantissa <<= shift;
@@ -51,9 +52,9 @@ LIBC_INLINE void normalize<long double>(int &exponent, uint64_t &mantissa) {
 template <>
 LIBC_INLINE void normalize<long double>(int &exponent, UInt128 &mantissa) {
   const uint64_t hi_bits = static_cast<uint64_t>(mantissa >> 64);
-  const int shift =
-      hi_bits ? (cpp::countl_zero(hi_bits) - 15)
-              : (cpp::countl_zero(static_cast<uint64_t>(mantissa)) + 49);
+  const int shift = hi_bits
+                        ? (unsafe_clz(hi_bits) - 15)
+                        : (unsafe_clz(static_cast<uint64_t>(mantissa)) + 49);
   exponent -= shift;
   mantissa <<= shift;
 }
@@ -136,7 +137,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
 
       // We compute one more iteration in order to round correctly.
       bool lsb = static_cast<bool>(y & 1); // Least significant bit
-      bool rb = false;                     // Round bit
+      bool rb = false;  // Round bit
       r <<= 2;
       UIntType tmp = (y << 2) + 1;
       if (r >= tmp) {
diff --git a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
index 0e7907e82943a..a3bf7e3cabad3 100644
--- a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
+++ b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
@@ -9,11 +9,11 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_SQRT_80_BIT_LONG_DOUBLE_H
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_SQRT_80_BIT_LONG_DOUBLE_H
 
-#include "src/__support/CPP/bit.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/UInt128.h"
+#include "src/__support/bit.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
@@ -22,7 +22,7 @@ namespace x86 {
 
 LIBC_INLINE void normalize(int &exponent, UInt128 &mantissa) {
   const unsigned int shift = static_cast<unsigned int>(
-      cpp::countl_zero(static_cast<uint64_t>(mantissa)) -
+      unsafe_clz(static_cast<uint64_t>(mantissa)) -
       (8 * sizeof(uint64_t) - 1 - MantissaWidth<long double>::VALUE));
   exponent -= shift;
   mantissa <<= shift;
@@ -101,7 +101,7 @@ LIBC_INLINE long double sqrt(long double x) {
 
     // We compute one more iteration in order to round correctly.
     bool lsb = static_cast<bool>(y & 1); // Least significant bit
-    bool rb = false;                     // Round bit
+    bool rb = false;  // Round bit
     r <<= 2;
     UIntType tmp = (y << 2) + 1;
     if (r >= tmp) {
diff --git a/libc/src/__support/HashTable/CMakeLists.txt b/libc/src/__support/HashTable/CMakeLists.txt
index 920ba194badd9..e9b4aa31290a1 100644
--- a/libc/src/__support/HashTable/CMakeLists.txt
+++ b/libc/src/__support/HashTable/CMakeLists.txt
@@ -6,7 +6,7 @@ add_header_library(
     PREFER_GENERIC
   DEPENDS
     libc.src.__support.common
-    libc.src.__support.CPP.bit
+    libc.src.__support.bit
     libc.src.__support.macros.properties.cpu_features
 )
 
@@ -25,17 +25,17 @@ add_header_library(
     table.h
   DEPENDS
     .bitmask
-    libc.include.llvm-libc-types.ENTRY
-    libc.src.__support.CPP.bit
-    libc.src.__support.CPP.new
+    libc.src.__support.memory_size
+    libc.src.__support.bit
     libc.src.__support.CPP.type_traits
-    libc.src.__support.hash
+    libc.src.__support.CPP.new
     libc.src.__support.macros.attributes
     libc.src.__support.macros.optimization
-    libc.src.__support.memory_size
+    libc.src.__support.hash
     libc.src.string.memset
     libc.src.string.strcmp
     libc.src.string.strlen
+    libc.include.llvm-libc-types.ENTRY
 )
 
 add_header_library(
diff --git a/libc/src/__support/HashTable/bitmask.h b/libc/src/__support/HashTable/bitmask.h
index c775b09f2236f..38c9860020594 100644
--- a/libc/src/__support/HashTable/bitmask.h
+++ b/libc/src/__support/HashTable/bitmask.h
@@ -9,7 +9,7 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_HASHTABLE_BITMASK_H
 #define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_BITMASK_H
 
-#include "src/__support/CPP/bit.h"
+#include "src/__support/bit.h"
 #include "src/__support/macros/properties/cpu_features.h"
 #include <stddef.h> // size_t
 #include <stdint.h> // uint8_t, uint64_t
@@ -45,7 +45,7 @@ template <typename T, T WORD_MASK, size_t WORD_STRIDE> struct BitMaskAdaptor {
   // Count trailing zeros with respect to stride. (Assume the bitmask is none
   // zero.)
   LIBC_INLINE constexpr size_t lowest_set_bit_nonzero() const {
-    return cpp::countr_zero<T>(word) / WORD_STRIDE;
+    return unsafe_ctz<T>(word) / WORD_STRIDE;
   }
 };
 
diff --git a/libc/src/__support/HashTable/table.h b/libc/src/__support/HashTable/table.h
index 305fe59792d5a..ec0ec78869ad5 100644
--- a/libc/src/__support/HashTable/table.h
+++ b/libc/src/__support/HashTable/table.h
@@ -10,10 +10,10 @@
 #define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_table_H
 
 #include "include/llvm-libc-types/ENTRY.h"
-#include "src/__support/CPP/bit.h" // bit_ceil
 #include "src/__support/CPP/new.h"
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/HashTable/bitmask.h"
+#include "src/__support/bit.h"
 #include "src/__support/hash.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/optimization.h"
@@ -70,7 +70,7 @@ LIBC_INLINE size_t capacity_to_entries(size_t cap) {
   if (cap < sizeof(Group))
     cap = sizeof(Group);
   // overflow is always checked in allocate()
-  return cpp::bit_ceil(cap * 8 / 7);
+  return next_power_of_two(cap * 8 / 7);
 }
 
 // The heap memory layout for N buckets HashTable is as follows:
@@ -98,8 +98,7 @@ struct HashTable {
 
   LIBC_INLINE size_t offset_from_entries() const {
     size_t entries_size = num_of_entries() * sizeof(ENTRY);
-    return entries_size +
-           SafeMemSize::offset_to(entries_size, table_alignment());
+    return entries_size + offset_to(entries_size, table_alignment());
   }
 
   LIBC_INLINE constexpr static size_t table_alignment() {
diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h
index 3bec2e3a47130..248324c326dfb 100644
--- a/libc/src/__support/UInt.h
+++ b/libc/src/__support/UInt.h
@@ -10,10 +10,10 @@
 #define LLVM_LIBC_SRC___SUPPORT_UINT_H
 
 #include "src/__support/CPP/array.h"
-#include "src/__support/CPP/bit.h" // countl_zero
 #include "src/__support/CPP/limits.h"
 #include "src/__support/CPP/optional.h"
 #include "src/__support/CPP/type_traits.h"
+#include "src/__support/bit.h" // unsafe_clz
 #include "src/__support/integer_utils.h"
 #include "src/__support/macros/attributes.h"   // LIBC_INLINE
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
@@ -557,7 +557,7 @@ template <size_t Bits, bool Signed> struct BigInt {
       if (val[i - 1] == 0) {
         leading_zeroes += sizeof(uint64_t) * 8;
       } else {
-        leading_zeroes += countl_zero(val[i - 1]);
+        leading_zeroes += unsafe_clz(val[i - 1]);
         break;
       }
     }
diff --git a/libc/src/__support/bit.h b/libc/src/__support/bit.h
new file mode 100644
index 0000000000000..ba7fc31de1227
--- /dev/null
+++ b/libc/src/__support/bit.h
@@ -0,0 +1,117 @@
+//===-- Mimics llvm/ADT/Bit.h -----------------------------------*- C++ -*-===//
+// Provides useful bit functions.
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BIT_H
+#define LLVM_LIBC_SRC___SUPPORT_BIT_H
+
+#include "src/__support/CPP/type_traits.h"   // make_unsigned
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
+
+namespace LIBC_NAMESPACE {
+
+// The following overloads are matched based on what is accepted by
+// __builtin_clz/ctz* rather than using the exactly-sized aliases from stdint.h.
+// This way, we can avoid making any assumptions about integer sizes and let the
+// compiler match for us.
+namespace __internal {
+
+template <typename T> LIBC_INLINE int constexpr correct_zero(T val, int bits) {
+  if (val == T(0))
+    return sizeof(T(0)) * 8;
+  else
+    return bits;
+}
+
+template <typename T> LIBC_INLINE constexpr int clz(T val);
+template <> LIBC_INLINE int clz<unsigned char>(unsigned char val) {
+  return __builtin_clz(static_cast<unsigned int>(val)) -
+         8 * static_cast<int>(sizeof(unsigned int) - sizeof(unsigned char));
+}
+template <> LIBC_INLINE int clz<unsigned short>(unsigned short val) {
+  return __builtin_clz(static_cast<unsigned int>(val)) -
+         8 * static_cast<int>(sizeof(unsigned int) - sizeof(unsigned short));
+}
+template <> LIBC_INLINE int clz<unsigned int>(unsigned int val) {
+  return __builtin_clz(val);
+}
+template <>
+LIBC_INLINE constexpr int clz<unsigned long int>(unsigned long int val) {
+  return __builtin_clzl(val);
+}
+template <>
+LIBC_INLINE constexpr int
+clz<unsigned long long int>(unsigned long long int val) {
+  return __builtin_clzll(val);
+}
+
+template <typename T> LIBC_INLINE constexpr int ctz(T val);
+template <> LIBC_INLINE int ctz<unsigned char>(unsigned char val) {
+  return __builtin_ctz(static_cast<unsigned int>(val));
+}
+template <> LIBC_INLINE int ctz<unsigned short>(unsigned short val) {
+  return __builtin_ctz(static_cast<unsigned int>(val));
+}
+template <> LIBC_INLINE int ctz<unsigned int>(unsigned int val) {
+  return __builtin_ctz(val);
+}
+template <>
+LIBC_INLINE constexpr int ctz<unsigned long int>(unsigned long int val) {
+  return __builtin_ctzl(val);
+}
+template <>
+LIBC_INLINE constexpr int
+ctz<unsigned long long int>(unsigned long long int val) {
+  return __builtin_ctzll(val);
+}
+} // namespace __internal
+
+template <typename T> LIBC_INLINE constexpr int safe_ctz(T val) {
+  return __internal::correct_zero(val, __internal::ctz(val));
+}
+
+template <typename T> LIBC_INLINE constexpr int unsafe_ctz(T val) {
+  return __internal::ctz(val);
+}
+
+template <typename T> LIBC_INLINE constexpr int safe_clz(T val) {
+  return __internal::correct_zero(val, __internal::clz(val));
+}
+
+template <typename T> LIBC_INLINE constexpr int unsafe_clz(T val) {
+  return __internal::clz(val);
+}
+
+template <typename T> LIBC_INLINE constexpr T next_power_of_two(T val) {
+  if (val == 0)
+    return 1;
+  T idx = safe_clz(val - 1);
+  return static_cast<T>(1) << ((8ull * sizeof(T)) - idx);
+}
+
+template <typename T> LIBC_INLINE constexpr bool is_power_of_two(T val) {
+  return val != 0 && (val & (val - 1)) == 0;
+}
+
+template <typename T> LIBC_INLINE constexpr T offset_to(T val, T align) {
+  return (-val) & (align - 1);
+}
+
+template <typename T> LIBC_INLINE constexpr T rotate_left(T val, T amount) {
+  // Implementation taken from "Safe, Efficient, and Portable Rotate in C/C++"
+  // https://blog.regehr.org/archives/1063
+  // Using the safe version as the rotation ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/74444


More information about the libc-commits mailing list