summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@orcam.me.uk>2026-01-11 21:21:57 +0000
committerAndrew Morton <akpm@linux-foundation.org>2026-01-26 19:07:14 -0800
commit4cc67b048459bebb7a60b693044ec83fb853eba1 (patch)
treefb153fa505f7376b51ba0f8bc6177c1e04def724 /include
parent5e65b5ca7d4e1f5d18e03ada94f549086ceb6500 (diff)
linux/log2.h: reduce instruction count for is_power_of_2()
Follow an observation that (n ^ (n - 1)) will only ever retain the most significant bit set in the word operated on if that is the only bit set in the first place, and use it to determine whether a number is a whole power of 2, avoiding the need for an explicit check for nonzero. This reduces the sequence produced to 3 instructions only across Alpha, MIPS, and RISC-V targets, down from 4, 5, and 4 respectively, removing a branch in the two latter cases. And it's 5 instructions on POWER and x86-64 vs 8 and 9 respectively. There are no branches now emitted here for targets that have a suitable conditional set operation, although an inline expansion will often end with one, depending on what code a call to this function is used in. Credit goes to GCC authors for coming up with this optimisation used as the fallback for (__builtin_popcountl(n) == 1), equivalent to this code, for targets where the hardware population count operation is considered expensive. Link: https://lkml.kernel.org/r/alpine.DEB.2.21.2601111836250.30566@angie.orcam.me.uk Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk> Cc: Jens Axboe <axboe@kernel.dk> Cc: John Garry <john.g.garry@oracle.com> Cc: "Martin K. Petersen" <martin.petersen@oracle.com> Cc: Su Hui <suhui@nfschina.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/log2.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/log2.h b/include/linux/log2.h
index 2eac3fc9303d..e17ceb32e0c9 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -44,7 +44,7 @@ int __ilog2_u64(u64 n)
static __always_inline __attribute__((const))
bool is_power_of_2(unsigned long n)
{
- return (n != 0 && ((n & (n - 1)) == 0));
+ return n - 1 < (n ^ (n - 1));
}
/**