diff options
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index d0673d952d0..a295f65f387 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4624,34 +4624,51 @@ static Instruction *canonicalizeICmpBool(ICmpInst &I, } // Transform pattern like: -// (1 << Y) u<= X -// (1 << Y) u> X +// (1 << Y) u<= X or ~(-1 << Y) u< X +// (1 << Y) u> X or ~(-1 << Y) u>= X // Into: // (X l>> Y) != 0 // (X l>> Y) == 0 static Instruction *foldICmpWithHighBitMask(ICmpInst &Cmp, InstCombiner::BuilderTy &Builder) { - ICmpInst::Predicate Pred; + ICmpInst::Predicate Pred, NewPred; Value *X, *Y; - if (!match(&Cmp, - m_c_ICmp(Pred, m_OneUse(m_Shl(m_One(), m_Value(Y))), m_Value(X)))) - return nullptr; + if (match(&Cmp, + m_c_ICmp(Pred, m_OneUse(m_Shl(m_One(), m_Value(Y))), m_Value(X)))) { + // We want X to be the icmp's second operand, so swap predicate if it isn't. + if (Cmp.getOperand(0) == X) + Pred = Cmp.getSwappedPredicate(); - // We want X to be the icmp's second operand, so swap predicate if it is not. - if (Cmp.getOperand(0) == X) - Pred = Cmp.getSwappedPredicate(); + switch (Pred) { + case ICmpInst::ICMP_ULE: + NewPred = ICmpInst::ICMP_NE; + break; + case ICmpInst::ICMP_UGT: + NewPred = ICmpInst::ICMP_EQ; + break; + default: + return nullptr; + } + } else if (match(&Cmp, + m_c_ICmp(Pred, + m_OneUse(m_Not(m_Shl(m_AllOnes(), m_Value(Y)))), + m_Value(X)))) { + // We want X to be the icmp's second operand, so swap predicate if it isn't. + if (Cmp.getOperand(0) == X) + Pred = Cmp.getSwappedPredicate(); - ICmpInst::Predicate NewPred; - switch (Pred) { - case ICmpInst::ICMP_ULE: - NewPred = ICmpInst::ICMP_NE; - break; - case ICmpInst::ICMP_UGT: - NewPred = ICmpInst::ICMP_EQ; - break; - default: + switch (Pred) { + case ICmpInst::ICMP_ULT: + NewPred = ICmpInst::ICMP_NE; + break; + case ICmpInst::ICMP_UGE: + NewPred = ICmpInst::ICMP_EQ; + break; + default: + return nullptr; + } + } else return nullptr; - } Value *NewX = Builder.CreateLShr(X, Y, X->getName() + ".highbits"); Constant *Zero = Constant::getNullValue(NewX->getType()); |

