Skip to content
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

One more missed bounds check optimization #75525

Closed
bugadani opened this issue Aug 14, 2020 · 11 comments
Closed

One more missed bounds check optimization #75525

bugadani opened this issue Aug 14, 2020 · 11 comments
Assignees
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-mir-opt Area: MIR optimizations C-enhancement Category: An issue proposing an enhancement or a PR with one. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bugadani
Copy link
Contributor

bugadani commented Aug 14, 2020

https://godbolt.org/z/3TGbK9

It looks like bounds checks are not eliminated when more than one restriction is applied to the index variable (i.e. when it's range checked from two sides). Late edit: It's also interesting that the issue disappears for certain lower limits. For example if idx > 2 && idx < 8 is optimized, while if idx > 5 && idx < 8 is not.

Using assumptions, the bounds checks are removed as expected: https://godbolt.org/z/Ksn8dW
However, if any of the assumptions is a GE or LE instead of a GT or LT, the bounds checks are back: https://godbolt.org/z/YhK1rT

@tesuji

This comment has been minimized.

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-mir-opt Area: MIR optimizations C-enhancement Category: An issue proposing an enhancement or a PR with one. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 14, 2020
@tesuji
Copy link
Contributor

tesuji commented Aug 14, 2020

This could be improved by optimizing MIR. But the problem rely on LLVM too.
C version: https://godbolt.org/z/M3Ynq6
Clang trunk has more optimizations than v10.0.1.
GCC is still ahead in these optimizations.

@the8472
Copy link
Member

the8472 commented Aug 14, 2020

Same as #73396?

@davidbolvansky
Copy link

Posted on llvm bugzilla:
https://bugs.llvm.org/show_bug.cgi?id=47172

@bugadani
Copy link
Contributor Author

Thanks for that report!

I've played some more with my examples and these three cases are particularly interesting for me: https://godbolt.org/z/z6o3Pc
I'm curious if the improvements shown by Clang trunk are caused by clang or llvm, and if llvm, will it fix these as well. I guess time will tell this :)

@davidbolvansky
Copy link

Since Clang does no optimizations, this is all about about LLVM:)

Also worth to see:
https://reviews.llvm.org/D84547

bors added a commit to rust-lang-ci/rust that referenced this issue Sep 1, 2020
Eliminate some other bound checks when index comes from an enum

rust-lang#36962 introduced an assumption for the upper limit of the enum's value. This PR adds an assumption to the lower value as well.

I've modified the original codegen test to show that derived (in that case, adding 1) values also don't generate bounds checks.

However, this test is actually carefully crafted to not hit a bug: if the enum's variants are modified to 1 and 2 instead of 2 and 3, the test fails by adding a bounds check. I suppose this is an LLVM issue and rust-lang#75525, while not exactly in this context should be tracking it.

I'm not at all confident if this patch can be accepted, or even if it _should_ be accepted in this state. But I'm curious about what others think :)

~Improves~ Should improve rust-lang#13926 but does not close it because it's not exactly predictable, where bounds checks may pop up against the assumptions.
@nikic
Copy link
Contributor

nikic commented Sep 19, 2020

This happens because LLVM canonicalizes idx > 5 && idx < 8 to len & -2 == 6, at which point it fails to reason about the implied value range.

@nikic
Copy link
Contributor

nikic commented Sep 20, 2020

Partial fix: llvm/llvm-project@445db89

@nikic
Copy link
Contributor

nikic commented Sep 27, 2020

Partial fix 2: llvm/llvm-project@fe79061

@nikic nikic self-assigned this Feb 27, 2021
@jrmuizel
Copy link
Contributor

jrmuizel commented Mar 2, 2021

I confirmed that f2 and f3 are fixed by #81451

@bugadani
Copy link
Contributor Author

bugadani commented Mar 5, 2021

This issue has been fixed by the LLVM 12 update (#81451). Note that in the original compiler explorer link, f1 has a bounds check, which is expected there. Other examples are optimized now.

@bugadani bugadani closed this as completed Mar 5, 2021
bugadani added a commit to bugadani/rust that referenced this issue Mar 5, 2021
m-ou-se added a commit to m-ou-se/rust that referenced this issue Mar 9, 2021
m-ou-se added a commit to m-ou-se/rust that referenced this issue Mar 9, 2021
bors added a commit to rust-lang-ci/rust that referenced this issue Mar 9, 2021
Rollup of 8 pull requests

Successful merges:

 - rust-lang#81127 (Improve sift_down performance in BinaryHeap)
 - rust-lang#81879 (Added #[repr(transparent)] to core::cmp::Reverse)
 - rust-lang#82048 (or-patterns: disallow in `let` bindings)
 - rust-lang#82731 (Bump libc dependency of std to 0.2.88.)
 - rust-lang#82799 (Add regression test for rust-lang#75525)
 - rust-lang#82841 (Change x64 size checks to not apply to x32.)
 - rust-lang#82883 (Update Cargo)
 - rust-lang#82887 (Update CONTRIBUTING.md)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-mir-opt Area: MIR optimizations C-enhancement Category: An issue proposing an enhancement or a PR with one. I-slow Issue: Problems and improvements with respect to performance of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants