summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-06-25 18:51:44 +0000
committerSanjay Patel <spatel@rotateright.com>2019-06-25 18:51:44 +0000
commitfcfa056cebf63462adaa0a25e77785ec19604e29 (patch)
tree71c994f4671f63793fc5020361c13d89dbfd9a8b /llvm/lib
parent30519a68d5b954c70e5a19764914e8f506baf59e (diff)
downloadbcm5719-llvm-fcfa056cebf63462adaa0a25e77785ec19604e29.tar.gz
bcm5719-llvm-fcfa056cebf63462adaa0a25e77785ec19604e29.zip
[InstCombine] reduce checks for power-of-2-or-zero using ctpop
This follows up the transform from rL363956 to use the ctpop intrinsic when checking for power-of-2-or-zero. This is matching the isPowerOf2() patterns used in PR42314: https://bugs.llvm.org/show_bug.cgi?id=42314 But there's at least 1 instcombine follow-up needed to match the alternate form: (v & (v - 1)) == 0; We should have all of the backend expansions handled with: rL364319 (x86-specific changes still needed for optimal code based on subtarget) And the larger patterns to exclude zero as a power-of-2 are joining with this change after: rL364153 ( D63660 ) rL364246 Differential Revision: https://reviews.llvm.org/D63777 llvm-svn: 364341
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp22
1 files changed, 10 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 0a6c5a3b0b2..c62e2ba843c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3829,23 +3829,21 @@ Instruction *InstCombiner::foldICmpEquality(ICmpInst &I) {
return new ICmpInst(Pred, A, B);
// Canonicalize checking for a power-of-2-or-zero value:
- // (A & -A) == A --> (A & (A - 1)) == 0
- // (-A & A) == A --> (A & (A - 1)) == 0
- // A == (A & -A) --> (A & (A - 1)) == 0
- // A == (-A & A) --> (A & (A - 1)) == 0
- // TODO: This could be reduced by using the ctpop intrinsic.
+ // (A & -A) == A --> ctpop(A) < 2 (four commuted variants)
+ // (-A & A) != A --> ctpop(A) > 1 (four commuted variants)
A = nullptr;
- if (match(Op0, m_OneUse(m_c_And(m_OneUse(m_Neg(m_Specific(Op1))),
- m_Specific(Op1)))))
+ if (match(Op0, m_OneUse(m_c_And(m_Neg(m_Specific(Op1)), m_Specific(Op1)))))
A = Op1;
- else if (match(Op1, m_OneUse(m_c_And(m_OneUse(m_Neg(m_Specific(Op0))),
- m_Specific(Op0)))))
+ else if (match(Op1,
+ m_OneUse(m_c_And(m_Neg(m_Specific(Op0)), m_Specific(Op0)))))
A = Op0;
+
if (A) {
Type *Ty = A->getType();
- Value *Dec = Builder.CreateAdd(A, ConstantInt::getAllOnesValue(Ty));
- Value *And = Builder.CreateAnd(A, Dec);
- return new ICmpInst(Pred, And, ConstantInt::getNullValue(Ty));
+ CallInst *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, A);
+ return Pred == ICmpInst::ICMP_EQ
+ ? new ICmpInst(ICmpInst::ICMP_ULT, CtPop, ConstantInt::get(Ty, 2))
+ : new ICmpInst(ICmpInst::ICMP_UGT, CtPop, ConstantInt::get(Ty, 1));
}
return nullptr;
OpenPOWER on IntegriCloud