Page MenuHomeFreeBSD

linuxkpi: Use `__builtin_popcountg()` instead of `bitcount*()`
Needs ReviewPublic

Authored by dumbbell on Mon, Jun 23, 9:37 PM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Jul 11, 4:50 AM
Unknown Object (File)
Thu, Jul 10, 9:43 PM
Unknown Object (File)
Thu, Jul 10, 8:38 PM
Unknown Object (File)
Wed, Jul 9, 1:29 AM
Unknown Object (File)
Tue, Jul 8, 5:11 PM
Unknown Object (File)
Sun, Jul 6, 10:12 PM
Unknown Object (File)
Sun, Jul 6, 10:49 AM
Unknown Object (File)
Sat, Jul 5, 11:21 PM
Subscribers

Details

Reviewers
None
Group Reviewers
linuxkpi
Summary

The DRM drivers generic code started to use HWEIGHT64() in the definition of an array field in a structure. Therefore, the array size needs to be known at compile time. This was not the case with the HWEIGHT*() macros based on bitcount*(). The use of __builtin_popcountg() solves that problem.

Sponsored by: The FreeBSD Foundation

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

Why do we + 1? It came in 4cc8a9da491d1 but I believe is a bug.

The only one used today is HWEIGHT32 in an assertion:

BUILD_BUG_ON(IWL_MAX_UMAC_SCANS > HWEIGHT32(IWL_MVM_SCAN_MASK) ||
             IWL_MAX_LMAC_SCANS > HWEIGHT32(IWL_MVM_SCAN_MASK));

Also, is __builtin_popcountg available in all of the compilers we need to support?

Why do we + 1? It came in 4cc8a9da491d1 but I believe is a bug.

I believe so too.

But I also do not understand to compile-time issue of this change. Our bitcount() is defined as:

sys/sys/libkern.h:#define       bitcount(x)     __bitcount((u_int)(x))
sys/sys/bitcount.h:#define      __bitcount(x)   __builtin_popcount((unsigned int)(x))

if POPCNT is defined ... and it seems clang only does for X86? Is this a relict of 589b2c1c1e31b48d9f8defe061983500766aa28f preventing us from being more efficient these days?
But then the issue should only show up on non-X86? The proposed commit message does not explain this and I wonder if my reading of code is correct?

Lastly contrib/llvm-project/libcxx/include/__bit/popcount.h says:

"__builtin_popcountg is available since Clang 19 and GCC 14"

No idea what our bare minimum is.

sys/compat/linuxkpi/common/include/linux/bitops.h
69

`__builtin_popcountg` is signdness agnostic so we should not need to cast it to uintX first? Can someone confirm?

Thank you @emaste for the bugfix. I was not sure myself if the + 1 was intended.

About the compile-time problem, the DRM drivers from Linux 6.9 failed to compile: the compiler complained that the size of the array had to be known at compile-time. I work on amd64. Perhaps the DRM drivers’ Makefile lack a define or an include somewhere? Because apparently a version not based on runtime code and not on POPCNT was selected.