mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[NFC][InstSimplify] Refactoring ThreadCmpOverSelect function
Removed code duplication in ThreadCmpOverSelect and broke it into several smaller functions for reusing them. Differential Revision: https://reviews.llvm.org/D71158
This commit is contained in:
parent
05003a5b3c
commit
6605830fb0
@ -137,6 +137,71 @@ static bool isSameCompare(Value *V, CmpInst::Predicate Pred, Value *LHS,
|
|||||||
CRHS == LHS;
|
CRHS == LHS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Simplify comparison with true or false branch of select:
|
||||||
|
/// %sel = select i1 %cond, i32 %tv, i32 %fv
|
||||||
|
/// %cmp = icmp sle i32 %sel, %rhs
|
||||||
|
/// Compose new comparison by substituting %sel with either %tv or %fv
|
||||||
|
/// and see if it simplifies.
|
||||||
|
static Value *simplifyCmpSelCase(CmpInst::Predicate Pred, Value *LHS,
|
||||||
|
Value *RHS, Value *Cond,
|
||||||
|
const SimplifyQuery &Q, unsigned MaxRecurse,
|
||||||
|
Constant *TrueOrFalse) {
|
||||||
|
Value *SimplifiedCmp = SimplifyCmpInst(Pred, LHS, RHS, Q, MaxRecurse);
|
||||||
|
if (SimplifiedCmp == Cond) {
|
||||||
|
// %cmp simplified to the select condition (%cond).
|
||||||
|
return TrueOrFalse;
|
||||||
|
} else if (!SimplifiedCmp && isSameCompare(Cond, Pred, LHS, RHS)) {
|
||||||
|
// It didn't simplify. However, if composed comparison is equivalent
|
||||||
|
// to the select condition (%cond) then we can replace it.
|
||||||
|
return TrueOrFalse;
|
||||||
|
}
|
||||||
|
return SimplifiedCmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simplify comparison with true branch of select
|
||||||
|
static Value *simplifyCmpSelTrueCase(CmpInst::Predicate Pred, Value *LHS,
|
||||||
|
Value *RHS, Value *Cond,
|
||||||
|
const SimplifyQuery &Q,
|
||||||
|
unsigned MaxRecurse) {
|
||||||
|
return simplifyCmpSelCase(Pred, LHS, RHS, Cond, Q, MaxRecurse,
|
||||||
|
getTrue(Cond->getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simplify comparison with false branch of select
|
||||||
|
static Value *simplifyCmpSelFalseCase(CmpInst::Predicate Pred, Value *LHS,
|
||||||
|
Value *RHS, Value *Cond,
|
||||||
|
const SimplifyQuery &Q,
|
||||||
|
unsigned MaxRecurse) {
|
||||||
|
return simplifyCmpSelCase(Pred, LHS, RHS, Cond, Q, MaxRecurse,
|
||||||
|
getFalse(Cond->getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We know comparison with both branches of select can be simplified, but they
|
||||||
|
/// are not equal. This routine handles some logical simplifications.
|
||||||
|
static Value *handleOtherCmpSelSimplifications(Value *TCmp, Value *FCmp,
|
||||||
|
Value *Cond,
|
||||||
|
const SimplifyQuery &Q,
|
||||||
|
unsigned MaxRecurse) {
|
||||||
|
// If the false value simplified to false, then the result of the compare
|
||||||
|
// is equal to "Cond && TCmp". This also catches the case when the false
|
||||||
|
// value simplified to false and the true value to true, returning "Cond".
|
||||||
|
if (match(FCmp, m_Zero()))
|
||||||
|
if (Value *V = SimplifyAndInst(Cond, TCmp, Q, MaxRecurse))
|
||||||
|
return V;
|
||||||
|
// If the true value simplified to true, then the result of the compare
|
||||||
|
// is equal to "Cond || FCmp".
|
||||||
|
if (match(TCmp, m_One()))
|
||||||
|
if (Value *V = SimplifyOrInst(Cond, FCmp, Q, MaxRecurse))
|
||||||
|
return V;
|
||||||
|
// Finally, if the false value simplified to true and the true value to
|
||||||
|
// false, then the result of the compare is equal to "!Cond".
|
||||||
|
if (match(FCmp, m_One()) && match(TCmp, m_Zero()))
|
||||||
|
if (Value *V = SimplifyXorInst(
|
||||||
|
Cond, Constant::getAllOnesValue(Cond->getType()), Q, MaxRecurse))
|
||||||
|
return V;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/// Does the given value dominate the specified phi node?
|
/// Does the given value dominate the specified phi node?
|
||||||
static bool valueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
|
static bool valueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) {
|
||||||
Instruction *I = dyn_cast<Instruction>(V);
|
Instruction *I = dyn_cast<Instruction>(V);
|
||||||
@ -398,6 +463,12 @@ static Value *ThreadBinOpOverSelect(Instruction::BinaryOps Opcode, Value *LHS,
|
|||||||
/// In the case of a comparison with a select instruction, try to simplify the
|
/// In the case of a comparison with a select instruction, try to simplify the
|
||||||
/// comparison by seeing whether both branches of the select result in the same
|
/// comparison by seeing whether both branches of the select result in the same
|
||||||
/// value. Returns the common value if so, otherwise returns null.
|
/// value. Returns the common value if so, otherwise returns null.
|
||||||
|
/// For example, if we have:
|
||||||
|
/// %tmp = select i1 %cmp, i32 1, i32 2
|
||||||
|
/// %cmp1 = icmp sle i32 %tmp, 3
|
||||||
|
/// We can simplify %cmp1 to true, because both branches of select are
|
||||||
|
/// less than 3. We compose new comparison by substituting %tmp with both
|
||||||
|
/// branches of select and see if it can be simplified.
|
||||||
static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
|
static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
|
||||||
Value *RHS, const SimplifyQuery &Q,
|
Value *RHS, const SimplifyQuery &Q,
|
||||||
unsigned MaxRecurse) {
|
unsigned MaxRecurse) {
|
||||||
@ -418,32 +489,14 @@ static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
|
|||||||
|
|
||||||
// Now that we have "cmp select(Cond, TV, FV), RHS", analyse it.
|
// Now that we have "cmp select(Cond, TV, FV), RHS", analyse it.
|
||||||
// Does "cmp TV, RHS" simplify?
|
// Does "cmp TV, RHS" simplify?
|
||||||
Value *TCmp = SimplifyCmpInst(Pred, TV, RHS, Q, MaxRecurse);
|
Value *TCmp = simplifyCmpSelTrueCase(Pred, TV, RHS, Cond, Q, MaxRecurse);
|
||||||
if (TCmp == Cond) {
|
if (!TCmp)
|
||||||
// It not only simplified, it simplified to the select condition. Replace
|
return nullptr;
|
||||||
// it with 'true'.
|
|
||||||
TCmp = getTrue(Cond->getType());
|
|
||||||
} else if (!TCmp) {
|
|
||||||
// It didn't simplify. However if "cmp TV, RHS" is equal to the select
|
|
||||||
// condition then we can replace it with 'true'. Otherwise give up.
|
|
||||||
if (!isSameCompare(Cond, Pred, TV, RHS))
|
|
||||||
return nullptr;
|
|
||||||
TCmp = getTrue(Cond->getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does "cmp FV, RHS" simplify?
|
// Does "cmp FV, RHS" simplify?
|
||||||
Value *FCmp = SimplifyCmpInst(Pred, FV, RHS, Q, MaxRecurse);
|
Value *FCmp = simplifyCmpSelFalseCase(Pred, FV, RHS, Cond, Q, MaxRecurse);
|
||||||
if (FCmp == Cond) {
|
if (!FCmp)
|
||||||
// It not only simplified, it simplified to the select condition. Replace
|
return nullptr;
|
||||||
// it with 'false'.
|
|
||||||
FCmp = getFalse(Cond->getType());
|
|
||||||
} else if (!FCmp) {
|
|
||||||
// It didn't simplify. However if "cmp FV, RHS" is equal to the select
|
|
||||||
// condition then we can replace it with 'false'. Otherwise give up.
|
|
||||||
if (!isSameCompare(Cond, Pred, FV, RHS))
|
|
||||||
return nullptr;
|
|
||||||
FCmp = getFalse(Cond->getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both sides simplified to the same value, then use it as the result of
|
// If both sides simplified to the same value, then use it as the result of
|
||||||
// the original comparison.
|
// the original comparison.
|
||||||
@ -452,26 +505,8 @@ static Value *ThreadCmpOverSelect(CmpInst::Predicate Pred, Value *LHS,
|
|||||||
|
|
||||||
// The remaining cases only make sense if the select condition has the same
|
// The remaining cases only make sense if the select condition has the same
|
||||||
// type as the result of the comparison, so bail out if this is not so.
|
// type as the result of the comparison, so bail out if this is not so.
|
||||||
if (Cond->getType()->isVectorTy() != RHS->getType()->isVectorTy())
|
if (Cond->getType()->isVectorTy() == RHS->getType()->isVectorTy())
|
||||||
return nullptr;
|
return handleOtherCmpSelSimplifications(TCmp, FCmp, Cond, Q, MaxRecurse);
|
||||||
// If the false value simplified to false, then the result of the compare
|
|
||||||
// is equal to "Cond && TCmp". This also catches the case when the false
|
|
||||||
// value simplified to false and the true value to true, returning "Cond".
|
|
||||||
if (match(FCmp, m_Zero()))
|
|
||||||
if (Value *V = SimplifyAndInst(Cond, TCmp, Q, MaxRecurse))
|
|
||||||
return V;
|
|
||||||
// If the true value simplified to true, then the result of the compare
|
|
||||||
// is equal to "Cond || FCmp".
|
|
||||||
if (match(TCmp, m_One()))
|
|
||||||
if (Value *V = SimplifyOrInst(Cond, FCmp, Q, MaxRecurse))
|
|
||||||
return V;
|
|
||||||
// Finally, if the false value simplified to true and the true value to
|
|
||||||
// false, then the result of the compare is equal to "!Cond".
|
|
||||||
if (match(FCmp, m_One()) && match(TCmp, m_Zero()))
|
|
||||||
if (Value *V =
|
|
||||||
SimplifyXorInst(Cond, Constant::getAllOnesValue(Cond->getType()),
|
|
||||||
Q, MaxRecurse))
|
|
||||||
return V;
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user