Skip to content

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

Closed
@bjorn3

Description

@bjorn3
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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions