-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Missed optimization when looping over bytes of a value #133528
Comments
As far as I can see, something very similar is at least partially fixed on LLVM trunk: https://godbolt.org/z/MzqG7rf9d. There's also another similar issue: llvm/llvm-project#117853, but I'm not sure if it's relevant to this particular issue. |
This comment has been minimized.
This comment has been minimized.
Looks like all 3 functions optimize to the same thing on LLVM trunk opt |
Hi Just wanted to know if this issue depends on LLVM releasing a new version that optimizes per-byte comparisons. |
The master branch has included the new version (LLVM 20). |
Got it, thank you! |
On the nightly, black_box_ne_bytes:
mov qword ptr [rsp - 8], rdi
lea rax, [rsp - 8]
cmp qword ptr [rsp - 8], -1
sete al
ret
direct:
cmp rdi, -1
sete al
ret I'd like to work on this issue, but I'm not sure how to go about writing good tests for this. I guess we could just test that |
@karolzwolak You should check the codegen tests (https://github.com/rust-lang/rust/blob/master/tests/codegen/) for example. You'll want to test that define noundef zeroext i1 @ne_bytes(i64 noundef %input) unnamed_addr {
start:
%_0 = icmp eq i64 %input, -1
ret i1 %_0
} Which will need a
|
Thanks, really appreciate the help. |
…133528, r=DianQK test(codegen): add looping_over_ne_bytes test for rust-lang#133528 Adds test for rust-lang#133528. I renamed the function to `looping_over_ne_bytes` to better reflect that it is doing. I also set the min llvm version to 20 as this was presumably a llvm bug that was fixed in version 20. I didn't tie the test to any specific architecture, as we are testing llvm output.
…iaskrgr Rollup of 9 pull requests Successful merges: - rust-lang#136865 (Perform deeper compiletest path normalization for `$TEST_BUILD_DIR` to account for compare-mode/debugger cases, and normalize long type file filename hashes) - rust-lang#136922 (Pattern types: Avoid having to handle an Option for range ends in the type system or the HIR) - rust-lang#137081 (change config.toml to bootstrap.toml) - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) Failed merges: - rust-lang#137147 (Add exclude to config.toml) r? `@ghost` `@rustbot` modify labels: rollup
…133528, r=DianQK test(codegen): add looping_over_ne_bytes test for rust-lang#133528 Adds test for rust-lang#133528. I renamed the function to `looping_over_ne_bytes` to better reflect that it is doing. I also set the min llvm version to 20 as this was presumably a llvm bug that was fixed in version 20. I didn't tie the test to any specific architecture, as we are testing llvm output.
…iaskrgr Rollup of 8 pull requests Successful merges: - rust-lang#136865 (Perform deeper compiletest path normalization for `$TEST_BUILD_DIR` to account for compare-mode/debugger cases, and normalize long type file filename hashes) - rust-lang#137081 (change config.toml to bootstrap.toml) - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) r? `@ghost` `@rustbot` modify labels: rollup
…133528, r=DianQK test(codegen): add looping_over_ne_bytes test for rust-lang#133528 Adds test for rust-lang#133528. I renamed the function to `looping_over_ne_bytes` to better reflect that it is doing. I also set the min llvm version to 20 as this was presumably a llvm bug that was fixed in version 20. I didn't tie the test to any specific architecture, as we are testing llvm output.
…iaskrgr Rollup of 7 pull requests Successful merges: - rust-lang#136865 (Perform deeper compiletest path normalization for `$TEST_BUILD_DIR` to account for compare-mode/debugger cases, and normalize long type file filename hashes) - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) r? `@ghost` `@rustbot` modify labels: rollup
…133528, r=DianQK test(codegen): add looping_over_ne_bytes test for rust-lang#133528 Adds test for rust-lang#133528. I renamed the function to `looping_over_ne_bytes` to better reflect that it is doing. I also set the min llvm version to 20 as this was presumably a llvm bug that was fixed in version 20. I didn't tie the test to any specific architecture, as we are testing llvm output.
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 6 pull requests Successful merges: - rust-lang#137103 ({json|html}docck: catch and error on deprecated syntax) - rust-lang#137632 (rustdoc: when merging target features, keep the highest stability) - rust-lang#137684 (Add rustdoc support for `--emit=dep-info[=path]`) - rust-lang#137794 (make qnx pass a test) - rust-lang#137801 (tests: Unignore target modifier tests on all platforms) - rust-lang#137826 (test(codegen): add looping_over_ne_bytes test for rust-lang#133528) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#137826 - karolzwolak:looping_over_ne_bytes_133528, r=DianQK test(codegen): add looping_over_ne_bytes test for rust-lang#133528 Adds test for rust-lang#133528. I renamed the function to `looping_over_ne_bytes` to better reflect that it is doing. I also set the min llvm version to 20 as this was presumably a llvm bug that was fixed in version 20. I didn't tie the test to any specific architecture, as we are testing llvm output.
Closed by #137826 |
I tried this code, which contains 3 functions which check if all the bits in a u64 are all ones:
I expected to see this happen:
ne_bytes()
should be optimized to the same thing asdirect()
, whileblack_box_ne_bytes()
should be optimized slightly worseInstead, this happened: I got the following assembly, where
ne_bytes()
is somehow optimized worse thanblack_box_ne_bytes()
Godbolt
Meta
Reproducible on godbolt with stable
rustc 1.82.0 (f6e511eec 2024-10-15)
and nightlyrustc 1.85.0-nightly (7db7489f9 2024-11-25)
The text was updated successfully, but these errors were encountered: