[InstCombine] (a+b) < a && (a+b) != 0 -> (0-b) < a iff a/b != 0 (PR43259)
authorRoman Lebedev <lebedev.ri@gmail.com>
Tue, 24 Sep 2019 16:10:50 +0000 (16:10 +0000)
committerRoman Lebedev <lebedev.ri@gmail.com>
Tue, 24 Sep 2019 16:10:50 +0000 (16:10 +0000)
commit5e050e91e1da02aecc5c1e8e08722f4183613c1f
treedb08d3c5c15b116b71c196ec9f5d7f2b9715d734
parentd745132b7b333c1cc421b033cb80a66819c50c29
[InstCombine] (a+b) < a && (a+b) != 0 -> (0-b) < a iff a/b != 0 (PR43259)

Summary:
This is again motivated by D67122 sanitizer check enhancement.
That patch seemingly worsens `-fsanitize=pointer-overflow`
overhead from 25% to 50%, which strongly implies missing folds.

For
```
#include <cassert>
char* test(char& base, signed long offset) {
  __builtin_assume(offset < 0);
  return &base + offset;
}
```
We produce

https://godbolt.org/z/r40U47

and again those two icmp's can be merged:
```
Name: 0
Pre: C != 0
  %adjusted = add i8 %base, C
  %not_null = icmp ne i8 %adjusted, 0
  %no_underflow = icmp ult i8 %adjusted, %base
  %r = and i1 %not_null, %no_underflow
=>
  %neg_offset = sub i8 0, C
  %r = icmp ugt i8 %base, %neg_offset
```
https://rise4fun.com/Alive/ALap
https://rise4fun.com/Alive/slnN

There are 3 other variants of this pattern,
i believe they all will go into InstSimplify.

https://bugs.llvm.org/show_bug.cgi?id=43259

Reviewers: spatel, xbolva00, nikic

Reviewed By: spatel

Subscribers: efriedma, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67849

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372768 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/result-of-add-of-negative-is-non-zero-and-no-underflow.ll