Issue 150353
Summary Possible range of values isn't fully tracked after division
Labels new issue
Assignees
Reporter kornelski
    LLVM can't see an always-true relationship between two divided numbers:

```c
void check(unsigned long v) {   
 assert((v / 100) <= v);           // optimized out OK
    assert((v / 200) <= v);           // optimized out OK

    assert((v / 200) <= (v / 2)); // FAIL        
}
```

Oddly, adding `if (v >= 400) return;` makes it prove the third case is true:

```c
void check(unsigned long v) {   
 if (v >= 400) return;

    assert((v / 100) <= v);           // optimized out
    assert((v / 200) <= v);           // optimized out

    assert((v / 200) <= (v / 2));     // optimized out now too     
}
```

but with `if (v >= 401) return;` it becomes unknowable again.

Here's a real-world code that needs such reasoning to remove bounds checks: 

https://github.com/kornelski/rust/blob/999967a57dce987bbad353d152f03c3ef67d41f2/library/core/src/slice/sort/select.rs#L222-L232

I expected I'd only need to prove the `v.len()` is non-0 to remove the bounds checks, but I needed to add [more hints](https://github.com/rust-lang/rust/pull/144327/files#diff-062e0b3adced7b5e420b1c3774d1aaac361ef8800458c0ef95011c5fc9f3c8baR217-R239).
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to