-
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
Eliminate some other bound checks when index comes from an enum #75529
Conversation
r? @lcnr (rust_highfive has picked a reviewer for you, use r? to override) |
Looks like it's even more brittle than I expected. How should I proceed? |
I found the |
@bugadani splitting the test sounds like the best course of action. |
Is there anything more I should do? |
hmm, this looks fairly innocent to me but I don't know too much about this. Is there anything actionable left for #13926, because otherwise I would prefer to close that issue and open separate issues for the remaining cases. Afaict this does fix #13926 (comment). I would prefer for someone else to take this over. |
One problem is that LLVM seems a bit limited in how it handles assumptions and because of this, this patch currently only works for some values, but not for others. This is why I think that issue can't yet be closed, but this is not something that can be fixed this way. The current test case is a bit of a lie because of this: it just demonstrates that some cases will be optimized, but I think I had to hunt for the numbers a bit since others did not get optimized... |
Hmm, can you then add some of these not yet optimized cases as a comment to the issue so it's clear what still needs to be done here? |
let cmp_end = | ||
bx.icmp(IntPredicate::IntULE, llval, ll_t_in_const); | ||
|
||
if *scalar.valid_range.start() > 0 { |
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.
Note to self/other reviewers: this condition should be enough because this is inside an if
that checks for scalar.valid_range.end() > scalar.valid_range.start()
(i.e. that the range does not wrap around, making it a valid simple unsigned integer range).
We could probably also support wraparound ranges, by treating them as signed integer ranges, but I guess that's less commonly used, especially for indexing?
I'm worried |
Awaiting bors try build completion |
⌛ Trying commit 6e670726116812a156cd0dd14cad1e5c58669f27 with merge 8f6a7e4210495c2a5cc5b0ab704b7ce17f2c5a35... |
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.
LGTM, but I'll let someone else have the final say wrt codegen
☀️ Try build successful - checks-actions, checks-azure |
Queued 8f6a7e4210495c2a5cc5b0ab704b7ce17f2c5a35 with parent 0301700, future comparison URL. |
Finished benchmarking try commit (8f6a7e4210495c2a5cc5b0ab704b7ce17f2c5a35): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
~This one fails: ~ Correction: this one passes with llvm11 // compile-flags: -O
// min-llvm-version: 10.0
#![crate_type = "lib"]
pub enum Bar {
A = 1,
B = 2
}
// CHECK-LABEL: @lookup_inc
#[no_mangle]
pub fn lookup_inc(buf: &[u8; 5], f: Bar) -> u8 {
// CHECK-NOT: panic_bounds_check
buf[f as usize + 1]
}
// CHECK-LABEL: @lookup_dec
#[no_mangle]
pub fn lookup_dec(buf: &[u8; 5], f: Bar) -> u8 {
// CHECK-NOT: panic_bounds_check
buf[f as usize - 1]
} So does the original case: // compile-flags: -O
// min-llvm-version: 10.0
#![crate_type = "lib"]
#[repr(u8)]
pub enum Exception {
Low = 5,
High = 10,
}
// CHECK-LABEL: @access
#[no_mangle]
pub fn access(array: &[usize; 12], exc: Exception) -> usize {
// CHECK-NOT: panic_bounds_check
array[(exc as u8 - 4) as usize]
} In fact, it is harder to find cases where the test passes. The only explanation I can think of is that LLVM has some other idea about the assumptions than me. |
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.
I don’t mind adding this either, but I wouldn’t hold my breath that any specific behaviour will last, especially across backend versions.
I’m saying this specifically because I don’t think the behaviour added tests verify is something we want to guarantee. It is sure nice when the optimisations just work out and manage to produce exactly the desired outcome, but I wouldn’t block e.g. LLVM upgrade over this test failing. This is also relevant to e.g. users that build with an external LLVM (such as debian).
I guess we can try to remember that these are not actually super important if we find them failing? Perhaps a comment would be good to somehow indicate that these tests are not normative.
otherwise r=me
Yeah this particular failure has been spuriously recently on many different PRs. |
⌛ Testing commit 1d157ce with merge 37ddb0103c726415513dd29225f339dc04627d4a... |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
💔 Test failed - checks-actions |
I love it :) Especially the empty log excerpt, which is actually accurate since the logs indicate network error :) @nagisa do you get notified about these, or should I keep pinging you? |
@bors retry |
⌛ Testing commit 1d157ce with merge b170fe1121dde6e9a7684038c8ccc5cb49f0c257... |
💔 Test failed - checks-actions |
Your PR failed (pretty log, raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem. Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
☀️ Test successful - checks-actions, checks-azure |
#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 #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 :)
ImprovesShould improve #13926 but does not close it because it's not exactly predictable, where bounds checks may pop up against the assumptions.