diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2018-09-11 22:40:20 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2018-09-11 22:40:20 +0000 |
| commit | 1cf0734b2f6b346993c41c18f4d6a9f2d1e11189 (patch) | |
| tree | e282f5e9a4dbcde551704a7e42e3358bad860cbe /llvm/lib/Transforms | |
| parent | 42e7cc1b0fdf3428ebd0dfd70a6e4efe162e1cd3 (diff) | |
| download | bcm5719-llvm-1cf0734b2f6b346993c41c18f4d6a9f2d1e11189.tar.gz bcm5719-llvm-1cf0734b2f6b346993c41c18f4d6a9f2d1e11189.zip | |
[InstCombine] add folds for unsigned-overflow compares
Name: op_ugt_sum
%a = add i8 %x, %y
%r = icmp ugt i8 %x, %a
=>
%notx = xor i8 %x, -1
%r = icmp ugt i8 %y, %notx
Name: sum_ult_op
%a = add i8 %x, %y
%r = icmp ult i8 %a, %x
=>
%notx = xor i8 %x, -1
%r = icmp ugt i8 %y, %notx
https://rise4fun.com/Alive/ZRxI
AFAICT, this doesn't interfere with any add-saturation patterns
because those have >1 use for the 'add'. But this should be
better for IR analysis and codegen in the basic cases.
This is another fold inspired by PR14613:
https://bugs.llvm.org/show_bug.cgi?id=14613
llvm-svn: 342004
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index e8e9e86d08b..875d6d9f053 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3047,6 +3047,18 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) { return nullptr; const CmpInst::Predicate Pred = I.getPredicate(); + Value *X; + + // Convert add-with-unsigned-overflow comparisons into a 'not' with compare. + // (Op1 + X) <u Op1 --> ~Op1 <u X + // Op0 >u (Op0 + X) --> X >u ~Op0 + if (match(Op0, m_OneUse(m_c_Add(m_Specific(Op1), m_Value(X)))) && + Pred == ICmpInst::ICMP_ULT) + return new ICmpInst(Pred, Builder.CreateNot(Op1), X); + if (match(Op1, m_OneUse(m_c_Add(m_Specific(Op0), m_Value(X)))) && + Pred == ICmpInst::ICMP_UGT) + return new ICmpInst(Pred, X, Builder.CreateNot(Op0)); + bool NoOp0WrapProblem = false, NoOp1WrapProblem = false; if (BO0 && isa<OverflowingBinaryOperator>(BO0)) NoOp0WrapProblem = |

