summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-12-19 16:28:53 +0000
committerSanjay Patel <spatel@rotateright.com>2016-12-19 16:28:53 +0000
commit8296c6c96f7bcd1ec2b7a87808ad9ba7931bae9d (patch)
tree9dad767dcd8a2d6ff20c65d7edaf0458c2df4f3a /llvm/lib/Transforms
parent9390d84d106e37cd6e3d20e217aed6f978d80e35 (diff)
downloadbcm5719-llvm-8296c6c96f7bcd1ec2b7a87808ad9ba7931bae9d.tar.gz
bcm5719-llvm-8296c6c96f7bcd1ec2b7a87808ad9ba7931bae9d.zip
[InstCombine] add folds for icmp (smax X, Y), X
This is a follow-up to: https://reviews.llvm.org/rL289855 (D27531) llvm-svn: 290111
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp52
1 files changed, 35 insertions, 17 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 6c4f4a1ce31..b986d80ac74 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3030,37 +3030,55 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) {
return nullptr;
}
-/// Fold icmp Pred smin(X, Y), X.
-static Instruction *foldICmpWithSMin(ICmpInst &Cmp) {
+/// Fold icmp Pred smin|smax(X, Y), X.
+static Instruction *foldICmpWithSMinMax(ICmpInst &Cmp) {
ICmpInst::Predicate Pred = Cmp.getPredicate();
Value *Op0 = Cmp.getOperand(0);
Value *X = Cmp.getOperand(1);
- // TODO: This should be expanded to handle smax/umax/umin.
+ // TODO: This should be expanded to handle umax/umin.
// Canonicalize minimum operand to LHS of the icmp.
- if (match(X, m_c_SMin(m_Specific(Op0), m_Value()))) {
+ if (match(X, m_c_SMin(m_Specific(Op0), m_Value())) ||
+ match(X, m_c_SMax(m_Specific(Op0), m_Value()))) {
std::swap(Op0, X);
Pred = Cmp.getSwappedPredicate();
}
Value *Y;
- if (!match(Op0, m_c_SMin(m_Specific(X), m_Value(Y))))
+ if (match(Op0, m_c_SMin(m_Specific(X), m_Value(Y)))) {
+ // smin(X, Y) == X --> X <= Y
+ // smin(X, Y) >= X --> X <= Y
+ if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_SGE)
+ return new ICmpInst(ICmpInst::ICMP_SLE, X, Y);
+
+ // smin(X, Y) != X --> X > Y
+ // smin(X, Y) < X --> X > Y
+ if (Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_SLT)
+ return new ICmpInst(ICmpInst::ICMP_SGT, X, Y);
+
+ // These cases should be handled in InstSimplify:
+ // smin(X, Y) <= X --> true
+ // smin(X, Y) > X --> false
return nullptr;
+ }
+ if (match(Op0, m_c_SMax(m_Specific(X), m_Value(Y)))) {
+ // smax(X, Y) == X --> X >= Y
+ // smax(X, Y) <= X --> X >= Y
+ if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_SLE)
+ return new ICmpInst(ICmpInst::ICMP_SGE, X, Y);
- // smin(X, Y) == X --> X <= Y
- // smin(X, Y) >= X --> X <= Y
- if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_SGE)
- return new ICmpInst(ICmpInst::ICMP_SLE, X, Y);
+ // smax(X, Y) != X --> X < Y
+ // smax(X, Y) > X --> X < Y
+ if (Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_SGT)
+ return new ICmpInst(ICmpInst::ICMP_SLT, X, Y);
- // smin(X, Y) != X --> X > Y
- // smin(X, Y) < X --> X > Y
- if (Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_SLT)
- return new ICmpInst(ICmpInst::ICMP_SGT, X, Y);
+ // These cases should be handled in InstSimplify:
+ // smax(X, Y) >= X --> true
+ // smax(X, Y) < X --> false
+ return nullptr;
+ }
- // These cases should be handled in InstSimplify:
- // smin(X, Y) <= X --> true
- // smin(X, Y) > X --> false
return nullptr;
}
@@ -4311,7 +4329,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
if (Instruction *Res = foldICmpBinOp(I))
return Res;
- if (Instruction *Res = foldICmpWithSMin(I))
+ if (Instruction *Res = foldICmpWithSMinMax(I))
return Res;
{
OpenPOWER on IntegriCloud