* [PATCH] csky: bitops: Use the compiler builtin for __fls()
@ 2026-10-22 11:59 Tzu-Ching Yang
2026-10-22 19:41 ` Yury Norov
0 siblings, 1 reply; 2+ messages in thread
From: Tzu-Ching Yang @ 2026-10-22 11:59 UTC (permalink / raw)
To: Guo Ren
Cc: linux-csky, Yury Norov, Rasmus Villemoes, Arnd Bergmann,
linux-arch, linux-kernel
The csky __fls() is a C wrapper, fls(x) - 1, around the ff1 asm
volatile in fls(), so the compiler can neither fold it for a constant
argument nor merge repeated calls. GCC implements __builtin_clzl()
with the same ff1 instruction for CK807, CK810 and CK860; CK610
(abiv1) cannot be built with upstream GCC.
Use the asm-generic builtin __fls() instead. ffs(), __ffs() and fls()
keep their asm: GCC has no ctz pattern for csky, so builtin ffs() and
__ffs() would become calls to __ffssi2() and __ctzsi2(), and a builtin
fls() needs a test for zero that ff1 makes unnecessary by returning 32
for 0.
__fls() now returns unsigned int instead of unsigned long, like the
asm-generic version; both are 32 bits wide on csky. __fls(0) remains
undefined.
With GCC 9 to 16, the text of every defconfig-based vmlinux tested
shrinks by 128 to 320 bytes.
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/all/affe7da1-41aa-4710-bee0-5e3c2b8a8dfc@app.fastmail.com/
Signed-off-by: Tzu-Ching Yang <shingekinocore@gmail.com>
---
In a test function, __fls(x) takes 4 instructions (return included)
before and after with each GCC and CPU tested, at -O2 and -Os; with a
constant argument, it now folds.
CK610 needs an abiv1 GCC; the only one I could find is the vendor's 6.3,
older than the 8.1 minimum and without a clz pattern for abiv1. There,
__fls() would become a call to __clzsi2(), which lib/clz_ctz.c
implements with the fls() asm, so it would still work; a builtin fls()
would make __clzsi2() call itself.
Testing: 35 defconfig-based kernels for CK807, CK810 and CK860, some
with KUnit or SMP, built before and after with W=1 by kernel.org GCC 9.5
to 16.2 (GCC 8 has no csky port, and GCC 9 to 11 reject -mcpu=ck860): no
new warnings and no calls to __ctzsi2(), __clzsi2() or __ffssi2().
allmodconfig with GCC 12 and 16 compiles the same objects with the same
warnings, but does not reach a vmlinux because of GCC internal compiler
errors, before and after. Under XuanTie's qemu-cskyv2 user mode, the old
and new helpers return the same values for every defined 32-bit input,
built with the kernel's flags by each GCC for each CPU at -O2 and -Os.
On qemu-system-cskyv2 -M virt, the ffs and bitops KUnit tests pass
before and after; test_bitmap passes with GCC 12 to 16 and has the same
one failure with GCC 9 to 11 in both, from a test bug fixed in
linux-next. No csky hardware was available.
Against the linux-next branch of c-sky/csky-linux.git (abb81e5ce7d9);
also applies to next-20261021 and to bitmap-for-next. Full build and
test data on request.
arch/csky/include/asm/bitops.h | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/arch/csky/include/asm/bitops.h b/arch/csky/include/asm/bitops.h
index 80d67eee6e86..118fb0df5267 100644
--- a/arch/csky/include/asm/bitops.h
+++ b/arch/csky/include/asm/bitops.h
@@ -49,14 +49,7 @@ static __always_inline __attribute_const__ int fls(unsigned int x)
return (32 - x);
}
-/*
- * asm-generic/bitops/__fls.h
- */
-static __always_inline __attribute_const__ unsigned long __fls(unsigned long x)
-{
- return fls(x) - 1;
-}
-
+#include <asm-generic/bitops/builtin-__fls.h>
#include <asm-generic/bitops/ffz.h>
#include <asm-generic/bitops/fls64.h>
base-commit: abb81e5ce7d995baa41556b8125fa59e28ba3be8
--
2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] csky: bitops: Use the compiler builtin for __fls()
2026-10-22 11:59 [PATCH] csky: bitops: Use the compiler builtin for __fls() Tzu-Ching Yang
@ 2026-10-22 19:41 ` Yury Norov
0 siblings, 0 replies; 2+ messages in thread
From: Yury Norov @ 2026-10-22 19:41 UTC (permalink / raw)
To: Tzu-Ching Yang
Cc: Guo Ren, linux-csky, Yury Norov, Rasmus Villemoes, Arnd Bergmann,
linux-arch, linux-kernel
On Thu, Oct 22, 2026 at 07:59:22PM +0800, Tzu-Ching Yang wrote:
> The csky __fls() is a C wrapper, fls(x) - 1, around the ff1 asm
> volatile in fls(), so the compiler can neither fold it for a constant
> argument nor merge repeated calls. GCC implements __builtin_clzl()
> with the same ff1 instruction for CK807, CK810 and CK860; CK610
> (abiv1) cannot be built with upstream GCC.
>
> Use the asm-generic builtin __fls() instead. ffs(), __ffs() and fls()
> keep their asm: GCC has no ctz pattern for csky, so builtin ffs() and
> __ffs() would become calls to __ffssi2() and __ctzsi2(), and a builtin
> fls() needs a test for zero that ff1 makes unnecessary by returning 32
> for 0.
>
> __fls() now returns unsigned int instead of unsigned long, like the
> asm-generic version; both are 32 bits wide on csky. __fls(0) remains
> undefined.
>
> With GCC 9 to 16, the text of every defconfig-based vmlinux tested
> shrinks by 128 to 320 bytes.
>
> Suggested-by: Arnd Bergmann <arnd@arndb.de>
> Link: https://lore.kernel.org/all/affe7da1-41aa-4710-bee0-5e3c2b8a8dfc@app.fastmail.com/
> Signed-off-by: Tzu-Ching Yang <shingekinocore@gmail.com>
> ---
> In a test function, __fls(x) takes 4 instructions (return included)
> before and after with each GCC and CPU tested, at -O2 and -Os; with a
> constant argument, it now folds.
>
> CK610 needs an abiv1 GCC; the only one I could find is the vendor's 6.3,
> older than the 8.1 minimum and without a clz pattern for abiv1. There,
> __fls() would become a call to __clzsi2(), which lib/clz_ctz.c
> implements with the fls() asm, so it would still work; a builtin fls()
> would make __clzsi2() call itself.
>
> Testing: 35 defconfig-based kernels for CK807, CK810 and CK860, some
> with KUnit or SMP, built before and after with W=1 by kernel.org GCC 9.5
> to 16.2 (GCC 8 has no csky port, and GCC 9 to 11 reject -mcpu=ck860): no
> new warnings and no calls to __ctzsi2(), __clzsi2() or __ffssi2().
> allmodconfig with GCC 12 and 16 compiles the same objects with the same
> warnings, but does not reach a vmlinux because of GCC internal compiler
> errors, before and after. Under XuanTie's qemu-cskyv2 user mode, the old
> and new helpers return the same values for every defined 32-bit input,
> built with the kernel's flags by each GCC for each CPU at -O2 and -Os.
> On qemu-system-cskyv2 -M virt, the ffs and bitops KUnit tests pass
> before and after; test_bitmap passes with GCC 12 to 16 and has the same
> one failure with GCC 9 to 11 in both, from a test bug fixed in
> linux-next. No csky hardware was available.
>
> Against the linux-next branch of c-sky/csky-linux.git (abb81e5ce7d9);
> also applies to next-20261021 and to bitmap-for-next. Full build and
> test data on request.
So I didn't understand if you have an access to the hardware or not. I
don't know the story behind using the non-generic version of ffl(),
but it may be for performance reasons. Can you / someone else please
run the lib/find_bit_benchmark.c on real hardware before we move this?
Thanks,
Yury
> arch/csky/include/asm/bitops.h | 9 +--------
> 1 file changed, 1 insertion(+), 8 deletions(-)
>
> diff --git a/arch/csky/include/asm/bitops.h b/arch/csky/include/asm/bitops.h
> index 80d67eee6e86..118fb0df5267 100644
> --- a/arch/csky/include/asm/bitops.h
> +++ b/arch/csky/include/asm/bitops.h
> @@ -49,14 +49,7 @@ static __always_inline __attribute_const__ int fls(unsigned int x)
> return (32 - x);
> }
>
> -/*
> - * asm-generic/bitops/__fls.h
> - */
> -static __always_inline __attribute_const__ unsigned long __fls(unsigned long x)
> -{
> - return fls(x) - 1;
> -}
> -
> +#include <asm-generic/bitops/builtin-__fls.h>
> #include <asm-generic/bitops/ffz.h>
> #include <asm-generic/bitops/fls64.h>
>
>
> base-commit: abb81e5ce7d995baa41556b8125fa59e28ba3be8
> --
> 2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-22 19:41 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-22 11:59 [PATCH] csky: bitops: Use the compiler builtin for __fls() Tzu-Ching Yang
2026-10-22 19:41 ` Yury Norov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®