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

Storage liveness is generated incorrectly for this code snippet #38669

Closed
nagisa opened this issue Dec 29, 2016 · 12 comments
Closed

Storage liveness is generated incorrectly for this code snippet #38669

nagisa opened this issue Dec 29, 2016 · 12 comments
Assignees
Labels
A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nagisa
Copy link
Member

nagisa commented Dec 29, 2016

fn good_loop() {
    let mut should_break = false;
    loop {
        if *should_break {
            break;
        }
        should_break = true;
    }
}

has

    bb1: {
        StorageLive(_4);                 // scope 1 at test.rs:4:12: 4:24
        _4 = _1;                         // scope 1 at test.rs:4:12: 4:24
        StorageDead(_4);                 // scope 1 at test.rs:4:24: 4:24
        if(_4) -> [true: bb2, false: bb3]; // scope 1 at test.rs:4:9: 6:10
    }

as the generated MIR. The LLVM IR ends up being generated correctly, because _4 is determined to be an SSA-like lvalue, but I fear that there may also be cases where equivalent of _4 would be forced into an alloca (and generate incorrect IR, after some compiler change maybe?) and would certainly interfere with MIR optimisations and MIR borrowck.

@Aatch Aatch added A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 9, 2017
@Aatch
Copy link
Contributor

Aatch commented Feb 9, 2017

/cc @rust-lang/compiler

@jrmuizel
Copy link
Contributor

jrmuizel commented Feb 9, 2017

It seems like this could possibly be the cause of #39455

@Aatch
Copy link
Contributor

Aatch commented Feb 9, 2017

Related: #39685

@arielb1 arielb1 added the I-wrong label Feb 9, 2017
@arielb1 arielb1 self-assigned this Feb 16, 2017
@arielb1
Copy link
Contributor

arielb1 commented Feb 16, 2017

This has to be fixed for MIR borrowck and the fix should not be that hard.

@arielb1 arielb1 added P-high High priority and removed I-nominated labels Feb 16, 2017
@nikomatsakis
Copy link
Contributor

@arielb1 I forget -- did we have a planned fix? =)

It seems like adopting the "extended basic block" formulation might help here, but given that IF is now SwitchInt, and we want to support the notion of a "complete set with no fallthrough", I'm not sure if it really does. That is, ultimately you want to push the StorageDead into the successors, right? Only other alternative I can see is adding implicit mutable condition codes, which I am not keen on.

@nikomatsakis
Copy link
Contributor

As discussed in @rust-lang/compiler meeting, the plan would be to introduce a fresh temporary with the value being tested. This temporary would have no storage-live/storage-dead, so it technically "lives forever", but since it's never borrowed, its lifetime can be trivially analyzed. In LLVM terms, it'd be represented as an SSA value.

@nikomatsakis
Copy link
Contributor

One other point is that we would want to be careful around constants (like false), which don't need said temporary.

@arielb1
Copy link
Contributor

arielb1 commented Feb 23, 2017

StorageDead is not really needed unless you have borrows.

arielb1 added a commit to arielb1/rust that referenced this issue Feb 27, 2017
In MIR construction, operands need to live exactly until they are used,
which is during the (sub)expression that made the call to `as_operand`.

Before this PR, operands lived until the end of the temporary scope,
which was sometimes unnecessarily longer and sometimes too short.

Fixes rust-lang#38669.
@bors bors closed this as completed in 906c06a Mar 3, 2017
@jrmuizel
Copy link
Contributor

jrmuizel commented Mar 7, 2017

It looks like this fixed #39455. Is it possible to get this uplifted all the way to stable? It seems like it can cause some pretty insidious problems.

@nagisa
Copy link
Member Author

nagisa commented Mar 7, 2017

Is it possible to get this uplifted all the way to stable?

No. We do not release point stable releases, except for very exceptional cases.

The fix seems non-trivial, so I doubt we’d backport it to beta either, especially given the fact that train rollover is near.

@jrmuizel
Copy link
Contributor

jrmuizel commented Mar 7, 2017

Do we have a good idea of how much code will be miscompiled without this fix?

@nagisa
Copy link
Member Author

nagisa commented Mar 8, 2017

Not much at all. There’s a number of conditions that are necessary to reproduce this issue and -Clto is a considerably rarely used option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html P-high High priority 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

5 participants