diff options
author | Craig Topper <craig.topper@intel.com> | 2017-06-15 17:55:20 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2017-06-15 17:55:20 +0000 |
commit | 6eec9e21a5e6d0b5d59855c821d8ada8565824ac (patch) | |
tree | 6eaea212c36a25244d9eede4b395ca68967452bf /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | |
parent | 7e85b26549b93f314de441085f01a9b6b3f9d0f0 (diff) | |
download | bcm5719-llvm-6eec9e21a5e6d0b5d59855c821d8ada8565824ac.tar.gz bcm5719-llvm-6eec9e21a5e6d0b5d59855c821d8ada8565824ac.zip |
[InstCombine] Handle (iszero(A & K1) | iszero(A & K2)) -> (A & (K1 | K2)) != (K1 | K2) when the one of the Ands is commuted relative to the other
Currently we expect A to be on the same side in both Ands but nothing guarantees that.
While there also switch to using matchers for some of the code.
Differential Revision: https://reviews.llvm.org/D34230
llvm-svn: 305487
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 4fe3225a217..28968357400 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1599,31 +1599,25 @@ Value *InstCombiner::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS, ConstantInt *LHSC = dyn_cast<ConstantInt>(LHS->getOperand(1)); ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS->getOperand(1)); + // TODO support vector splats if (LHS->getPredicate() == ICmpInst::ICMP_EQ && LHSC && LHSC->isZero() && RHS->getPredicate() == ICmpInst::ICMP_EQ && RHSC && RHSC->isZero()) { - BinaryOperator *LAnd = dyn_cast<BinaryOperator>(LHS->getOperand(0)); - BinaryOperator *RAnd = dyn_cast<BinaryOperator>(RHS->getOperand(0)); - if (LAnd && RAnd && LAnd->hasOneUse() && RHS->hasOneUse() && - LAnd->getOpcode() == Instruction::And && - RAnd->getOpcode() == Instruction::And) { - - Value *Mask = nullptr; - Value *Masked = nullptr; - if (LAnd->getOperand(0) == RAnd->getOperand(0) && - isKnownToBeAPowerOfTwo(LAnd->getOperand(1), false, 0, CxtI) && - isKnownToBeAPowerOfTwo(RAnd->getOperand(1), false, 0, CxtI)) { - Mask = Builder->CreateOr(LAnd->getOperand(1), RAnd->getOperand(1)); - Masked = Builder->CreateAnd(LAnd->getOperand(0), Mask); - } else if (LAnd->getOperand(1) == RAnd->getOperand(1) && - isKnownToBeAPowerOfTwo(LAnd->getOperand(0), false, 0, CxtI) && - isKnownToBeAPowerOfTwo(RAnd->getOperand(0), false, 0, CxtI)) { - Mask = Builder->CreateOr(LAnd->getOperand(0), RAnd->getOperand(0)); - Masked = Builder->CreateAnd(LAnd->getOperand(1), Mask); - } + Value *A, *B, *C, *D; + if (match(LHS->getOperand(0), m_And(m_Value(A), m_Value(B))) && + match(RHS->getOperand(0), m_And(m_Value(C), m_Value(D)))) { + if (A == D || B == D) + std::swap(C, D); + if (B == C) + std::swap(A, B); - if (Masked) + if (A == C && + isKnownToBeAPowerOfTwo(B, false, 0, CxtI) && + isKnownToBeAPowerOfTwo(D, false, 0, CxtI)) { + Value *Mask = Builder->CreateOr(B, D); + Value *Masked = Builder->CreateAnd(A, Mask); return Builder->CreateICmp(ICmpInst::ICMP_NE, Masked, Mask); + } } } |