[ValueTracking] Expose implies via ValueTracking, NFC

Summary: This will allow a later patch to `JumpThreading` use this functionality.

Reviewers: reames

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D13971

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251488 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjoy Das 2015-10-28 03:20:19 +00:00
parent e06e113689
commit 3386f43f2a
3 changed files with 51 additions and 50 deletions

View File

@ -436,6 +436,15 @@ namespace llvm {
/// E.g. if RangeMD is !{i32 0, i32 10, i32 15, i32 20} then return [0, 20).
ConstantRange getConstantRangeFromMetadata(MDNode &RangeMD);
/// Return true if RHS is known to be implied by LHS. A & B must be i1
/// (boolean) values or a vector of such values. Note that the truth table for
/// implication is the same as <=u on i1 values (but not <=s!). The truth
/// table for both is:
/// | T | F (B)
/// T | T | F
/// F | T | T
/// (A)
bool isImpliedCondition(Value *LHS, Value *RHS);
} // end namespace llvm
#endif

View File

@ -2128,54 +2128,6 @@ static Constant *computePointerICmp(const DataLayout &DL,
return nullptr;
}
/// Return true if B is known to be implied by A. A & B must be i1 (boolean)
/// values or a vector of such values. Note that the truth table for
/// implication is the same as <=u on i1 values (but not <=s!). The truth
/// table for both is:
/// | T | F (B)
/// T | T | F
/// F | T | T
/// (A)
static bool implies(Value *A, Value *B) {
assert(A->getType() == B->getType() && "mismatched type");
Type *OpTy = A->getType();
assert(OpTy->getScalarType()->isIntegerTy(1));
// A ==> A by definition
if (A == B) return true;
if (OpTy->isVectorTy())
// TODO: extending the code below to handle vectors
return false;
assert(OpTy->isIntegerTy(1) && "implied by above");
ICmpInst::Predicate APred, BPred;
Value *I;
Value *L;
ConstantInt *CI;
// i +_{nsw} C_{>0} <s L ==> i <s L
if (match(A, m_ICmp(APred,
m_NSWAdd(m_Value(I), m_ConstantInt(CI)),
m_Value(L))) &&
APred == ICmpInst::ICMP_SLT &&
!CI->isNegative() &&
match(B, m_ICmp(BPred, m_Specific(I), m_Specific(L))) &&
BPred == ICmpInst::ICMP_SLT)
return true;
// i +_{nuw} C_{>0} <u L ==> i <u L
if (match(A, m_ICmp(APred,
m_NUWAdd(m_Value(I), m_ConstantInt(CI)),
m_Value(L))) &&
APred == ICmpInst::ICMP_ULT &&
!CI->isNegative() &&
match(B, m_ICmp(BPred, m_Specific(I), m_Specific(L))) &&
BPred == ICmpInst::ICMP_ULT)
return true;
return false;
}
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
@ -2224,7 +2176,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
// X >=u 1 -> X
if (match(RHS, m_One()))
return LHS;
if (implies(RHS, LHS))
if (isImpliedCondition(RHS, LHS))
return getTrue(ITy);
break;
case ICmpInst::ICMP_SLT:
@ -2238,7 +2190,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
return LHS;
break;
case ICmpInst::ICMP_ULE:
if (implies(LHS, RHS))
if (isImpliedCondition(LHS, RHS))
return getTrue(ITy);
break;
}

View File

@ -4081,3 +4081,43 @@ ConstantRange llvm::getConstantRangeFromMetadata(MDNode &Ranges) {
return CR;
}
bool llvm::isImpliedCondition(Value *LHS, Value *RHS) {
assert(LHS->getType() == RHS->getType() && "mismatched type");
Type *OpTy = LHS->getType();
assert(OpTy->getScalarType()->isIntegerTy(1));
// LHS ==> RHS by definition
if (LHS == RHS) return true;
if (OpTy->isVectorTy())
// TODO: extending the code below to handle vectors
return false;
assert(OpTy->isIntegerTy(1) && "implied by above");
ICmpInst::Predicate APred, BPred;
Value *I;
Value *L;
ConstantInt *CI;
// i +_{nsw} C_{>0} <s L ==> i <s L
if (match(LHS, m_ICmp(APred,
m_NSWAdd(m_Value(I), m_ConstantInt(CI)),
m_Value(L))) &&
APred == ICmpInst::ICMP_SLT &&
!CI->isNegative() &&
match(RHS, m_ICmp(BPred, m_Specific(I), m_Specific(L))) &&
BPred == ICmpInst::ICMP_SLT)
return true;
// i +_{nuw} C_{>0} <u L ==> i <u L
if (match(LHS, m_ICmp(APred,
m_NUWAdd(m_Value(I), m_ConstantInt(CI)),
m_Value(L))) &&
APred == ICmpInst::ICMP_ULT &&
!CI->isNegative() &&
match(RHS, m_ICmp(BPred, m_Specific(I), m_Specific(L))) &&
BPred == ICmpInst::ICMP_ULT)
return true;
return false;
}