Repository: rust
Issue: Compiler do not remove slice bounds checks if index is guaranteed to be less than part of the length
Labels: A-LLVM,I-slow,C-bug

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

I tried this code:

```rust
pub fn test_assert(arr: &[u32], j: usize)->u32{
    assert!(j < arr.len() / 2);
    arr[j]
}
```

I expected to see this happen: Since for any nonnegative integer `i / 2 < i`,   `j < i / 2` implies that `j < i` so we should not have bounds check here at indexing.

Instead, this happened: Function checks j twice: first for `len / 2` then for `len`, and generates all code for panics.
```asm
example::test_assert:
        push    rax
        mov     rax, rsi
        shr     rax
        cmp     rax, rdx
        jbe     .LBB0_3
        cmp     rdx, rsi
        jae     .LBB0_2
        mov     eax, dword ptr [rdi + 4*rdx]
        pop     rcx
        ret
.LBB0_2:
        lea     rax, [rip + .L__unnamed_1]
        mov     rdi, rdx
        mov     rdx, rax
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2
.LBB0_3:
        lea     rdi, [rip + .L__unnamed_2]
        lea     rdx, [rip + .L__unnamed_3]
        mov     esi, 35
        call    qword ptr [rip + core::panicking::panic@GOTPCREL]
        ud2
```

I noticed, that if we shorten slice first, it can remove bounds checks. E.g. this code doesn't generate any bounds checks:
```rust
pub fn test_unreachable2(arr: &[u32], j: usize)->u32{
    let arr = &arr[..arr.len() / 2];
    if j >= arr.len() {
        unsafe {
            unreachable_unchecked();
        }
    }
    arr[j]
}
```

```asm
example::test_unreachable2:
        mov     eax, dword ptr [rdi + 4*rdx]
        ret
```

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.69.0 (84c898d65 2023-04-16)
binary: rustc
commit-hash: 84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc
commit-date: 2023-04-16
host: x86_64-unknown-linux-gnu
release: 1.69.0
LLVM version: 15.0.7
```
[Godbolt link.](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:rust,selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'pub+fn+test_assert(arr:+%26%5Bu32%5D,+j:+usize)-%3Eu32%7B%0A++++assert!!(j+%3C+arr.len()+/+2)%3B%0A++++arr%5Bj%5D%0A%7D%0A%0Ause+std::hint::unreachable_unchecked%3B%0Apub+fn+test_unreachable(arr:+%26%5Bu32%5D,+j:+usize)-%3Eu32%7B%0A++++if+j+%3E%3D+arr.len()+/+2+%7B%0A++++++++unsafe+%7B%0A++++++++++++unreachable_unchecked()%3B%0A++++++++%7D%0A++++%7D%0A++++arr%5Bj%5D%0A%7D%0A%0Apub+fn+test_unreachable2(arr:+%26%5Bu32%5D,+j:+usize)-%3Eu32%7B%0A++++let+arr+%3D+%26arr%5B..arr.len()+/+2%5D%3B%0A++++if+j+%3E%3D+arr.len()+%7B%0A++++++++unsafe+%7B%0A++++++++++++unreachable_unchecked()%3B%0A++++++++%7D%0A++++%7D%0A++++arr%5Bj%5D%0A%7D'),l:'5',n:'0',o:'Rust+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:r1690,deviceViewOpen:'1',filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:rust,libs:!(),options:'-Copt-level%3D3',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+rustc+1.69.0+(Editor+%231)',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)