-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add trailing_zeros and leading_zeros to non zero types #79114
add trailing_zeros and leading_zeros to non zero types #79114
Conversation
r? @m-ou-se (rust_highfive has picked a reviewer for you, use r? to override) |
I'm a fan 👍 This is important for avoiding dead ASM for the default x64 target, but can even improve the generated code on newer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a good addition!
Maybe it's good to explain the existence of these functions in the doc comments? Maybe something like On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
, or something in that direction.
7cda148
to
02a6aad
Compare
thanks for the comments have addressed them and pushed up the changes now |
02a6aad
to
e8864a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! One more small comment:
e8864a0
to
9bbc4c1
Compare
thanks again and fixed |
Thanks! @bors r+ rollup=always |
📌 Commit 9bbc4c1 has been approved by |
…eros, r=m-ou-se add trailing_zeros and leading_zeros to non zero types as a way towards being able to use the optimized intrinsics ctlz_nonzero and cttz_nonzero from stable. have not crated any tracking issue if this is not a solution that is wanted
Rollup of 11 pull requests Successful merges: - rust-lang#78361 (Updated the list of white-listed target features for x86) - rust-lang#78785 (linux: try to use libc getrandom to allow interposition) - rust-lang#78999 (stability: More precise location for deprecation lint on macros) - rust-lang#79039 (Tighten the bounds on atomic Ordering in std::sys::unix::weak::Weak) - rust-lang#79079 (Turn top-level comments into module docs in MIR visitor) - rust-lang#79114 (add trailing_zeros and leading_zeros to non zero types) - rust-lang#79131 (Enable AVX512 *epi64 variants by updating stdarch) - rust-lang#79133 (bootstrap: use the same version number for rustc and cargo) - rust-lang#79145 (Fix handling of panic calls) - rust-lang#79151 (Fix typo in `std::io::Write` docs) - rust-lang#79158 (type is too big -> values of the type are too big) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
I've tried this in my codebase, looking at the generated asm, and I've seen that in 100% of the cases, thanks sometimes to inlining, LLVM was able to infer that the input isn't zero, so no performance change has happened. |
In cases where the non-zero value are is created somewhat close to the place where leading_zeros/trailing_zeros is applied, it will definitely optimize this nicely. But just using |
@leonardo-m As another example, note that LLVM is currently not capable of optimizing this even when there's an explicit check for zero in the code before doing the |
Using "-C opt-level=2 -C target-cpu=native" it seems to optimize it well. |
With "-C opt-level=3 -C target-cpu=native -Z mir-opt-level=3" it seems to optimize well. |
@leonardo-m With that option it makes use of an instruction that does not need a special case for zero. It still doesn't make use of the fact that NonZero* cannot be zero. |
Oh, fun, thank you. It's still the same LLVM limit, I guess: |
Very interesting that |
as a way towards being able to use the optimized intrinsics ctlz_nonzero and cttz_nonzero from stable.
have not crated any tracking issue if this is not a solution that is wanted