Repository navigation
Incorrectly unified locals at -Zmir-opt-level=2 #79191
Copy link
Copy link
Closed
Labels
A-mir-optArea: MIR optimizationsArea: MIR optimizationsA-mir-opt-nrvoFixed by the Named Return Value Opt. (NRVO)Fixed by the Named Return Value Opt. (NRVO)C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Description
fn main() {
if f(false) != 1 {
panic!();
}
}
#[inline(always)]
fn f(use_y: bool) -> u8 {
let (x, y) = (1, 2);
if use_y { y } else { x }
}$ rustc -Zmir-opt-level=1 a.rs && ./a
$ rustc -Zmir-opt-level=2 a.rs && ./a
thread 'main' panicked at 'explicit panic', a.rs:3:9--- a.main.005-011.DestinationPropagation.before.mir
+++ a.main.005-011.DestinationPropagation.after.mir
@@ -1,70 +1,70 @@
-// MIR for `main` before DestinationPropagation
+// MIR for `main` after DestinationPropagation
fn main() -> () {
let mut _0: ();
let mut _1: bool;
let mut _2: u8;
let mut _3: !;
let _4: ();
let mut _5: !;
let mut _6: bool;
scope 1 (inlined f) {
debug use_y => _6;
let _7: u8;
let mut _8: bool;
scope 2 {
debug x => _2;
- debug y => _7;
+ debug y => _2;
}
}
bb0: {
StorageLive(_1);
- StorageLive(_2);
+ nop;
StorageLive(_6);
_6 = const false;
_2 = const 1_u8;
- StorageLive(_7);
- _7 = const 2_u8;
+ nop;
+ _2 = const 2_u8;
StorageLive(_8);
_8 = const false;
goto -> bb4;
}
bb1: {
- StorageDead(_2);
+ nop;
_0 = const ();
StorageDead(_1);
return;
}
bb2: {
- StorageDead(_2);
+ nop;
StorageLive(_4);
StorageLive(_5);
begin_panic::<&str>(const "explicit panic");
}
bb3: {
- _2 = _7;
+ nop;
goto -> bb4;
}
bb4: {
- StorageDead(_7);
+ nop;
StorageDead(_8);
StorageDead(_6);
_1 = Ne(_2, const 1_u8);
nop;
switchInt(move _2) -> [1_u8: bb1, otherwise: bb2];
}
}
<!-- TRIAGEBOT_START -->
<!-- TRIAGEBOT_ASSIGN_START -->
<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"JakobDegen"}$$TRIAGEBOT_ASSIGN_DATA_END -->
<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-mir-optArea: MIR optimizationsArea: MIR optimizationsA-mir-opt-nrvoFixed by the Named Return Value Opt. (NRVO)Fixed by the Named Return Value Opt. (NRVO)C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Activity
jonas-schievink commentedon Nov 26, 2020
Hmm, seems like it doesn't see the conflict because the assignment is unreachable:
Seems like we should consider assignments in dead blocks as propagation candidates. But does that fix the whole bug?
tmiasko commentedon Nov 27, 2020
I think that the main issue is that the notion of conflicts is based on liveness. A local could be never live but still conflict with others merely because there are dead stores to it.
For example, in code below
awill be unified withb(after running destination propagation for the second time after inlining):jonas-schievink commentedon Nov 28, 2020
Right. I think this briefly came up when implementing the pass, but I never wrote it down anywhere, nor could I produce an example.
Sounds like we need to run a dead store elimination pass before destination propagation, or change the analysis it uses to account for dead stores.
JakobDegen commentedon Feb 23, 2022
@rustbot claim
SparrowLii commentedon Apr 25, 2022
@JakobDegen I'm interested in this, too. Have you done some work? If not, I should be able to submit a PR soon
JakobDegen commentedon Apr 25, 2022
Yeah, I have a local branch up. Looking to open a PR today. The PR will be a draft though - the opt actually has significantly more problems than are reported in issues, and some of those problems being resolved is blocked on open questions about MIR semantics
Auto merge of rust-lang#96451 - JakobDegen:dest-prop, r=tmiasko
tmiasko commentedon Dec 5, 2022
Fixed in #96451.