Skip to content

Commit

Permalink
move decomposeBitTestICmp() to Transforms/Utils; NFC
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rotateright committed Jul 20, 2016
1 parent 481232e commit 683170b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 47 deletions.
5 changes: 5 additions & 0 deletions llvm/include/llvm/Transforms/Utils/CmpInstAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
47 changes: 0 additions & 47 deletions llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ConstantInt>(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 <u 2^n is equivalent to (X & ~(2^n-1)) == 0.
if (!C->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.
Expand Down
44 changes: 44 additions & 0 deletions llvm/lib/Transforms/Utils/CmpInstAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ConstantInt>(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 <u 2^n is equivalent to (X & ~(2^n-1)) == 0.
if (!C->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;
}

0 comments on commit 683170b

Please sign in to comment.