summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-01-05 19:01:17 +0000
committerSanjay Patel <spatel@rotateright.com>2018-01-05 19:01:17 +0000
commit5b6aacf2c1ef0b58333e924743704c7d2a124e6e (patch)
treec518b8839498dfc63431b4f8680124898e76665e /llvm/lib/Transforms
parent0000060274aec30c7dda9ba4d8752a7cf83f778a (diff)
downloadbcm5719-llvm-5b6aacf2c1ef0b58333e924743704c7d2a124e6e.tar.gz
bcm5719-llvm-5b6aacf2c1ef0b58333e924743704c7d2a124e6e.zip
[InstCombine] add folds for min(~a, b) --> ~max(a, b)
Besides the bug of omitting the inverse transform of max(~a, ~b) --> ~min(a, b), the use checking and operand creation were off. We were potentially creating repeated identical instructions of existing values. This led to infinite looping after I added the extra folds. By using the simpler m_Not matcher and not creating new 'not' ops for a and b, we avoid that problem. It's possible that not using IsFreeToInvert() here is more limiting than the simpler matcher, but there are no tests for anything more exotic. It's also possible that we should relax the use checking further to handle a case like PR35834: https://bugs.llvm.org/show_bug.cgi?id=35834 ...but we can make that a follow-up if it is needed. llvm-svn: 321882
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp34
1 files changed, 12 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 6f26f7f5cd1..b02865c1290 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1551,6 +1551,18 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
Value *NewCast = Builder.CreateCast(CastOp, NewSI, SelType);
return replaceInstUsesWith(SI, NewCast);
}
+
+ // MAX(~a, ~b) -> ~MIN(a, b)
+ // MIN(~a, ~b) -> ~MAX(a, b)
+ Value *A, *B;
+ if (match(LHS, m_Not(m_Value(A))) && LHS->getNumUses() <= 2 &&
+ match(RHS, m_Not(m_Value(B))) && RHS->getNumUses() <= 2) {
+ CmpInst::Predicate InvertedPred =
+ getCmpPredicateForMinMax(getInverseMinMaxSelectPattern(SPF));
+ Value *InvertedCmp = Builder.CreateICmp(InvertedPred, A, B);
+ Value *NewSel = Builder.CreateSelect(InvertedCmp, A, B);
+ return BinaryOperator::CreateNot(NewSel);
+ }
}
if (SPF) {
@@ -1570,28 +1582,6 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
return R;
}
- // MAX(~a, ~b) -> ~MIN(a, b)
- if ((SPF == SPF_SMAX || SPF == SPF_UMAX) &&
- IsFreeToInvert(LHS, LHS->hasNUses(2)) &&
- IsFreeToInvert(RHS, RHS->hasNUses(2))) {
- // For this transform to be profitable, we need to eliminate at least two
- // 'not' instructions if we're going to add one 'not' instruction.
- int NumberOfNots =
- (LHS->hasNUses(2) && match(LHS, m_Not(m_Value()))) +
- (RHS->hasNUses(2) && match(RHS, m_Not(m_Value()))) +
- (SI.hasOneUse() && match(*SI.user_begin(), m_Not(m_Value())));
-
- if (NumberOfNots >= 2) {
- Value *NewLHS = Builder.CreateNot(LHS);
- Value *NewRHS = Builder.CreateNot(RHS);
- Value *NewCmp = SPF == SPF_SMAX ? Builder.CreateICmpSLT(NewLHS, NewRHS)
- : Builder.CreateICmpULT(NewLHS, NewRHS);
- Value *NewSI =
- Builder.CreateNot(Builder.CreateSelect(NewCmp, NewLHS, NewRHS));
- return replaceInstUsesWith(SI, NewSI);
- }
- }
-
// TODO.
// ABS(-X) -> ABS(X)
}
OpenPOWER on IntegriCloud