Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 02d8347

Browse files
committed
[InstSimplify] add folds for and-of-icmps with same operands
All of these (and a few more) are already handled by InstCombine, but we shouldn't have to wait until then to simplify these because they're cheap to deal with here in InstSimplify. This is the 'and' sibling of the earlier 'or' patch: https://reviews.llvm.org/rL288833 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288841 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9c3d059 commit 02d8347

File tree

2 files changed

+91
-197
lines changed

2 files changed

+91
-197
lines changed

lib/Analysis/InstructionSimplify.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,10 +1518,43 @@ static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
15181518
return nullptr;
15191519
}
15201520

1521+
/// Commuted variants are assumed to be handled by calling this function again
1522+
/// with the parameters swapped.
1523+
static Value *simplifyAndOfICmpsWithSameOperands(ICmpInst *Op0, ICmpInst *Op1) {
1524+
ICmpInst::Predicate Pred0, Pred1;
1525+
Value *A ,*B;
1526+
match(Op0, m_ICmp(Pred0, m_Value(A), m_Value(B)));
1527+
if (match(Op1, m_ICmp(Pred1, m_Specific(B), m_Specific(A))))
1528+
Op1->swapOperands();
1529+
1530+
if (!match(Op1, m_ICmp(Pred1, m_Specific(A), m_Specific(B))))
1531+
return nullptr;
1532+
1533+
// We have (icmp Pred0, A, B) & (icmp Pred1, A, B).
1534+
// If Op1 is always implied true by Op0, then Op0 is a subset of Op1, and we
1535+
// can eliminate Op1 from this 'and'.
1536+
if (ICmpInst::isImpliedTrueByMatchingCmp(Pred0, Pred1))
1537+
return Op0;
1538+
1539+
// Check for any combination of predicates that are guaranteed to be disjoint.
1540+
if ((Pred0 == ICmpInst::getInversePredicate(Pred1)) ||
1541+
(Pred0 == ICmpInst::ICMP_EQ && ICmpInst::isFalseWhenEqual(Pred1)) ||
1542+
(Pred0 == ICmpInst::ICMP_SLT && Pred1 == ICmpInst::ICMP_SGT) ||
1543+
(Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_UGT))
1544+
return getFalse(Op0->getType());
1545+
1546+
return nullptr;
1547+
}
1548+
1549+
/// Commuted variants are assumed to be handled by calling this function again
1550+
/// with the parameters swapped.
15211551
static Value *SimplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
15221552
if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/true))
15231553
return X;
15241554

1555+
if (Value *X = simplifyAndOfICmpsWithSameOperands(Op0, Op1))
1556+
return X;
1557+
15251558
// Look for this pattern: (icmp V, C0) & (icmp V, C1)).
15261559
Type *ITy = Op0->getType();
15271560
ICmpInst::Predicate Pred0, Pred1;

0 commit comments

Comments
 (0)