Repository: rust
Issue: Missed inference with array of nonzero divisors
Labels: I-slow,C-enhancement,T-compiler

This is an ER about a possible currently missed inference. I am not sure if here I am asking too much from LLVM. This code shows three different implementations of a simple function (that's reduced from other code):

```rust
#![feature(core_intrinsics)]
use std::intrinsics::assume;

pub fn foo1(x: u32, i: usize) -> Option<u32> {
    const PS: [u32; 6] = [2, 3, 5, 7, 11, 13];
    if i < PS.len() {
        let psi = PS[i];
        Some(x % psi)
    } else {
        None
    }
}

pub fn foo2(x: u32, i: usize) -> Option<u32> {
    const PS: [u32; 6] = [2, 3, 5, 7, 11, 13];
    if i < PS.len() {
        let psi = PS[i];
        unsafe { assume(psi != 0); }
        Some(x % psi)
    } else {
        None
    }
}

pub fn foo3(x: u32, i: usize) -> Option<u32> {
    match i {
        0 => Some(x % 2),
        1 => Some(x % 3),
        2 => Some(x % 5),
        3 => Some(x % 7),
        4 => Some(x % 11),
        5 => Some(x % 13),
        _ => None,
    }
}
```
Gives (rustc 1.46.0-nightly 3503f565e 2020-07-02):
```asm
foo1:
        push    rax
        cmp     rsi, 5
        ja      .LBB0_1
        lea     rax, [rip + .L__unnamed_1]
        mov     ecx, dword ptr [rax + 4*rsi]
        test    ecx, ecx
        je      .LBB0_5
        mov     eax, edi
        xor     edx, edx
        div     ecx
        mov     eax, 1
        pop     rcx
        ret
.LBB0_1:
        xor     eax, eax
        pop     rcx
        ret
.LBB0_5:
        lea     rdi, [rip + str.0]
        lea     rdx, [rip + .L__unnamed_2]
        mov     esi, 57
        call    qword ptr [rip + core::panicking::panic@GOTPCREL]
        ud2

foo2:
        cmp     rsi, 5
        ja      .LBB1_1
        lea     rcx, [rip + .L__unnamed_1]
        mov     eax, edi
        xor     edx, edx
        div     dword ptr [rcx + 4*rsi]
        mov     eax, 1
        ret
.LBB1_1:
        xor     eax, eax
        ret

foo3:
        cmp     rsi, 5
        ja      .LBB2_1
        lea     rax, [rip + .LJTI2_0]
        movsxd  rcx, dword ptr [rax + 4*rsi]
        add     rcx, rax
        jmp     rcx
.LBB2_3:
        and     edi, 1
        mov     eax, 1
        mov     edx, edi
        ret
.LBB2_1:
        xor     eax, eax
        mov     edx, edi
        ret
.LBB2_4:
        mov     eax, edi
        mov     ecx, 2863311531
        imul    rcx, rax
        shr     rcx, 33
        lea     eax, [rcx + 2*rcx]
        sub     edi, eax
        mov     eax, 1
        mov     edx, edi
        ret
.LBB2_5:
        mov     eax, edi
        mov     ecx, 3435973837
        imul    rcx, rax
        shr     rcx, 34
        lea     eax, [rcx + 4*rcx]
        sub     edi, eax
        mov     eax, 1
        mov     edx, edi
        ret
.LBB2_6:
        mov     eax, edi
        imul    rax, rax, 613566757
        shr     rax, 32
        mov     ecx, edi
        sub     ecx, eax
        shr     ecx
        add     ecx, eax
        shr     ecx, 2
        lea     eax, [8*rcx]
        sub     ecx, eax
        add     ecx, edi
        mov     eax, 1
        mov     edx, ecx
        ret
.LBB2_7:
        mov     eax, edi
        mov     ecx, 3123612579
        imul    rcx, rax
        shr     rcx, 35
        lea     eax, [rcx + 4*rcx]
        lea     eax, [rcx + 2*rax]
        sub     edi, eax
        mov     eax, 1
        mov     edx, edi
        ret
.LBB2_8:
        mov     eax, edi
        imul    rax, rax, 1321528399
        shr     rax, 34
        lea     ecx, [rax + 2*rax]
        lea     eax, [rax + 4*rcx]
        sub     edi, eax
        mov     eax, 1
        mov     edx, edi
        ret
.LJTI2_0:
        .long   .LBB2_3-.LJTI2_0
        .long   .LBB2_4-.LJTI2_0
        .long   .LBB2_5-.LJTI2_0
        .long   .LBB2_6-.LJTI2_0
        .long   .LBB2_7-.LJTI2_0
        .long   .LBB2_8-.LJTI2_0
```
The PS array contains only nonzero values, so "attempt to calculate the remainder with a divisor of zero" can't happen. Is this worth submitting upstream?