Uh oh!
There was an error while loading. Please reload this page.
UnreachableProp: Preserve unreachable branches for multiple targets - #99762
Conversation
rust-highfive
commented
Jul 26, 2022
r? @oli-obk (rust-highfive has picked a reviewer for you, use r? to override) |
rustbot
commented
Jul 26, 2022
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
This comment has been minimized.
This comment has been minimized.
eddyb
commented
Jul 26, 2022
Isn't the issue that it becomes And if that's indeed the problem, we could theoretically encode |
JakobDegen
commented
Jul 26, 2022
@eddyb agreed, especially because |
JakobDegen
commented
Jul 26, 2022
@bors try @rust-timer queue |
rust-timer
commented
Jul 26, 2022
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
bors
commented
Jul 26, 2022
⌛ Trying commit b100b4de35c0f64b160da79c678e3719281ca810 with merge a7fcf124a326d3a6b66d44389da7b1b49d5493ac... |
bors
commented
Jul 26, 2022
☀️ Try build successful - checks-actions |
rust-timer
commented
Jul 26, 2022
Queued a7fcf124a326d3a6b66d44389da7b1b49d5493ac with parent c9b3183, future comparison URL. |
rust-timer
commented
Jul 26, 2022
Finished benchmarking commit (a7fcf124a326d3a6b66d44389da7b1b49d5493ac): comparison url. Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results
CyclesResults
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Footnotes |
Noratrieb
commented
Jul 26, 2022
That's not bad, but also not great. I could try to also look at |
JakobDegen
commented
Jul 26, 2022
We shouldn't special case the intrinsic in this pass - we should instead add it to the lower intrinsics pass we have already (if it's not in there) |
Noratrieb
commented
Jul 27, 2022
The lower intrinsics pass does indeed lower unreachable already, so no improvements can be made there (assuming it runs before this pass, which it probably does). |
There was a problem hiding this comment.
This statement is only true because we don't have enough range information available, right?
There was a problem hiding this comment.
(Also: please add a codegen test showing this opt)
There was a problem hiding this comment.
src/test/codegen/match-optimizes-away.rs is the test for this, and found this issue in the opt originally. And this doesn't necessarily have to do with range information only, it could also be an unreachable_unchecked the user wrote themselves to enable another optimization. Deleting unreachable branches like this just isn't a good idea because it loses information.
There was a problem hiding this comment.
This statement is only true because we don't have enough range information available, right?
Potentially, but IMO it's a bad idea to turn this:
match x {Enum::A => 1,Enum::B => 2,Enum::C => 3,// Not in the user's code, but added for switchInt's "otherwise" target:// _ => unreachable_unchecked(),}into:
match x {Enum::A => 1,Enum::B => 2,
_ => 3,}It's erasing the refinement that the third case is only reachable when x is Enum::C.
You can recompute this refinement with an analysis, but why erase it in the first place?
See also #99762 (comment) where I suggest a solution (make otherwise optional).
Noratrieb
commented
Jul 29, 2022
And the merge conflicts are fixed |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
bors
commented
Aug 4, 2022
☔ The latest upstream changes (presumably #100087) made this pull request unmergeable. Please resolve the merge conflicts. |
6ec07a8 to
ace7e18CompareJakobDegen
commented
Aug 8, 2022
@bors try @rust-timer queue |
rust-timer
commented
Aug 8, 2022
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
bors
commented
Aug 8, 2022
⌛ Trying commit ace7e18a3e510b6e9851f073a64701ae63cc568c with merge 8a6fa0c7e08655ea76a5f9071ddeccf6ebe68ec2... |
bors
commented
Aug 8, 2022
☀️ Try build successful - checks-actions |
rust-timer
commented
Aug 8, 2022
Queued 8a6fa0c7e08655ea76a5f9071ddeccf6ebe68ec2 with parent f03ce30, future comparison URL. |
rust-timer
commented
Aug 9, 2022
Finished benchmarking commit (8a6fa0c7e08655ea76a5f9071ddeccf6ebe68ec2): comparison url. Instruction count
Max RSS (memory usage)Results
CyclesThis benchmark run did not return any relevant results for this metric. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Footnotes |
Before, UnreachablePropagation removed all unreachable branches.
This was a pessimization, as it removed information about
reachability that was used later in the optimization pipeline.
For example, this code
```rust
pub enum Two { A, B }
pub fn identity(x: Two) -> Two {
match x {
Two::A => Two::A,
Two::B => Two::B,
}
}
```
basically has `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]` for the match.
This allows it to be transformed into a simple `x`. If we remove the
unreachable branch, the transformation becomes illegal.It was disabled because of pathological behaviour of LLVM in some benchmarks. As of rust-lang#77680, this has been fixed. The problem there was that it caused pessimizations in some cases. These have now been fixed as well.
ace7e18 to
18bfcd3Compareoli-obk
commented
Aug 22, 2022
curious ctfe stress test regression. seems ok to me, but weird that it doesn't show up in the details of perfbots webpage. |
oli-obk
commented
Aug 22, 2022
@bors r+ |
bors
commented
Aug 22, 2022
bors
commented
Aug 22, 2022
bors
commented
Aug 22, 2022
☀️ Test successful - checks-actions |
rust-timer
commented
Aug 23, 2022
Finished benchmarking commit (015a824): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Footnotes |
| TerminatorKind::Unreachable | ||
| } else if is_unreachable(otherwise) { | ||
| // If there are multiple targets, don't delete unreachable branches (like an unreachable otherwise) | ||
| // unless otherwise is unrachable, in which case deleting a normal branch causes it to be merged with |
Before, UnreachablePropagation removed all unreachable branches. This was a pessimization, as it removed information about reachability that was used later in the optimization pipeline.
For example, this code
basically has
switchInt() -> [0: 0, 1: 1, otherwise: unreachable]for the match. This allows it to be transformed into a simplex. If we remove the unreachable branch, the transformation becomes illegal.This was the problem keeping
UnreachablePropagationfrom being enabled, so we can enable it now.Something similar already happened in #77800, but it did not show a perf improvement there. Let's try it again anyways!
Fixes#68105, although that issue has been fixed for a long time (see #77680).