diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-11-27 06:32:46 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-11-27 06:32:46 +0000 |
commit | c6a5e1dd4f595b2ff437ee47345b9c27864ad232 (patch) | |
tree | 47ed58586fe32b5e92445a363a94bcca4f8e98ab /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | a5cd950c731c803e1a65159e53bbdad0ca255bef (diff) | |
download | llvm-c6a5e1dd4f595b2ff437ee47345b9c27864ad232.zip llvm-c6a5e1dd4f595b2ff437ee47345b9c27864ad232.tar.gz llvm-c6a5e1dd4f595b2ff437ee47345b9c27864ad232.tar.bz2 |
InstSimplify: Restore optimizations lost in r210006
This restores our ability to optimize:
(X & C) ? X & ~C : X into X & ~C
(X & C) ? X : X & ~C into X
(X & C) ? X | C : X into X
(X & C) ? X : X | C into X | C
llvm-svn: 222868
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 014bc0f..3c61cd1 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3055,6 +3055,40 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, if (isa<UndefValue>(FalseVal)) // select C, X, undef -> X return TrueVal; + if (const auto *ICI = dyn_cast<ICmpInst>(CondVal)) { + Value *X; + const APInt *Y; + if (ICI->isEquality() && + 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 + if (FalseVal == X && match(TrueVal, m_And(m_Specific(X), m_APInt(C))) && + *Y == ~*C) + return Pred == ICmpInst::ICMP_EQ ? FalseVal : TrueVal; + // (X & Y) == 0 ? X : X & ~Y --> X & ~Y + // (X & Y) != 0 ? X : X & ~Y --> X + if (TrueVal == X && match(FalseVal, m_And(m_Specific(X), m_APInt(C))) && + *Y == ~*C) + return Pred == ICmpInst::ICMP_EQ ? FalseVal : TrueVal; + + if (Y->isPowerOf2()) { + // (X & Y) == 0 ? X | Y : X --> X | Y + // (X & Y) != 0 ? X | Y : X --> X + if (FalseVal == X && match(TrueVal, m_Or(m_Specific(X), m_APInt(C))) && + *Y == *C) + return Pred == ICmpInst::ICMP_EQ ? TrueVal : FalseVal; + // (X & Y) == 0 ? X : X | Y --> X + // (X & Y) != 0 ? X : X | Y --> X | Y + if (TrueVal == X && match(FalseVal, m_Or(m_Specific(X), m_APInt(C))) && + *Y == *C) + return Pred == ICmpInst::ICMP_EQ ? TrueVal : FalseVal; + } + } + } + return nullptr; } |