summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-09-13 16:04:06 +0000
committerSanjay Patel <spatel@rotateright.com>2018-09-13 16:04:06 +0000
commit6f00fc3317f3fba3d7602fe98889c74127141c8d (patch)
tree60a43f3cf3e9952aabfe938e4352b2cc94fefcac /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
parentf31f596152befc309a83f00f164b8145ca9485b3 (diff)
downloadbcm5719-llvm-6f00fc3317f3fba3d7602fe98889c74127141c8d.tar.gz
bcm5719-llvm-6f00fc3317f3fba3d7602fe98889c74127141c8d.zip
[InstCombine] reorder folds to reduce chance of infinite loops
I don't have a test case for this, but it's motivated by the discussion in D51964, and I've added TODO comments for the better fix - move simplifications into instsimplify because that's more efficient and reduces risk of infinite loops in instcombine caused by transforms trying to do the opposite folds. In this case, we know that the transform that tries to move 'not' through min/max can be fooled by the multiple uses of a value in another min/max, so try to squash the foldSPFofSPF() patterns first. llvm-svn: 342147
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp42
1 files changed, 20 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 622b6eace5d..aacb38ce06e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1084,11 +1084,13 @@ Instruction *InstCombiner::foldSPFofSPF(Instruction *Inner,
if (C == A || C == B) {
// MAX(MAX(A, B), B) -> MAX(A, B)
// MIN(MIN(a, b), a) -> MIN(a, b)
+ // TODO: This could be done in instsimplify.
if (SPF1 == SPF2 && SelectPatternResult::isMinOrMax(SPF1))
return replaceInstUsesWith(Outer, Inner);
// MAX(MIN(a, b), a) -> a
// MIN(MAX(a, b), a) -> a
+ // TODO: This could be done in instsimplify.
if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) ||
(SPF1 == SPF_SMAX && SPF2 == SPF_SMIN) ||
(SPF1 == SPF_UMIN && SPF2 == SPF_UMAX) ||
@@ -1101,6 +1103,7 @@ Instruction *InstCombiner::foldSPFofSPF(Instruction *Inner,
if (match(B, m_APInt(CB)) && match(C, m_APInt(CC))) {
// MIN(MIN(A, 23), 97) -> MIN(A, 23)
// MAX(MAX(A, 97), 23) -> MAX(A, 97)
+ // TODO: This could be done in instsimplify.
if ((SPF1 == SPF_UMIN && CB->ule(*CC)) ||
(SPF1 == SPF_SMIN && CB->sle(*CC)) ||
(SPF1 == SPF_UMAX && CB->uge(*CC)) ||
@@ -1121,6 +1124,7 @@ Instruction *InstCombiner::foldSPFofSPF(Instruction *Inner,
// ABS(ABS(X)) -> ABS(X)
// NABS(NABS(X)) -> NABS(X)
+ // TODO: This could be done in instsimplify.
if (SPF1 == SPF2 && (SPF1 == SPF_ABS || SPF1 == SPF_NABS)) {
return replaceInstUsesWith(Outer, Inner);
}
@@ -1793,6 +1797,19 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
Instruction::CastOps CastOp;
SelectPatternResult SPR = matchSelectPattern(&SI, LHS, RHS, &CastOp);
auto SPF = SPR.Flavor;
+ if (SPF) {
+ Value *LHS2, *RHS2;
+ if (SelectPatternFlavor SPF2 = matchSelectPattern(LHS, LHS2, RHS2).Flavor)
+ if (Instruction *R = foldSPFofSPF(cast<Instruction>(LHS), SPF2, LHS2,
+ RHS2, SI, SPF, RHS))
+ return R;
+ if (SelectPatternFlavor SPF2 = matchSelectPattern(RHS, LHS2, RHS2).Flavor)
+ if (Instruction *R = foldSPFofSPF(cast<Instruction>(RHS), SPF2, LHS2,
+ RHS2, SI, SPF, LHS))
+ return R;
+ // TODO.
+ // ABS(-X) -> ABS(X)
+ }
if (SelectPatternResult::isMinOrMax(SPF)) {
// Canonicalize so that
@@ -1830,7 +1847,9 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
// MIN(~a, ~b) -> ~MAX(a, b)
Value *A, *B;
if (match(LHS, m_Not(m_Value(A))) && match(RHS, m_Not(m_Value(B))) &&
- (!LHS->hasNUsesOrMore(3) || !RHS->hasNUsesOrMore(3))) {
+ !IsFreeToInvert(A, A->hasOneUse()) &&
+ !IsFreeToInvert(B, B->hasOneUse()) &&
+ (!LHS->hasNUsesOrMore(3) || !RHS->hasNUsesOrMore(3))) {
CmpInst::Predicate InvertedPred = getInverseMinMaxPred(SPF);
Value *InvertedCmp = Builder.CreateICmp(InvertedPred, A, B);
Value *NewSel = Builder.CreateSelect(InvertedCmp, A, B);
@@ -1840,27 +1859,6 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
if (Instruction *I = factorizeMinMaxTree(SPF, LHS, RHS, Builder))
return I;
}
-
- if (SPF) {
- // MAX(MAX(a, b), a) -> MAX(a, b)
- // MIN(MIN(a, b), a) -> MIN(a, b)
- // MAX(MIN(a, b), a) -> a
- // MIN(MAX(a, b), a) -> a
- // ABS(ABS(a)) -> ABS(a)
- // NABS(NABS(a)) -> NABS(a)
- Value *LHS2, *RHS2;
- if (SelectPatternFlavor SPF2 = matchSelectPattern(LHS, LHS2, RHS2).Flavor)
- if (Instruction *R = foldSPFofSPF(cast<Instruction>(LHS),SPF2,LHS2,RHS2,
- SI, SPF, RHS))
- return R;
- if (SelectPatternFlavor SPF2 = matchSelectPattern(RHS, LHS2, RHS2).Flavor)
- if (Instruction *R = foldSPFofSPF(cast<Instruction>(RHS),SPF2,LHS2,RHS2,
- SI, SPF, LHS))
- return R;
- }
-
- // TODO.
- // ABS(-X) -> ABS(X)
}
// See if we can fold the select into a phi node if the condition is a select.
OpenPOWER on IntegriCloud