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

[MIR-opt] Broken MIR for vec indexing with MIR inlining #67590

Closed
bjorn3 opened this issue Dec 24, 2019 · 2 comments
Closed

[MIR-opt] Broken MIR for vec indexing with MIR inlining #67590

bjorn3 opened this issue Dec 24, 2019 · 2 comments
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bjorn3
Copy link
Member

bjorn3 commented Dec 24, 2019

pub fn inxbuild(this: Vec<()>) {
    for j in 0..1 {
        this[j];
    }
}
$ rustc -V
rustc 1.42.0-nightly (9ae6cedb8 2019-12-23)
$ rustc src/lib.rs -Zmir-opt-level=3 --crate-type lib --emit mir,llvm-ir --sysroot rustc_codegen_cranelift/build_sysroot/sysroot
error: internal compiler error: src/librustc_codegen_ssa/mir/operand.rs:122: not immediate: OperandRef(Pair((i64:  %33 = load i64, i64* %32, align 8), (i64:  %35 = load i64, i64* %34, align 8)) @ TyLayout { ty: std::ops::Range<usize>, details: LayoutDetails { variants: Single { index: 0 }, fields: Arbitrary { offsets: [Size { raw: 0 }, Size { raw: 8 }], memory_index: [0, 1] }, abi: ScalarPair(Scalar { value: Int(I64, false), valid_range: 0..=18446744073709551615 }, Scalar { value: Int(I64, false), valid_range: 0..=18446744073709551615 }), largest_niche: None, align: AbiAndPrefAlign { abi: Align { pow2: 3 }, pref: Align { pow2: 3 } }, size: Size { raw: 16 } } })

The mir inliner doesn't seem to inline <Vec<()> as Index<usize>>::index when not using the patched sysroot of rustc_codegen_cranelift, so this problem doesn't trigger with the normal sysroot.

Optimized MIR
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
fn  inxbuild(_1: std::vec::Vec<()>) -> () {
    debug this => _1;                    // in scope 0 at src/lib.rs:1:17: 1:21
    let mut _0: ();                      // return place in scope 0 at src/lib.rs:1:32: 1:32
    let mut _2: std::ops::Range<usize>;  // in scope 0 at src/lib.rs:2:14: 2:18
    let mut _3: std::ops::Range<usize>;  // in scope 0 at src/lib.rs:2:14: 2:18
    let mut _4: std::ops::Range<usize>;  // in scope 0 at src/lib.rs:2:14: 2:18
    let mut _5: std::option::Option<usize>; // in scope 0 at src/lib.rs:2:14: 2:18
    let mut _6: &mut std::ops::Range<usize>; // in scope 0 at src/lib.rs:2:14: 2:18
    let mut _7: isize;                   // in scope 0 at src/lib.rs:2:9: 2:10
    let _9: ();                          // in scope 0 at src/lib.rs:3:9: 3:16
    let mut _10: &std::vec::Vec<()>;     // in scope 0 at src/lib.rs:3:9: 3:13
    scope 1 {
        debug iter => _4;                // in scope 1 at src/lib.rs:2:14: 2:18
        scope 2 {
            debug __next => _8;          // in scope 2 at src/lib.rs:2:14: 2:18
            let _8: usize;               // in scope 2 at src/lib.rs:2:9: 2:10
            scope 3 {
                debug val => _8;         // in scope 3 at src/lib.rs:2:9: 2:10
            }
            scope 4 {
                debug j => _8;           // in scope 4 at src/lib.rs:2:9: 2:10
                scope 6 {
                    debug self => _10;   // in scope 6 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/liballoc/vec.rs:1877:14: 1877:19
                    debug index => _8;   // in scope 6 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/liballoc/vec.rs:1877:21: 1877:26
                    let _11: &[()];      // in scope 6 at src/lib.rs:3:9: 3:16
                    scope 7 {
                        debug self => _11; // in scope 7 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2655:14: 2655:19
                        debug index => _8; // in scope 7 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2655:21: 2655:26
                        scope 8 {
                            debug self => _8; // in scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2789:14: 2789:18
                            debug slice => _11; // in scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2789:20: 2789:25
                            let _12: &(); // in scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2656:9: 2656:26
                            let mut _13: usize; // in scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2656:9: 2656:26
                            let mut _14: bool; // in scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2656:9: 2656:26
                        }
                    }
                }
            }
        }
    }
    scope 5 {
        debug self => _3;                // in scope 5 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/iter/traits/collect.rs:247:18: 247:22
    }

    bb0: {
        StorageLive(_2);                 // bb0[0]: scope 0 at src/lib.rs:2:14: 2:18
        StorageLive(_3);                 // bb0[1]: scope 0 at src/lib.rs:2:14: 2:18
        (_3.0: usize) = const 0usize;    // bb0[2]: scope 0 at src/lib.rs:2:14: 2:18
                                         // ty::Const
                                         // + ty: usize
                                         // + val: Value(Scalar(0x0000000000000000))
                                         // mir::Constant
                                         // + span: src/lib.rs:2:14: 2:15
                                         // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) }
        (_3.1: usize) = const 1usize;    // bb0[3]: scope 0 at src/lib.rs:2:14: 2:18
                                         // ty::Const
                                         // + ty: usize
                                         // + val: Value(Scalar(0x0000000000000001))
                                         // mir::Constant
                                         // + span: src/lib.rs:2:17: 2:18
                                         // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000001)) }
        _2 = move _3;                    // bb0[4]: scope 5 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/iter/traits/collect.rs:248:9: 248:13
        StorageDead(_3);                 // bb0[5]: scope 0 at src/lib.rs:2:17: 2:18
        StorageLive(_4);                 // bb0[6]: scope 0 at src/lib.rs:2:14: 2:18
        _4 = move _2;                    // bb0[7]: scope 0 at src/lib.rs:2:14: 2:18
        goto -> bb1;                     // bb0[8]: scope 1 at src/lib.rs:2:5: 4:6
    }

    bb1: {
        StorageLive(_5);                 // bb1[0]: scope 2 at src/lib.rs:2:14: 2:18
        _6 = &mut _4;                    // bb1[1]: scope 2 at src/lib.rs:2:14: 2:18
        _5 = const <std::ops::Range<usize> as std::iter::Iterator>::next(move _6) -> bb2; // bb1[2]: scope 2 at src/lib.rs:2:14: 2:18
                                         // ty::Const
                                         // + ty: for<'r> fn(&'r mut std::ops::Range<usize>) -> std::option::Option<<std::ops::Range<usize> as std::iter::Iterator>::Item> {<std::ops::Range<usize> as std::iter::Iterator>::next}
                                         // + val: Value(Scalar(<ZST>))
                                         // mir::Constant
                                         // + span: src/lib.rs:2:14: 2:18
                                         // + literal: Const { ty: for<'r> fn(&'r mut std::ops::Range<usize>) -> std::option::Option<<std::ops::Range<usize> as std::iter::Iterator>::Item> {<std::ops::Range<usize> as std::iter::Iterator>::next}, val: Value(Scalar(<ZST>)) }
    }

    bb2: {
        _7 = discriminant(_5);           // bb2[0]: scope 2 at src/lib.rs:2:9: 2:10
        switchInt(move _7) -> [0isize: bb3, 1isize: bb5, otherwise: bb4]; // bb2[1]: scope 2 at src/lib.rs:2:9: 2:10
    }

    bb3: {
        StorageDead(_5);                 // bb3[0]: scope 2 at src/lib.rs:2:17: 2:18
        StorageDead(_4);                 // bb3[1]: scope 0 at src/lib.rs:4:5: 4:6
        StorageDead(_2);                 // bb3[2]: scope 0 at src/lib.rs:2:17: 2:18
        drop(_1) -> bb6;                 // bb3[3]: scope 0 at src/lib.rs:5:1: 5:2
    }

    bb4: {
        unreachable;                     // bb4[0]: scope 2 at src/lib.rs:2:14: 2:18
    }

    bb5: {
        _8 = ((_5 as Some).0: usize);    // bb5[0]: scope 2 at src/lib.rs:2:9: 2:10
        StorageDead(_5);                 // bb5[1]: scope 2 at src/lib.rs:2:17: 2:18
        StorageLive(_9);                 // bb5[2]: scope 4 at src/lib.rs:3:9: 3:16
        _10 = &_1;                       // bb5[3]: scope 4 at src/lib.rs:3:9: 3:13
        _11 = const <std::vec::Vec<()> as std::ops::Deref>::deref(move _10) -> bb7; // bb5[4]: scope 6 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/liballoc/vec.rs:1878:23: 1878:29
                                         // ty::Const
                                         // + ty: for<'r> fn(&'r std::vec::Vec<()>) -> &'r <std::vec::Vec<()> as std::ops::Deref>::Target {<std::vec::Vec<()> as std::ops::Deref>::deref}
                                         // + val: Value(Scalar(<ZST>))
                                         // mir::Constant
                                         // + span: /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/liballoc/vec.rs:1878:23: 1878:29
                                         // + literal: Const { ty: for<'r> fn(&'r std::vec::Vec<()>) -> &'r <std::vec::Vec<()> as std::ops::Deref>::Target {<std::vec::Vec<()> as std::ops::Deref>::deref}, val: Value(Scalar(<ZST>)) }
    }

    bb6: {
        return;                          // bb6[0]: scope 0 at src/lib.rs:5:2: 5:2
    }

    bb7: {
        _13 = Len((*_11));               // bb7[0]: scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2791:10: 2791:24
        _14 = Lt(_8, _13);               // bb7[1]: scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2791:10: 2791:24
        assert(move _14, "index out of bounds: the len is move _13 but the index is _8") -> bb8; // bb7[2]: scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2791:10: 2791:24
    }

    bb8: {
        _12 = &(*_11)[_4];               // bb8[0]: scope 8 at /home/bjorn/Documenten/cg_clif/build_sysroot/sysroot_src/src/libcore/slice/mod.rs:2791:9: 2791:24
        _9 = (*_12);                     // bb8[1]: scope 4 at src/lib.rs:3:9: 3:16
        StorageDead(_9);                 // bb8[2]: scope 4 at src/lib.rs:3:16: 3:17
        goto -> bb1;                     // bb8[3]: scope 1 at src/lib.rs:2:5: 4:6
    }
}

The _12 = &(*_11)[_4]; is invalid because _4 is of type Range<usize>.

@rustbot modify label: +A-mir +C-bug +requires-nightly

@Centril Centril added A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 24, 2019
@Aaron1011
Copy link
Member

I think this will be fixed by #67796

@bjorn3
Copy link
Member Author

bjorn3 commented Jan 3, 2020

Yes. The crate from which this was reduced compiles fine now.

@bjorn3 bjorn3 closed this as completed Jan 3, 2020
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 C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. 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

3 participants