summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-09-11 22:40:20 +0000
committerSanjay Patel <spatel@rotateright.com>2018-09-11 22:40:20 +0000
commit1cf0734b2f6b346993c41c18f4d6a9f2d1e11189 (patch)
treee282f5e9a4dbcde551704a7e42e3358bad860cbe /llvm/lib/Transforms
parent42e7cc1b0fdf3428ebd0dfd70a6e4efe162e1cd3 (diff)
downloadbcm5719-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.cpp12
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 =
OpenPOWER on IntegriCloud