-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Optimize slice.{r}position result bounds check #45501
Conversation
r? @dtolnay (rust_highfive has picked a reviewer for you, use r? to override) |
3a32678
to
b9760de
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.
Nicely done!
@bors r+ |
📌 Commit b9760de has been approved by |
Travis is showing:
@bors r- |
b9760de
to
3529709
Compare
Sorry about that, broken tests... They're fixed now. |
@bors r=dtolnay |
📌 Commit 3529709 has been approved by |
⌛ Testing commit 35297095934dd2d0235a61af4dd91f3b304a9b55 with merge 916521726c4b54b3cfe96122e2c98d2b735f819d... |
💔 Test failed - status-travis |
@bors retry
|
⌛ Testing commit 35297095934dd2d0235a61af4dd91f3b304a9b55 with merge 18d66a16d23811fffa2aefad15122c676b7b7f23... |
💔 Test failed - status-travis |
Same error. It's legit then. @arthurprs Could you figure out what triggers #44899 here, and workaround it? |
3529709
to
d2dc4a4
Compare
I moved the assume to the end. Can we try again? |
src/libcore/slice/mod.rs
Outdated
}) | ||
}); | ||
if let Some(index) = result { | ||
unsafe { assume(index < self.len); } |
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.
self.len
seems wrong here.
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. I ran out of caffeine ☕
d2dc4a4
to
f014dc1
Compare
f014dc1
to
9591262
Compare
Ok, this is definitely not safe. |
src/libcore/slice/mod.rs
Outdated
let mut index = 0; | ||
self.search_while(None, move |elt| { | ||
if predicate(elt) { | ||
SearchWhile::Done(Some(index)) | ||
} else { | ||
index += 1; | ||
unsafe { assume(index < len); } |
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.
(This one should be before += 1 to be correct.)
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.
Good point. Moving it before the mutation probably kills the optimization though.
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.
@arthurprs What if you make it assume(0 < index && index <= len)
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.
We can try that too. Lets try a few more things.
A bit of a tangential thought, maybe we should have a version of assume that's like debug_assert in debug builds and assume in release builds. I'm a proponent of debug checking almost all unsafe code. |
ecb4f4a
to
896e6a5
Compare
896e6a5
to
c8d3814
Compare
Is there a way to have a test for this? I have a PR that will conflict massively with this, and selfishly I'd like an easy way to ensure I don't regress it by accident. Another thought: is this something that should be done for everything that's |
@arthurprs Edit the |
It failed in both musl builds :sad: Any ideas?
|
I'm gonna wait for #45595 to get in so I can try more combinations. I'm not felling hopeful though 😞 |
@arthurprs Have you tried to reproduce locally via Docker? Just run
|
I gave up trying, I keep getting
|
I am closing the PR because it doesn't look like it is being worked on. I filed #45964 to follow up and try again. It seems like |
…k, r=dtolnay Optimize slice.{r}position result bounds check Second attempt of rust-lang#45501 Fixes rust-lang#45964 Demo: https://godbolt.org/g/N4mBHp
Use the slice length to hint the optimizer about iter.position result Using the len of the iterator doesn't give the same result. That's also why we can't generalize it to all TrustedLen iterators. Problem demo: https://godbolt.org/g/MXg2ae Fix demo: https://godbolt.org/g/P8q5aZ Second attempt of #47333 Third attempt of #45501 Fixes #45964
Try to fix 48116 and 48192 The bug #48116 happens because of a misoptimization of the `import_path_to_string` function, where a `names` slice is empty but the `!names.is_empty()` branch is executed. https://github.com/rust-lang/rust/blob/4d2d3fc5dadf894a8ad709a5860a549f2c0b1032/src/librustc_resolve/resolve_imports.rs#L1015-L1042 Yesterday, @eddyb had locally reproduced the bug, and [came across the `position` function](https://mozilla.logbot.info/rust-infra/20180214#c14296834) where the `assume()` call is found to be suspicious. We have *not* concluded that this `assume()` causes #48116, but given [the reputation of `assume()`](#45501 (comment)), this seems higher relevant. Here we try to see if commenting it out can fix the errors. Later @alexcrichton has bisected and found a potential bug [in the LLVM side](#48116 (comment)). We are currently testing if reverting that LLVM commit is enough to stop the bug. If true, this PR can be reverted (keep the `assume()`) and we could backport the LLVM patch instead. (This PR also includes an earlier commit from #48127 for help debugging ICE happening in compile-fail/parse-fail tests.) The PR also reverts #48059, which seems to cause #48192. r? @alexcrichton cc @eddyb, @arthurprs (#47333)
All the unrolling makes it hard for llvm to optimize it out.
Sample https://godbolt.org/g/R9nLvC