[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Z6yWbROu5rREhw85@vaxr-BM6660-BM6360>
Date: Wed, 12 Feb 2025 20:39:09 +0800
From: I Hsin Cheng <richard120310@...il.com>
To: David Laight <david.laight.linux@...il.com>
Cc: yury.norov@...il.com, anshuman.khandual@....com, arnd@...db.de,
linux-kernel@...r.kernel.org, jserv@...s.ncku.edu.tw,
skhan@...uxfoundation.org
Subject: Re: [PATCH 2/2] uapi: Refactor __GENMASK_ULL() for speed-up
On Tue, Feb 11, 2025 at 10:30:45PM +0000, David Laight wrote:
> On Wed, 12 Feb 2025 00:24:12 +0800
> I Hsin Cheng <richard120310@...il.com> wrote:
>
> > The calculation of "((~_ULL(0)) - (_ULL(1) << (l)) + 1)" is to generate
> > a bitmask with "l" trailing zeroes, which is equivalent to
> > "(~_ULL(0) << (l))".
>
> Yes, and if you look through the commit history you'll see it was changed
> to avoid a compiler warning about the shift losing significant bits.
> So you are just reverting that change and the compiler warnings will
> reappear.
>
> For non-constants I suspect that (2ul << hi) - (1ul << lo) is the
> best answer.
> But the compiler (clang with some options?) will still complain
> for constants when trying to set the high bit.
>
> That version also doesn't need BITS_PER_[U]LONG.
> While that is valid for C, the _ULL() are there for the assembler
> (when they are no-ops) so there is no way asm copies can be right
> for both GENMASK() ans GENMASK_ULL().
>
> David
Hi David,
Thanks for the review!
> Yes, and if you look through the commit history you'll see it was changed
> to avoid a compiler warning about the shift losing significant bits.
I've browse through the commits of include/linux/bits.h , where
GENMASK() was placed under. Though I didn't find specific commit of it,
would you be so kind to paste the link of the commit?
I assume you're talking about warnings like the following?
warning: left shift count >= width of type [-Wshift-count-overflow]
If this is the case then it happens for the current version as well, I
mean from the perspective of operations, "(~_ULL(0) << (l))" and
"(_ULL(1) << (1))" are basically the same, they all shift a constant
left with an amount of "l". When "l" is large enough the compiler will
complain about losing msb.
> While that is valid for C, the _ULL() are there for the assembler
> (when they are no-ops) so there is no way asm copies can be right
> for both GENMASK() ans GENMASK_ULL().
I don't understand this part sorry, if asm copies can't be right for
"~_ULL(0) << (l)" , how can it be right for "(_ULL(1) << (l))" ?
At least from my pespective these 2 ops only differs at the value of
constant. Please let me know about it, I'm not familiar with assembler
and would love to know more about it. Thanks.
Best regards,
I Hsin Cheng
Powered by blists - more mailing lists