Repository: rust
Issue: optimisation opportunity missed due to `assert!`
Labels: A-LLVM,C-enhancement,T-compiler,C-optimization

I have noticed interesting behaviour regarding `assert!` which was unexpected. I am not sure if this is a LLVM or Rust issue.

in the following code (See godbolt link below) I have a vec like structure `OwnedRegion`.
I want to iterate over the region (implemented as `slice::IterMut`) and populate an array.
I expect LLVM to do loop unrolling and loop vectorisation. If you place 
the necessary `intrinsics::assume` to trick llvm into removing the bound check you do 
indeed get the optimisations. However I wanted to replace the `assume` with an `assert!`
but that removes the optimisation even if combined with an `assume`! What I think is happening
is the bounds check is being reintroduced because the length check in the `assert!` is being moved into the for loop or elided completely because it duplicates the length check in the index operation. 

What should happen is the bounds check in the for loop should be lifted/elided because of the `assert!`

```
fn main() {
    let mut region: OwnedRegion<usize> = test::black_box(OwnedRegion::empty());
    let mut my_array: [usize; 128] = [0;128];

    // !!! The following assert blocks the loop vectorization optimization !!!
    // !!! remove the following line to enable Loop vectorization !!!
    assert!(region.len > 128 );

    // I know this assume is unsafe given that we created an empty OwnedRegion. 
    // I am only looking at the output assembly to see if optimization is run 
    unsafe {  assume(region.len() > 128) };
    for i in 0..128 {
       my_array[i] = region[i];
    } 
    println!("{:?}", &my_array[..32]);
}
```

with `assert!` and  `assume`:

inner loops is:
```asm
  cmp r15, rcx
  jbe .LBB6_5
  lea rcx, [rax - 2]
  mov rdx, qword ptr [rbx + 8*rax - 24]
  mov qword ptr [rbp + 8*rax - 1152], rdx
  cmp r15, rcx
  jbe .LBB6_4
  lea rcx, [rax - 1]
  mov rdx, qword ptr [rbx + 8*rax - 16]
  mov qword ptr [rbp + 8*rax - 1144], rdx
  cmp r15, rcx
  jbe .LBB6_8
  mov rcx, qword ptr [rbx + 8*rax - 8]
  mov qword ptr [rbp + 8*rax - 1136], rcx
  cmp r15, rax
  jbe .LBB6_10
  add rsi, 4
  mov rcx, qword ptr [rbx + 8*rax]
  mov qword ptr [rbp + 8*rax - 1128], rcx
```
where LBB6_4, LBB6_5, LBB6_8, and LBB6_10 jump to `std::panic` 

with just `assume`:

inner loops is:
```asm
.LBB3_3:
  movups xmm0, xmmword ptr [rbx + 8*rax]
  movups xmm1, xmmword ptr [rbx + 8*rax + 16]
  movups xmmword ptr [rbp + 8*rax - 1120], xmm0
  movups xmmword ptr [rbp + 8*rax - 1104], xmm1
  movups xmm0, xmmword ptr [rbx + 8*rax + 32]
  movups xmm1, xmmword ptr [rbx + 8*rax + 48]
  movups xmmword ptr [rbp + 8*rax - 1088], xmm0
  movups xmmword ptr [rbp + 8*rax - 1072], xmm1
  movups xmm0, xmmword ptr [rbx + 8*rax + 64]
  movups xmm1, xmmword ptr [rbx + 8*rax + 80]
  movups xmmword ptr [rbp + 8*rax - 1056], xmm0
  movups xmmword ptr [rbp + 8*rax - 1040], xmm1
  movups xmm0, xmmword ptr [rbx + 8*rax + 96]
  movups xmm1, xmmword ptr [rbx + 8*rax + 112]
  movups xmmword ptr [rbp + 8*rax - 1024], xmm0
  movups xmmword ptr [rbp + 8*rax - 1008], xmm1
  add rax, 16
  cmp rax, 128
  jne .LBB3_3
```

here is a [godbolt link](https://rust.godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAKxAEZSBnVAV2OUxAHIBSAJgGYwYbgFYAQgDNMAQwKtM0TADtMxPMgD6AB2nFpAWw2yCxBgEpRAEW4AGAIJ9Bw8VNnyI6Yqi3IA1hswAT0wdAmQECxFre0chUUkZOWIFBgRdTHRIywBqWwcBOJdE9zRkjTwlEwqGdXMrPNjnBLdkiAJMBgIshoKm1ySFCuQAG2YagDdMDT0lYExu%2B0wAD3biJWzkPXbs9s7ufjEG%2BzHMbM70EBAtE0uAZTTk9H3D44ZT88v9XV9VS4AFNKVVD6SyyaTPPInM4EC4gCpVJQ1ZAMS7SBgMZj6TAQ17vGGXbwokDcADsYjewwkpGyllUmCpNLpEgAsswCNSAJJKLBLTnc5asgik6wHSFvaGwtKpS6k8mYSnUgASaIQwpxDnsWmYACNocRmMgCNkAPIAdxU6AASphgHhUEp9gBhMCcNSzakAFRA2RdbuA%2B2wuTJeWyoey12I3vu6Se/EdHoDpBDYeGym9YzwAC9MEn7GHsgB6AvZAByqHa3o9CDwDGyX2IP2I2Sl2SUqA29reAEdmMp2LWJCQO%2BNdHhpEp2Nk8AA6TDTk3mjLW232qe1tAjtTjo2r7gANhsCYP0%2BToaL2SrNbX2WYSjGzGkw2y2swyGkUNNpzSkzrbOk2tTbJpGQftayIC9nzZICzGyS0KmAbVmAkKQm2qeQwIQU422IL5hlPQti1SGNsgADWNS1fwIf9AP1VNa1QCRYLGI1x3QZ8YLsP4OWyZQMWSWt9D/bU8GGQhAmve1hnErRUHRPAANOU1CAQID8PPQSqIU7JkhQvtTnA/cbDNC1lztB0D2yU1q3CHilEHNgOinJRNzHCdsQOM520IM5MEwfRa2SNF7Wo/TUDU4tP2kH51gqFzx0neydmrMDAi0OdwuyZlvlUa8VFA3RxMSzxvHCXxsggT9slQc1cgPI8bBg1idnbYTuSS05DN9eDDOyUSpAIPAsRPPMww0etG29AFt2BUEqKdPg9y62YLwDBoSWiDU7EGrQ8LjF1pE9b19oDBcTJtMynX2z0TtlfDHHiCpRJUeoRtDLVdQkdZUyUCAFopCQYIAWhOjNsyDF47HzfN/unb67vWu7XtyAQHqUJ7sSifD3uyT6eP0a5AggIGTtueVGNupH82Mpdzt3YNKaht6bmyaNHkuPyCaJ3NIcZqHvu9Gxud5qGxuyyNsimoEQTBfD8zVJH5YcBGYnsbbdudV14MOn1NdmE7aR0nGh2pq1aYdPbdeAa7%2BEDCmedDAhUtOD1dDmI19hyeIE0x0UVft5H%2BFR9GXv93GsB037eD3f7iZt5G91JylLhd4g3fB2Ww1vBhpCkdOGcZ1MjQjXJ%2BByGGI2nNFtBMIn1WF/M0QxLEICECuaw0O9hmGImLF9/3hcuD4QAYUT2EuCQvEMPRTW0XQCAYCAI2pGHvosfOgw2uXlaVja8jVy7Le1pb/Tjg36UFI2mxN0z7QPv1rdt%2Bn/fu8RHoqDHN7DMOmTGtlI73DSPlKSx1tlHQBicJDJ1dpgd2T9hZZxzh1OB9dQyF3DCYEuZcybTgrlXCMtc%2B4oNDI3TEChW4mGnO3Tu3czC9whkQ7Ig98TD1HhwEAE9gTTGkDPHQxB56/wIIvEwy9sGrwzqGRWW9d7bz3vjdWx8j6WxOnYBg1oJDzXEN7EUgZErXzNnfLWK0452zlijV%2BaN34h3zLjKuEc/pkxAfHL2Vg879zDP9eG0jd6qzkQY90F4jpKLjiowUGixBaJOroxcpsVzmw1vfIxj96FhhfmIN%2Bz1MZIxsQwAR/9AEx2yMDYxYCoLOKiK44WHiFYyJkT4naB8DoBOyI6YY9p3KBhaW0y%2Bp0aaxIaQ/CpX91gjDaf/ApRTAx6L6RbRpCZjHIMZreNWfllDtHQEIWu1TvGh2Ga0lQGgOH6DyVBf61JyyYXFgtKZF0ZkPxgiY3mSy5ErMqBkDZa9n41O2fvW5TTlSpBOv8lSUSzrTI1rMm6CyA5B0sZknZzYVROkVN6KUSAQBAtUAGMZZNl5UQrPHQBip7lQvzECy4qL/4ACpKWnOhLIeYni1rfN8b8uZgYuQ8idKDdp3Trm31ZZC5JDsnYmjZFqd2pcjEQzumYtJFiMmf1DLjCoPJsUKicjydMNRsyOIWh6QZjNzwljEJBESBBAYVA1cseC2RxhjlqjYBaZTrAHnERIqOEBqUx1RpyuFUimVHC2iy8FAyOUCjZFy7VPKQW9JuSGxJBroXmODn6oZVqli5IWvknF6atVZnmIUm6JSjT6oeYa4sxrTXDHNZalV1rlp2ukA6rNpTNH1FdevFtRpPU0ocT65YViUlfMDbI%2BpAq46EkuGGpYTpJ0gEtOOOYkb82rTjjGmJcaroJrLTsEVxoxWlMlc69UMrA7JthYqnGMV%2BRLDVQyOtSxvRzoXbMdyjpuUBl1VHZ1ib8zTsuA%2Bqlvb1UPo%2Bf6mI28fnxrZVVLQRJp2zrg5cF9cwPRhTjB%2Bm2kTjbRJvnErdMGd2OzSqKgg4rMG5DbT7aVCtZXpI/vhZVN673UgfU%2BpD87F2YDQ8u7Mn7C3FL3D%2Bndf6b0AeYwtL1ObQOMogxtKDBGTpzoQ3GZ9XGABik9ePtOw1fXD%2Bjx1JPwsR04%2B6yOHs9lRkUNHn50flQxrJ17VX2JA2J2DRIUOYE08CbT/GJlOKs7%2BsM/64QSajlJ1zPIwNDq8aO%2BRnAIUTo4ypx0anX3qeYF3XTPSN38ug4K4ze6D0Sss%2BE%2BofdT0woVYxpzywWPZHKG5tLcwMtdy/UJwLIn3Fk1kzvOL/SE3KZvYhjzXGuQjAzJMXzWG104dBZuhLAyiNFfMyVyjZXqOBtMWeuVKbL1Mec1HWlbH3PIbGxOUYEw32YewO14TJLgtidC4dvcEX703uixI4ddT4uJcDENzlqmOOebQ%2BNy7eApsYajaunRc3Y15cU/MoVu6SNmfIx7dbESKu0Z2/RwdSrau3pc%2B9zVp3OOvtBxdyb13oc2zu51h7oYQuAck8BknyxPsbwDX7BTi3BvJZvaEoHo3X3TewNlvl%2BG%2BeEahakvHqaCfpszcWoB7PH1k882L9rgD7vI9EzyQU4meTK4AVBN7rGPu9cVv1wzZPp1C9S8DrjPGocrpm7DvT82EfS4KzjqrDn4UPpN9myLyx2Mi9Q%2Bh99tPbsCdAab92DO9ePYN2yI3yxg9m7ZxbqLVvIPBsR/9gXqehTC7O%2BlrTru%2BPu95fpsFhfE1y/s/jq9SuNLHKNMdprTuK8%2Bar%2B07XraNue0Z9ke3afnsZ/b127I5v02c%2Bt/nsd%2BWkvwcFxGsv5OWuZd2h7nLeGBsy%2BR03vbNW29/xn7SxrpPmteZ34PxPw%2BguhiqZ82LP3D9KeL%2BG0vjuI%2BYDB2pzFwlzrwWz%2B0bzs1P0c3P0EUv2k273/0AKuy1zjwJSHy0WfzH3XwIHTwzWnxVznxky2W5yDWXwbwBx/xG3L0jyQIhxpzd3F1m093hyl3AJ3RPwvTPyD3wIT1VxzzDw12d1QFoMh2jwYIf0xxcS6yZ2wNwMzyNEIMt2ILkxHXsFxi%2BAqCJkTTQUAWSFiW9ElzFwo12BwJAAAmAn8G1FQFvUl3Znxkdh7jrhTBgUom0jNl4AMNALyxu2MI6FMPML8A0CsJsK8KUDsM5loScNQRcMAX0ECCMGID0ECG9HiEwxNVoF4AAA4pCj1xBHUDgMjsjNskZzwhAyiwALxMIjYu5qobVG5VAjQAJUA/AMJThWlvBbVXwiA1BMxZAzJYMBp9Asw%2BjVxyi4gSjiwxiKjkh9BUAfwCAqjBwailJlp0ZmpbIQpsgAAZVADoyYQ0EgYYgaUYsY/CeovhDZPQsyWGZQEuQMQo7IOhLbMMc8biXwNsU0JKK8EhLEa8BBXOW0SYdYBY2QSyU4TYRIDIICdYDmR2ffM2ecDKbiAwKqNGcSdo3wOoo0BY04FgVbICdEPyACcScCN4U4PARibwQYo4/oq8fUdYfCf4pBE1AkpuBQK4%2B0G4n6e5OOQo4lazRjIcPAJybIGwacacB46QuIhIpIh6HInIDkh0V%2BcrY/daXIJGLQN0AgYYJQDZPgXgWUYkfgdTNUXgXgakLNeI3QWU8QcU/gA0qIJ4uTTgMwUgYYLgEQTgUgMIzgGwL01ALgS0ZiTyVgScRwWgL0nA30l0103wEAfgfgacAATgABZMi9wUyRBaB%2BAbASQRB%2BASQSQ3SuAUyvSfS/TSAAzOAvSURBYoy/TXS4BYAkA0B8YRJVByBKBWytB2zIwlA8BgAEBtTAhSAJAzVVAUQIBtQuAKzWoCouAIzSBWysRKhjQ0SZyvSsAvhZhUwNzSB8BkhDQ6CURozSBlhXw2QOBOBFz4R5Q9yqh9ANzXTRJtQURIBXSqSzITzClAZNh6VAYTNnxLVAZHQBjAZUxJhdpLB%2BAayWAHI6BnyPSyy9yqz9ROhkBWwByhypJypcBCAhxwzqRUs2zUwmxwyzBIynzYz4zeBpwSRaBMibBeBaB8yRAkyMikzzT3TOBSzvSUKuAayQA6ynzSAmzEAQA8TxVOyIBuzey6Azz8BuiELizOBPS%2BLTyqzwzLJlJtJmIML%2BzBzhzKLozaFSA4yEzpwEyrLrKbKVLeLyz/SBLGAhLSB6yYyVLeBkKNKnK3LTLJhTAzIQAUygA%3D)