[libc-commits] [libc] [llvm] [libc][NFC] Split builtin_wrapper into bit and math_extras (PR #73113)
via libc-commits
libc-commits at lists.llvm.org
Wed Nov 22 05:04:38 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Guillaume Chatelet (gchatelet)
<details>
<summary>Changes</summary>
---
Patch is 30.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73113.diff
23 Files Affected:
- (modified) libc/src/__support/CMakeLists.txt (+19-12)
- (modified) libc/src/__support/FPUtil/CMakeLists.txt (+5-5)
- (modified) libc/src/__support/FPUtil/FPBits.h (+1-1)
- (modified) libc/src/__support/FPUtil/Hypot.h (+1-1)
- (modified) libc/src/__support/FPUtil/generic/CMakeLists.txt (+5-5)
- (modified) libc/src/__support/FPUtil/generic/FMA.h (+1-1)
- (modified) libc/src/__support/FPUtil/generic/FMod.h (+1-1)
- (modified) libc/src/__support/FPUtil/generic/sqrt.h (+1-1)
- (modified) libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h (+1-1)
- (modified) libc/src/__support/UInt.h (+33-17)
- (added) libc/src/__support/bit.h (+77)
- (modified) libc/src/__support/integer_utils.h (+1-1)
- (renamed) libc/src/__support/math_extras.h (+5-63)
- (modified) libc/src/__support/str_to_float.h (+1-1)
- (modified) libc/src/math/generic/CMakeLists.txt (+5-5)
- (modified) libc/src/math/generic/powf.cpp (+1-1)
- (modified) libc/test/src/__support/CMakeLists.txt (+23)
- (added) libc/test/src/__support/bit_test.cpp (+18)
- (added) libc/test/src/__support/math_extras_test.cpp (+18)
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+19-10)
- (modified) utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl (+1-1)
- (added) utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel (+23)
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/libc_math_test_rules.bzl (+2-1)
``````````diff
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 35b724b3e3df9a4..8f66209ab54c550 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -27,9 +27,17 @@ add_header_library(
)
add_header_library(
- builtin_wrappers
+ bit
HDRS
- builtin_wrappers.h
+ bit.h
+ DEPENDS
+ libc.src.__support.macros.attributes
+)
+
+add_header_library(
+ math_extras
+ HDRS
+ math_extras.h
DEPENDS
.named_pair
libc.src.__support.CPP.type_traits
@@ -98,7 +106,6 @@ add_header_library(
libc.src.__support.CPP.type_traits
)
-
add_header_library(
float_to_string
HDRS
@@ -131,18 +138,17 @@ add_header_library(
.str_to_integer
.str_to_num_result
.uint128
- libc.src.__support.CPP.optional
+ libc.src.__support.common
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.FPUtil.dyadic_float
- libc.src.__support.builtin_wrappers
- libc.src.__support.common
+ libc.src.__support.bit
libc.src.errno.errno
)
-
add_header_library(
integer_operations
HDRS
@@ -187,10 +193,10 @@ add_header_library(
HDRS
integer_utils.h
DEPENDS
- .builtin_wrappers
+ .bit
.number_pair
- libc.src.__support.CPP.type_traits
libc.src.__support.common
+ libc.src.__support.CPP.type_traits
)
add_header_library(
@@ -198,9 +204,10 @@ add_header_library(
HDRS
UInt.h
DEPENDS
- .builtin_wrappers
- .number_pair
+ .bit
.integer_utils
+ .math_extras
+ .number_pair
libc.src.__support.CPP.array
libc.src.__support.CPP.type_traits
libc.src.__support.macros.optimization
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 4025c2a5d19a53f..bf6e39f436c8c49 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -45,12 +45,12 @@ add_header_library(
HDRS
FPBits.h
DEPENDS
- .platform_defs
.float_properties
- libc.src.__support.builtin_wrappers
+ .platform_defs
+ libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
- libc.src.__support.common
+ libc.src.__support.bit
)
add_header_library(
@@ -153,10 +153,10 @@ add_header_library(
.fenv_impl
.fp_bits
.rounding_mode
- libc.src.__support.builtin_wrappers
+ libc.src.__support.common
libc.src.__support.CPP.bit
libc.src.__support.CPP.type_traits
- libc.src.__support.common
+ 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 37e9bc9cfc84c3a..0db90d1e36df0c2 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -13,7 +13,7 @@
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
-#include "src/__support/builtin_wrappers.h"
+#include "src/__support/bit.h"
#include "src/__support/common.h"
#include "FloatProperties.h"
diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h
index 357d9a6e99c7457..db2a62fbdf2a107 100644
--- a/libc/src/__support/FPUtil/Hypot.h
+++ b/libc/src/__support/FPUtil/Hypot.h
@@ -16,7 +16,7 @@
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/UInt128.h"
-#include "src/__support/builtin_wrappers.h"
+#include "src/__support/bit.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
diff --git a/libc/src/__support/FPUtil/generic/CMakeLists.txt b/libc/src/__support/FPUtil/generic/CMakeLists.txt
index 7f986d05adedf92..cf603e7987e1d68 100644
--- a/libc/src/__support/FPUtil/generic/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/generic/CMakeLists.txt
@@ -4,16 +4,16 @@ add_header_library(
sqrt.h
sqrt_80_bit_long_double.h
DEPENDS
+ libc.include.fenv
+ 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.fp_bits
libc.src.__support.FPUtil.platform_defs
libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.builtin_wrappers
- libc.src.__support.common
+ libc.src.__support.bit
libc.src.__support.uint128
- libc.include.fenv
)
add_header_library(
@@ -27,8 +27,8 @@ add_header_library(
libc.src.__support.FPUtil.float_properties
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.builtin_wrappers
libc.src.__support.macros.optimization
+ libc.src.__support.bit
libc.src.__support.uint128
)
@@ -43,7 +43,7 @@ add_header_library(
libc.src.__support.FPUtil.float_properties
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
- libc.src.__support.builtin_wrappers
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 b90b134926bb649..5a856d144733041 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -15,7 +15,7 @@
#include "src/__support/FPUtil/FloatProperties.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/UInt128.h"
-#include "src/__support/builtin_wrappers.h"
+#include "src/__support/bit.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
diff --git a/libc/src/__support/FPUtil/generic/FMod.h b/libc/src/__support/FPUtil/generic/FMod.h
index ff320f36ee2277b..6f934cd4a87bd4a 100644
--- a/libc/src/__support/FPUtil/generic/FMod.h
+++ b/libc/src/__support/FPUtil/generic/FMod.h
@@ -13,7 +13,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "src/__support/builtin_wrappers.h"
+#include "src/__support/bit.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/math/generic/math_utils.h"
diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h
index 7d446d3a5ffb135..db9f4b11eb17c59 100644
--- a/libc/src/__support/FPUtil/generic/sqrt.h
+++ b/libc/src/__support/FPUtil/generic/sqrt.h
@@ -17,7 +17,7 @@
#include "src/__support/FPUtil/PlatformDefs.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/UInt128.h"
-#include "src/__support/builtin_wrappers.h"
+#include "src/__support/bit.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
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 685a90dba7c704b..dbbb238ca24d1b8 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
@@ -14,7 +14,7 @@
#include "src/__support/FPUtil/PlatformDefs.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/UInt128.h"
-#include "src/__support/builtin_wrappers.h"
+#include "src/__support/bit.h"
#include "src/__support/common.h"
namespace LIBC_NAMESPACE {
diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h
index 9aeb239b8328bea..f46e31ae03db291 100644
--- a/libc/src/__support/UInt.h
+++ b/libc/src/__support/UInt.h
@@ -13,9 +13,10 @@
#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/CPP/type_traits.h"
-#include "src/__support/builtin_wrappers.h"
+#include "src/__support/bit.h" // unsafe_clz
#include "src/__support/integer_utils.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/math_extras.h" // SumCarry, DiffBorrow
#include "src/__support/number_pair.h"
#include <stddef.h> // For size_t
@@ -33,7 +34,9 @@ template <size_t Bits, bool Signed> struct BigInt {
static LIBC_INLINE_VAR constexpr uint64_t MASK32 = 0xFFFFFFFFu;
static LIBC_INLINE constexpr uint64_t low(uint64_t v) { return v & MASK32; }
- static LIBC_INLINE constexpr uint64_t high(uint64_t v) { return (v >> 32) & MASK32; }
+ static LIBC_INLINE constexpr uint64_t high(uint64_t v) {
+ return (v >> 32) & MASK32;
+ }
LIBC_INLINE constexpr BigInt() = default;
@@ -93,7 +96,8 @@ template <size_t Bits, bool Signed> struct BigInt {
}
}
- LIBC_INLINE constexpr explicit BigInt(const cpp::array<uint64_t, WORDCOUNT> &words) {
+ LIBC_INLINE constexpr explicit BigInt(
+ const cpp::array<uint64_t, WORDCOUNT> &words) {
for (size_t i = 0; i < WORDCOUNT; ++i)
val[i] = words[i];
}
@@ -143,7 +147,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return s.carry;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator+(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
+ operator+(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result;
SumCarry<uint64_t> s{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -155,7 +160,8 @@ template <size_t Bits, bool Signed> struct BigInt {
// This will only apply when initializing a variable from constant values, so
// it will always use the constexpr version of add_with_carry.
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator+(BigInt<Bits, Signed> &&other) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
+ operator+(BigInt<Bits, Signed> &&other) const {
BigInt<Bits, Signed> result;
SumCarry<uint64_t> s{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -182,7 +188,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return d.borrow;
}
- LIBC_INLINE BigInt<Bits, Signed> operator-(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE BigInt<Bits, Signed>
+ operator-(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result;
DiffBorrow<uint64_t> d{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -192,7 +199,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- LIBC_INLINE constexpr BigInt<Bits, Signed> operator-(BigInt<Bits, Signed> &&other) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed>
+ operator-(BigInt<Bits, Signed> &&other) const {
BigInt<Bits, Signed> result;
DiffBorrow<uint64_t> d{0, 0};
for (size_t i = 0; i < WORDCOUNT; ++i) {
@@ -317,7 +325,7 @@ template <size_t Bits, bool Signed> struct BigInt {
// 256 4 16 10 3
// 512 8 64 36 7
constexpr BigInt<Bits, Signed>
- LIBC_INLINE quick_mul_hi(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE quick_mul_hi(const BigInt<Bits, Signed> &other) const {
BigInt<Bits, Signed> result(0);
BigInt<128, Signed> partial_sum(0);
uint64_t carry = 0;
@@ -407,8 +415,8 @@ template <size_t Bits, bool Signed> struct BigInt {
// Since the remainder of each division step < x < 2^32, the computation of
// each step is now properly contained within uint64_t.
// And finally we perform some extra alignment steps for the remaining bits.
- LIBC_INLINE constexpr optional<BigInt<Bits, Signed>> div_uint32_times_pow_2(uint32_t x,
- size_t e) {
+ LIBC_INLINE constexpr optional<BigInt<Bits, Signed>>
+ div_uint32_times_pow_2(uint32_t x, size_t e) {
BigInt<Bits, Signed> remainder(0);
if (x == 0) {
@@ -729,7 +737,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return result;
}
- LIBC_INLINE constexpr bool operator==(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool
+ operator==(const BigInt<Bits, Signed> &other) const {
for (size_t i = 0; i < WORDCOUNT; ++i) {
if (val[i] != other.val[i])
return false;
@@ -737,7 +746,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return true;
}
- LIBC_INLINE constexpr bool operator!=(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool
+ operator!=(const BigInt<Bits, Signed> &other) const {
for (size_t i = 0; i < WORDCOUNT; ++i) {
if (val[i] != other.val[i])
return true;
@@ -745,7 +755,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return false;
}
- LIBC_INLINE constexpr bool operator>(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool
+ operator>(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for different signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -766,7 +777,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return false;
}
- LIBC_INLINE constexpr bool operator>=(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool
+ operator>=(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for different signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -787,7 +799,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return true;
}
- LIBC_INLINE constexpr bool operator<(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool
+ operator<(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for different signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -809,7 +822,8 @@ template <size_t Bits, bool Signed> struct BigInt {
return false;
}
- LIBC_INLINE constexpr bool operator<=(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr bool
+ operator<=(const BigInt<Bits, Signed> &other) const {
if constexpr (Signed) {
// Check for different signs;
bool a_sign = val[WORDCOUNT - 1] >> 63;
@@ -857,7 +871,9 @@ template <size_t Bits, bool Signed> struct BigInt {
}
// Return the i-th 64-bit word of the number.
- LIBC_INLINE constexpr const uint64_t &operator[](size_t i) const { return val[i]; }
+ LIBC_INLINE constexpr const uint64_t &operator[](size_t i) const {
+ return val[i];
+ }
// Return the i-th 64-bit word of the number.
LIBC_INLINE constexpr uint64_t &operator[](size_t i) { return val[i]; }
diff --git a/libc/src/__support/bit.h b/libc/src/__support/bit.h
new file mode 100644
index 000000000000000..d0a15c89b7b45e7
--- /dev/null
+++ b/libc/src/__support/bit.h
@@ -0,0 +1,77 @@
+//===-- 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/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 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 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);
+}
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BIT_H
diff --git a/libc/src/__support/integer_utils.h b/libc/src/__support/integer_utils.h
index 7b62cb0d9f50593..433e99227bcfd4a 100644
--- a/libc/src/__support/integer_utils.h
+++ b/libc/src/__support/integer_utils.h
@@ -12,7 +12,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
-#include "builtin_wrappers.h"
+#include "bit.h"
#include "number_pair.h"
#include <stdint.h>
diff --git a/libc/src/__support/builtin_wrappers.h b/libc/src/__support/math_extras.h
similarity index 72%
rename from libc/src/__support/builtin_wrappers.h
rename to libc/src/__support/math_extras.h
index bd307a3544cd930..cc22aa49d02601b 100644
--- a/libc/src/__support/builtin_wrappers.h
+++ b/libc/src/__support/math_extras.h
@@ -1,5 +1,5 @@
-//===--Convenient template for builtins -------------------------*- C++ -*-===//
-// (Count Lead Zeroes) and (Count Trailing Zeros)
+//===-- Mimics llvm/Support/MathExtras.h ------------------------*- C++ -*-===//
+// Provides useful math functions.
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTIN_WRAPPERS_H
-#define LLVM_LIBC_SRC___SUPPORT_BUILTIN_WRAPPERS_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXTRAS_H
#include "named_pair.h"
#include "src/__support/CPP/type_traits.h"
@@ -17,64 +17,6 @@
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 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 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...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/73113
More information about the libc-commits
mailing list