summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-12-06 19:05:46 +0000
committerSanjay Patel <spatel@rotateright.com>2016-12-06 19:05:46 +0000
commit9b1b2de348e391632bd1c8d4460ff03926269f2c (patch)
tree667444682ae2c6e6d19a7717170f7f2b01c66abb /llvm/lib/Analysis
parent0a683e7bfd45d97a44c31c0a82fe80672136e1e5 (diff)
downloadbcm5719-llvm-9b1b2de348e391632bd1c8d4460ff03926269f2c.tar.gz
bcm5719-llvm-9b1b2de348e391632bd1c8d4460ff03926269f2c.zip
[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 llvm-svn: 288841
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 26d1635802e..cc4a6ba9402 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1518,10 +1518,43 @@ static Value *simplifyUnsignedRangeCheck(ICmpInst *ZeroICmp,
return nullptr;
}
+/// Commuted variants are assumed to be handled by calling this function again
+/// with the parameters swapped.
+static Value *simplifyAndOfICmpsWithSameOperands(ICmpInst *Op0, ICmpInst *Op1) {
+ ICmpInst::Predicate Pred0, Pred1;
+ Value *A ,*B;
+ match(Op0, m_ICmp(Pred0, m_Value(A), m_Value(B)));
+ if (match(Op1, m_ICmp(Pred1, m_Specific(B), m_Specific(A))))
+ Op1->swapOperands();
+
+ if (!match(Op1, m_ICmp(Pred1, m_Specific(A), m_Specific(B))))
+ return nullptr;
+
+ // We have (icmp Pred0, A, B) & (icmp Pred1, A, B).
+ // If Op1 is always implied true by Op0, then Op0 is a subset of Op1, and we
+ // can eliminate Op1 from this 'and'.
+ if (ICmpInst::isImpliedTrueByMatchingCmp(Pred0, Pred1))
+ return Op0;
+
+ // Check for any combination of predicates that are guaranteed to be disjoint.
+ if ((Pred0 == ICmpInst::getInversePredicate(Pred1)) ||
+ (Pred0 == ICmpInst::ICMP_EQ && ICmpInst::isFalseWhenEqual(Pred1)) ||
+ (Pred0 == ICmpInst::ICMP_SLT && Pred1 == ICmpInst::ICMP_SGT) ||
+ (Pred0 == ICmpInst::ICMP_ULT && Pred1 == ICmpInst::ICMP_UGT))
+ return getFalse(Op0->getType());
+
+ return nullptr;
+}
+
+/// Commuted variants are assumed to be handled by calling this function again
+/// with the parameters swapped.
static Value *SimplifyAndOfICmps(ICmpInst *Op0, ICmpInst *Op1) {
if (Value *X = simplifyUnsignedRangeCheck(Op0, Op1, /*IsAnd=*/true))
return X;
+ if (Value *X = simplifyAndOfICmpsWithSameOperands(Op0, Op1))
+ return X;
+
// Look for this pattern: (icmp V, C0) & (icmp V, C1)).
Type *ITy = Op0->getType();
ICmpInst::Predicate Pred0, Pred1;
OpenPOWER on IntegriCloud