{integer}::leading_zeros, 0, and undefined results

I noticed that the docs for the leading_zeros function on the various integer types do not mention that calling it on 0 could lead to undefined results. In particular, GCC's __builtin_clz{l,ll} functions specify that calling it on 0 leads to undefined results. On x86, the bsr instruction (used underneath) also mentions this.

Rust (LLVM) lowers these to bsr as well, and so would also be susceptible to this. Did I miss a warning on this somewhere? As mentioned, I couldn't find anything in the docs.

EDIT: Well, looked at the assembly again, and it does handle the zero case by returning (# of bits). So, should the docs mention this explicitly to not make people nervous? :slight_smile:

4 Likes

Yep, seems reasonable to mention this in the docs!

2 Likes

I should also mention that targeting Haswell or newer Intel will cause LLVM to lower the call to lzcnt, which has a defined result for 0 :slight_smile:. Anyway, should I file a github issue to make the documentation clear? Or will someone actively involved with rust development shepherd this request? :slight_smile:

1 Like

Internally, Rust uses LLVM's llvm.ctlz.* intristic which takes two arguments - source number and so called "is zero undefined" boolean argument. Rust provides false to that argument, which means that 0 is defined.

It probably should specify that when argument is 0, the returned value is number of bits of integer type.

1 Like