diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2016-12-19 16:28:53 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2016-12-19 16:28:53 +0000 |
| commit | 8296c6c96f7bcd1ec2b7a87808ad9ba7931bae9d (patch) | |
| tree | 9dad767dcd8a2d6ff20c65d7edaf0458c2df4f3a /llvm/lib | |
| parent | 9390d84d106e37cd6e3d20e217aed6f978d80e35 (diff) | |
| download | bcm5719-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')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 52 |
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; { |

