* lib/stdbit.in.h (stdc_first_leading_zero)
(stdc_first_leading_one, stdc_first_trailing_zero_uc)
(stdc_first_trailing_one_uc): Redo to avoid the need for a
conditional branch, at least on x86-64 with GCC 14.
---
 ChangeLog       |  7 +++++-
 lib/stdbit.in.h | 60 ++++++++++++++++++++++++++++++++-----------------
 2 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f37d9f2796..049f27b3b8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,11 @@
 2024-05-15  Paul Eggert  <egg...@cs.ucla.edu>
 
-       stdbit: tweak for non-GCC non-Clang
+       stdbit: tweak first_leading for GCC
+       * lib/stdbit.in.h (stdc_first_leading_zero)
+       (stdc_first_leading_one, stdc_first_trailing_zero_uc)
+       (stdc_first_trailing_one_uc): Redo to avoid the need for a
+       conditional branch, at least on x86-64 with GCC 14.
+
        * lib/stdbit.in.h (__gl_stdbit_clz, __gl_stdbit_clzl)
        (__gl_stdbit_clzll, __gl_stdbit_ctz, __gl_stdbit_ctzl)
        (__gl_stdbit_ctzll): Work even if the argument is zero.
diff --git a/lib/stdbit.in.h b/lib/stdbit.in.h
index 984ef44ef9..ab328a7793 100644
--- a/lib/stdbit.in.h
+++ b/lib/stdbit.in.h
@@ -494,35 +494,40 @@ _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_zero_uc (unsigned char n)
 {
   unsigned int count = stdc_leading_ones_uc (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_zero_us (unsigned short int n)
 {
   unsigned int count = stdc_leading_ones_us (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_zero_ui (unsigned int n)
 {
   unsigned int count = stdc_leading_ones_ui (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_zero_ul (unsigned long int n)
 {
   unsigned int count = stdc_leading_ones_ul (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_zero_ull (unsigned long long int n)
 {
   unsigned int count = stdc_leading_ones_ull (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 #define stdc_first_leading_zero(n) \
@@ -537,35 +542,40 @@ _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_one_uc (unsigned char n)
 {
   unsigned int count = stdc_leading_zeros_uc (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_one_us (unsigned short int n)
 {
   unsigned int count = stdc_leading_zeros_us (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_one_ui (unsigned int n)
 {
   unsigned int count = stdc_leading_zeros_ui (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_one_ul (unsigned long int n)
 {
   unsigned int count = stdc_leading_zeros_ul (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_leading_one_ull (unsigned long long int n)
 {
   unsigned int count = stdc_leading_zeros_ull (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 #define stdc_first_leading_one(n) \
@@ -580,35 +590,40 @@ _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_zero_uc (unsigned char n)
 {
   unsigned int count = stdc_trailing_ones_uc (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_zero_us (unsigned short int n)
 {
   unsigned int count = stdc_trailing_ones_us (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_zero_ui (unsigned int n)
 {
   unsigned int count = stdc_trailing_ones_ui (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_zero_ul (unsigned long int n)
 {
   unsigned int count = stdc_trailing_ones_ul (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_zero_ull (unsigned long long int n)
 {
   unsigned int count = stdc_trailing_ones_ull (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 #define stdc_first_trailing_zero(n) \
@@ -623,35 +638,40 @@ _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_one_uc (unsigned char n)
 {
   unsigned int count = stdc_trailing_zeros_uc (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_one_us (unsigned short int n)
 {
   unsigned int count = stdc_trailing_zeros_us (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_one_ui (unsigned int n)
 {
   unsigned int count = stdc_trailing_zeros_ui (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_one_ul (unsigned long int n)
 {
   unsigned int count = stdc_trailing_zeros_ul (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 _GL_STDBIT_INLINE unsigned int
 stdc_first_trailing_one_ull (unsigned long long int n)
 {
   unsigned int count = stdc_trailing_zeros_ull (n);
-  return count == 8 * sizeof n ? 0 : count + 1;
+  unsigned int bits = 8 * sizeof n;
+  return count % bits + (count < bits);
 }
 
 #define stdc_first_trailing_one(n) \
-- 
2.45.0


Reply via email to