Skip to content

Index argument for simd_insert no longer a const #85105

Open
@bjorn3

Description

@bjorn3

I tried this code:

let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);                                                 
let r = _mm_insert_epi16(a, 9, 0);                                                              
let e = _mm_setr_epi16(9, 1, 2, 3, 4, 5, 6, 7);                                                 
assert_eq_m128i(r, e);

I expected to see this happen: The index argument 9 is given as direct constant to the simd_insert intrinsic.

Instead, this happened: The cast of the index argument to u32 is stored in a local and then this local is passed to simd_insert. This causes cg_clif to error out as it requires a constant.

#[rustc_legacy_const_generics(2)]
pub unsafe fn _mm_insert_epi16<const IMM8: i32>(a: __m128i, i: i32) -> __m128i {                    
    static_assert_imm3!(IMM8);                                                                      
    transmute(simd_insert(a.as_i16x8(), IMM8 as u32, i as i16))                                     
}
[src/constant.rs:450] fx.mir = Body {
    basic_blocks: [
        BasicBlockData {
            statements: [
                StorageLive(_3),
                StorageLive(_4),
                StorageLive(_5),
                _5 = _1,
                StorageLive(_9),
                StorageLive(_10),
                _10 = move _5,
                _9 = _10,
                StorageDead(_10),
            ],
            terminator: Some(
                Terminator {
                    source_info: // ...
                    kind: _4 = std::intrinsics::transmute::<std::arch::x86_64::__m128i, core::core_arch::simd::i16x8>(move _9) -> bb3,
                },
            ),
            is_cleanup: false,
        },
        BasicBlockData {
            statements: [
                StorageDead(_7),
                StorageDead(_6),
                StorageDead(_4),
            ],
            terminator: Some(
                Terminator {
                    source_info: // ...
                    kind: _0 = std::intrinsics::transmute::<core::core_arch::simd::i16x8, std::arch::x86_64::__m128i>(move _3) -> bb2,
                },
            ),
            is_cleanup: false,
        },
        BasicBlockData {
            statements: [
                StorageDead(_3),
            ],
            terminator: Some(
                Terminator {
                    source_info: // ...
                    kind: return,
                },
            ),
            is_cleanup: false,
        },
        BasicBlockData {
            statements: [
                StorageDead(_9),
                StorageDead(_5),
                StorageLive(_6),
                _6 = const IMM8 as u32 (Misc),
                StorageLive(_7),
                StorageLive(_8),
                _8 = _2,
                _7 = move _8 as i16 (Misc),
                StorageDead(_8),
            ],
            terminator: Some(
                Terminator {
                    source_info: // ...
                    kind: _3 = core::core_arch::simd_llvm::simd_insert::<core::core_arch::simd::i16x8, i16>(move _4, move _6, move _7) -> bb1,
                },
            ),
            is_cleanup: false,
        },
    ],
    phase: Optimization,
    source: MirSource {
        instance: Item(
            WithOptConstParam {
                did: DefId(2:13246 ~ core[8231]::core_arch::x86::sse2::_mm_insert_epi16),
                const_param_did: None,
            },
        ),
        promoted: None,
    },
    local_decls: [
        LocalDecl {
            ty: std::arch::x86_64::__m128i,
            // ...
        },
        LocalDecl {
            ty: std::arch::x86_64::__m128i,
            // ...
        },
        LocalDecl {
            ty: i32,
            // ...
        },
        LocalDecl {
            ty: core::core_arch::simd::i16x8,
            // ...
        },
        LocalDecl {
            ty: core::core_arch::simd::i16x8,
            // ...
        },
        LocalDecl {
            ty: std::arch::x86_64::__m128i,
            // ...
        },
        LocalDecl {
            ty: u32,
            // ...
        },
        LocalDecl {
            ty: i16,
            // ...
        },
        LocalDecl {
            ty: i32,
            // ...
        },
        LocalDecl {
            ty: std::arch::x86_64::__m128i,
            // ...
        },
        LocalDecl {
            ty: std::arch::x86_64::__m128i,
            // ...
        },
    ],
    var_debug_info: [
        VarDebugInfo {
            name: "a",
            source_info: // ...
            value: _1,
        },
        VarDebugInfo {
            name: "i",
            source_info: // ...
            value: _2,
        },
        VarDebugInfo {
            name: "self",
            source_info: // ...
            value: _5,
        },
        VarDebugInfo {
            name: "self",
            source_info: // ...
            value: _10,
        },
    ],
    required_consts: [
        const core::core_arch::macros::ValidateConstImm::<IMM8, 0_i32, 7_i32>::VALID,
    ],
    // ...
}
[src/constant.rs:451] operand = move _6

Meta

rustc --version --verbose:

rustc 1.54.0-nightly (881c1ac40 2021-05-08)
binary: rustc
commit-hash: 881c1ac408d93bb7adaa3a51dabab9266e82eee8
commit-date: 2021-05-08
host: x86_64-unknown-linux-gnu
release: 1.54.0-nightly
LLVM version: 12.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-SIMDArea: SIMD (Single Instruction Multiple Data)A-craneliftThings relevant to the [future] cranelift backendC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions