[libc-commits] [PATCH] D117684: [libc] Use __builtin_clz to find leading 1 in hypot
Clint Caywood via Phabricator via libc-commits
libc-commits at lists.llvm.org
Wed Jan 19 09:52:42 PST 2022
cratonica updated this revision to Diff 401295.
cratonica added a comment.
s/uint32_t/unsigned int/ on return type for find_leading_one
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D117684/new/
https://reviews.llvm.org/D117684
Files:
libc/src/__support/FPUtil/Hypot.h
Index: libc/src/__support/FPUtil/Hypot.h
===================================================================
--- libc/src/__support/FPUtil/Hypot.h
+++ libc/src/__support/FPUtil/Hypot.h
@@ -21,33 +21,39 @@
template <typename T>
static inline T find_leading_one(T mant, int &shift_length);
+// The following overloads are matched based on what is accepted by
+// __builtin_clz* rather than using the exactly-sized aliases from stdint.h
+// (such as uint32_t). There are 3 overloads even though 2 will only ever be
+// used by a specific platform, since unsigned long varies in size depending on
+// the word size of the architecture.
+
template <>
-inline uint32_t find_leading_one<uint32_t>(uint32_t mant, int &shift_length) {
+inline unsigned int find_leading_one<unsigned int>(unsigned int mant,
+ int &shift_length) {
shift_length = 0;
- constexpr int NSTEPS = 5;
- constexpr uint32_t BOUNDS[NSTEPS] = {1 << 16, 1 << 8, 1 << 4, 1 << 2, 1 << 1};
- constexpr int SHIFTS[NSTEPS] = {16, 8, 4, 2, 1};
- for (int i = 0; i < NSTEPS; ++i) {
- if (mant >= BOUNDS[i]) {
- shift_length += SHIFTS[i];
- mant >>= SHIFTS[i];
- }
+ if (mant > 0) {
+ shift_length = (sizeof(mant) * 8) - 1 - __builtin_clz(mant);
}
return 1U << shift_length;
}
template <>
-inline uint64_t find_leading_one<uint64_t>(uint64_t mant, int &shift_length) {
+inline unsigned long find_leading_one<unsigned long>(unsigned long mant,
+ int &shift_length) {
shift_length = 0;
- constexpr int NSTEPS = 6;
- constexpr uint64_t BOUNDS[NSTEPS] = {1ULL << 32, 1ULL << 16, 1ULL << 8,
- 1ULL << 4, 1ULL << 2, 1ULL << 1};
- constexpr int SHIFTS[NSTEPS] = {32, 16, 8, 4, 2, 1};
- for (int i = 0; i < NSTEPS; ++i) {
- if (mant >= BOUNDS[i]) {
- shift_length += SHIFTS[i];
- mant >>= SHIFTS[i];
- }
+ if (mant > 0) {
+ shift_length = (sizeof(mant) * 8) - 1 - __builtin_clzl(mant);
+ }
+ return 1UL << shift_length;
+}
+
+template <>
+inline unsigned long long
+find_leading_one<unsigned long long>(unsigned long long mant,
+ int &shift_length) {
+ shift_length = 0;
+ if (mant > 0) {
+ shift_length = (sizeof(mant) * 8) - 1 - __builtin_clzll(mant);
}
return 1ULL << shift_length;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117684.401295.patch
Type: text/x-patch
Size: 2392 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20220119/49386e37/attachment-0001.bin>
More information about the libc-commits
mailing list