On Thu, 30 Mar 2023, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote: > On Thu, 30 Mar 2023 21:53:03 +0000 David Laight <David.Laight@xxxxxxxxxx> wrote: > >> > But wouldn't all these issues be addressed by simply doing >> > >> > #define is_power_of_2(n) (n != 0 && ((n & (n - 1)) == 0)) >> > >> > ? >> > >> > (With suitable tweaks to avoid evaluating `n' more than once) >> >> I think you need to use the 'horrid tricks' from min() to get >> a constant expression from constant inputs. > > This > > --- a/include/linux/log2.h~a > +++ a/include/linux/log2.h > @@ -41,11 +41,11 @@ int __ilog2_u64(u64 n) > * *not* considered a power of two. > * Return: true if @n is a power of 2, otherwise false. > */ > -static inline __attribute__((const)) > -bool is_power_of_2(unsigned long n) > -{ > - return (n != 0 && ((n & (n - 1)) == 0)); > -} > +#define is_power_of_2(_n) \ > + ({ \ > + typeof(_n) n = (_n); \ > + n != 0 && ((n & (n - 1)) == 0); \ > + }) > > /** > * __roundup_pow_of_two() - round up to nearest power of two > _ > > worked for me in a simple test. > > --- a/fs/open.c~b > +++ a/fs/open.c > @@ -1564,3 +1564,10 @@ int stream_open(struct inode *inode, str > } > > EXPORT_SYMBOL(stream_open); > + > +#include <linux/log2.h> > + > +int foo(void) > +{ > + return is_power_of_2(43); > +} > _ > > > foo: > # fs/open.c:1573: } > xorl %eax, %eax # > ret > > > Is there some more tricky situation where it breaks? It doesn't work with BUILD_BUG_ON_ZERO(). test.c: #define IS_POWER_OF_2(_n) \ ({ \ typeof(_n) n = (_n); \ n != 0 && ((n & (n - 1)) == 0); \ }) #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) #define FOO(n) ((n) + BUILD_BUG_ON_ZERO(!IS_POWER_OF_2(n))) int main(void) { return FOO(2); } $ gcc test.c test.c: In function ‘main’: test.c:16:51: error: bit-field ‘<anonymous>’ width not an integer constant 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ test.c:18:23: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’ 18 | #define FOO(n) ((n) + BUILD_BUG_ON_ZERO(!IS_POWER_OF_2(n))) | ^~~~~~~~~~~~~~~~~ test.c:22:9: note: in expansion of macro ‘FOO’ 22 | return FOO(2); | ^~~ BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center