From 683170bf561dcaf79edccac3291319a023c7c0ca Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 20 Jul 2016 17:18:45 +0000 Subject: [PATCH] move decomposeBitTestICmp() to Transforms/Utils; NFC As noted in https://reviews.llvm.org/D22537 , we can use this functionality in visitSelectInstWithICmp() and InstSimplify, but currently we have duplicated code. llvm-svn: 276140 --- .../llvm/Transforms/Utils/CmpInstAnalysis.h | 5 +++ .../Transforms/InstCombine/InstCombineAndOrXor.cpp | 47 ---------------------- llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp | 44 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h b/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h index ed58765..5ec3888 100644 --- a/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h +++ b/llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h @@ -60,6 +60,11 @@ namespace llvm { /// equality comparison (which is signless). bool PredicatesFoldable(CmpInst::Predicate p1, CmpInst::Predicate p2); + /// Decompose an icmp into the form ((X & Y) pred Z) if possible. The returned + /// predicate is either == or !=. Returns false if decomposition fails. + bool decomposeBitTestICmp(const ICmpInst *I, CmpInst::Predicate &Pred, + Value *&X, Value *&Y, Value *&Z); + } // end namespace llvm #endif diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 4cdf154..4314b2b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -524,53 +524,6 @@ static unsigned conjugateICmpMask(unsigned Mask) { return NewMask; } -/// Decompose an icmp into the form ((X & Y) pred Z) if possible. -/// The returned predicate is either == or !=. Returns false if -/// decomposition fails. -static bool decomposeBitTestICmp(const ICmpInst *I, ICmpInst::Predicate &Pred, - Value *&X, Value *&Y, Value *&Z) { - ConstantInt *C = dyn_cast(I->getOperand(1)); - if (!C) - return false; - - switch (I->getPredicate()) { - default: - return false; - case ICmpInst::ICMP_SLT: - // X < 0 is equivalent to (X & SignBit) != 0. - if (!C->isZero()) - return false; - Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth())); - Pred = ICmpInst::ICMP_NE; - break; - case ICmpInst::ICMP_SGT: - // X > -1 is equivalent to (X & SignBit) == 0. - if (!C->isAllOnesValue()) - return false; - Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth())); - Pred = ICmpInst::ICMP_EQ; - break; - case ICmpInst::ICMP_ULT: - // X getValue().isPowerOf2()) - return false; - Y = ConstantInt::get(I->getContext(), -C->getValue()); - Pred = ICmpInst::ICMP_EQ; - break; - case ICmpInst::ICMP_UGT: - // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0. - if (!(C->getValue() + 1).isPowerOf2()) - return false; - Y = ConstantInt::get(I->getContext(), ~C->getValue()); - Pred = ICmpInst::ICMP_NE; - break; - } - - X = I->getOperand(0); - Z = ConstantInt::getNullValue(C->getType()); - return true; -} - /// Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E) /// Return the set of pattern classes (from MaskedICmpType) /// that both LHS and RHS satisfy. diff --git a/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp b/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp index 0b13005..60ae374 100644 --- a/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp +++ b/llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp @@ -62,3 +62,47 @@ bool llvm::PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) { (CmpInst::isSigned(p1) && ICmpInst::isEquality(p2)) || (CmpInst::isSigned(p2) && ICmpInst::isEquality(p1)); } + +bool llvm::decomposeBitTestICmp(const ICmpInst *I, CmpInst::Predicate &Pred, + Value *&X, Value *&Y, Value *&Z) { + ConstantInt *C = dyn_cast(I->getOperand(1)); + if (!C) + return false; + + switch (I->getPredicate()) { + default: + return false; + case ICmpInst::ICMP_SLT: + // X < 0 is equivalent to (X & SignBit) != 0. + if (!C->isZero()) + return false; + Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth())); + Pred = ICmpInst::ICMP_NE; + break; + case ICmpInst::ICMP_SGT: + // X > -1 is equivalent to (X & SignBit) == 0. + if (!C->isAllOnesValue()) + return false; + Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth())); + Pred = ICmpInst::ICMP_EQ; + break; + case ICmpInst::ICMP_ULT: + // X getValue().isPowerOf2()) + return false; + Y = ConstantInt::get(I->getContext(), -C->getValue()); + Pred = ICmpInst::ICMP_EQ; + break; + case ICmpInst::ICMP_UGT: + // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0. + if (!(C->getValue() + 1).isPowerOf2()) + return false; + Y = ConstantInt::get(I->getContext(), ~C->getValue()); + Pred = ICmpInst::ICMP_NE; + break; + } + + X = I->getOperand(0); + Z = ConstantInt::getNullValue(C->getType()); + return true; +} -- 2.7.4