mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-04 01:26:41 +00:00
[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:
parent
e06e113689
commit
3386f43f2a
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user