diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-12-20 03:04:38 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-12-20 03:04:38 +0000 |
commit | 0b6a0b02573bdf62eb3f0b000cfd7c7fcdbc1ccb (patch) | |
tree | 2da52620ca4fb7e1f3d8fe10f6438f4e3ad2dcee /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 2cb463ed080fe95c683dfe2212a6215a0c8b2803 (diff) | |
download | llvm-0b6a0b02573bdf62eb3f0b000cfd7c7fcdbc1ccb.zip llvm-0b6a0b02573bdf62eb3f0b000cfd7c7fcdbc1ccb.tar.gz llvm-0b6a0b02573bdf62eb3f0b000cfd7c7fcdbc1ccb.tar.bz2 |
InstSimplify: Optimize away pointless comparisons
(X & INT_MIN) ? X & INT_MAX : X into X & INT_MAX
(X & INT_MIN) ? X : X & INT_MAX into X
(X & INT_MIN) ? X | INT_MIN : X into X
(X & INT_MIN) ? X : X | INT_MIN into X | INT_MIN
llvm-svn: 224669
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 1db7ab7..b788265 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3155,10 +3155,10 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, if (const auto *ICI = dyn_cast<ICmpInst>(CondVal)) { Value *X; const APInt *Y; - if (ICI->isEquality() && + ICmpInst::Predicate Pred = ICI->getPredicate(); + if (ICmpInst::isEquality(Pred) && match(ICI->getOperand(0), m_And(m_Value(X), m_APInt(Y))) && match(ICI->getOperand(1), m_Zero())) { - ICmpInst::Predicate Pred = ICI->getPredicate(); const APInt *C; // (X & Y) == 0 ? X & ~Y : X --> X // (X & Y) != 0 ? X & ~Y : X --> X & ~Y @@ -3184,6 +3184,42 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, return Pred == ICmpInst::ICMP_EQ ? TrueVal : FalseVal; } } + if (Pred == ICmpInst::ICMP_SLT && match(ICI->getOperand(1), m_Zero())) { + // (X < 0) ? X : X | SignBit --> X | SignBit + if (TrueVal == ICI->getOperand(0) && + match(FalseVal, m_Or(m_Specific(TrueVal), m_SignBit()))) + return FalseVal; + // (X < 0) ? X | SignBit : X --> X + if (FalseVal == ICI->getOperand(0) && + match(TrueVal, m_Or(m_Specific(FalseVal), m_SignBit()))) + return FalseVal; + // (X < 0) ? X & INT_MAX : X --> X & INT_MAX + if (FalseVal == ICI->getOperand(0) && + match(TrueVal, m_And(m_Specific(FalseVal), m_MaxSignedValue()))) + return TrueVal; + // (X < 0) ? X : X & INT_MAX --> X + if (TrueVal == ICI->getOperand(0) && + match(FalseVal, m_And(m_Specific(TrueVal), m_MaxSignedValue()))) + return TrueVal; + } + if (Pred == ICmpInst::ICMP_SGT && match(ICI->getOperand(1), m_AllOnes())) { + // (X > -1) ? X : X | SignBit --> X + if (TrueVal == ICI->getOperand(0) && + match(FalseVal, m_Or(m_Specific(TrueVal), m_SignBit()))) + return TrueVal; + // (X > -1) ? X | SignBit : X --> X | SignBit + if (FalseVal == ICI->getOperand(0) && + match(TrueVal, m_Or(m_Specific(FalseVal), m_SignBit()))) + return TrueVal; + // (X > -1) ? X & INT_MAX : X --> X + if (FalseVal == ICI->getOperand(0) && + match(TrueVal, m_And(m_Specific(FalseVal), m_MaxSignedValue()))) + return FalseVal; + // (X > -1) ? X : X & INT_MAX --> X & INT_MAX + if (TrueVal == ICI->getOperand(0) && + match(FalseVal, m_And(m_Specific(TrueVal), m_MaxSignedValue()))) + return FalseVal; + } } return nullptr; |