Branchless `u64::leading_zeros` on x86

100 points wyf0

I've recently been interested in branchless programming, and I was using u64::leading_zeros for an algorithm. However, I noticed on Godbolt than on x86 architecture, leading_zeros was compiled into bsf instruction, and because because bsf doesn't support zero, compiler has to add a test before and a conditional branching.

I know that lzcnt exists now, and it can be enabled using -C target-feature=+lzcnt, as explained here, but that's not the subject of this post.

So I've wrote a branchless version of `u64::leading_zeros*, that you can find on the playground. We can verify on Godbolt that there is no more branching.

EDIT: as suggested in comment, the following version is simpler https://godbolt.org/z/1qYeG6cbo

Obviously, I've no idea of the performance of this function just by looking at the assembly, and I don't really expect it to be faster; at least, performance should be consistent. However, I don't have an x86 architecture to bench it (Apple Silicon spotted), so I decided to write a Reddit post to ask if there are interested folks who would mind doing it and share the results 😬

If I could, I would do a benchmark with multiple random numbers, to mess with CPU branch prediction, and also a benchmark with only one number, to (maybe) help the CPU. But I'm neither a CPU expert, nor a benchmark expert.