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 | |
| 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
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 34 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/onehot_merge.ll | 13 |
2 files changed, 18 insertions, 29 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); + } } } diff --git a/llvm/test/Transforms/InstCombine/onehot_merge.ll b/llvm/test/Transforms/InstCombine/onehot_merge.ll index 6fd4fc66a52..c9f0c4d2690 100644 --- a/llvm/test/Transforms/InstCombine/onehot_merge.ll +++ b/llvm/test/Transforms/InstCombine/onehot_merge.ll @@ -34,21 +34,16 @@ bb: } ; Same as above but with operands commuted one of the ands, but not the other. -; TODO handle this form correctly define i1 @foo1_and_commuted(i32 %k, i32 %c1, i32 %c2) { ; CHECK-LABEL: @foo1_and_commuted( -; CHECK-NEXT: bb: ; CHECK-NEXT: [[K2:%.*]] = mul i32 [[K:%.*]], [[K]] ; CHECK-NEXT: [[TMP:%.*]] = shl i32 1, [[C1:%.*]] ; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 -2147483648, [[C2:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[K2]], [[TMP]] -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 -; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], [[K2]] -; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP2]], [[TMP6]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[TMP]], [[TMP4]] +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[K2]], [[TMP0]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], [[TMP0]] +; CHECK-NEXT: ret i1 [[TMP2]] ; -bb: %k2 = mul i32 %k, %k ; to trick the complexity sorting %tmp = shl i32 1, %c1 %tmp4 = lshr i32 -2147483648, %c2 |

