summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2016-04-21 00:53:14 +0000
committerNick Lewycky <nicholas@mxc.ca>2016-04-21 00:53:14 +0000
commit762f8a8549c86014d0f1d73518c1133829202c1c (patch)
tree3fd53937d82cd0ad9914ef6303d3045fb96e75b5 /llvm/lib/Analysis/ValueTracking.cpp
parent410ae489b4989667f34621037ef84114375aa7e7 (diff)
downloadbcm5719-llvm-762f8a8549c86014d0f1d73518c1133829202c1c.tar.gz
bcm5719-llvm-762f8a8549c86014d0f1d73518c1133829202c1c.zip
Add optimization for 'icmp slt (or A, B), A' and some related idioms based on knowledge of the sign bit for A and B.
No matter what value you OR in to A, the result of (or A, B) is going to be UGE A. When A and B are positive, it's SGE too. If A is negative, OR'ing a value into it can't make it positive, but can increase its value closer to -1, therefore (or A, B) is SGE A. Working through all possible combinations produces this truth table: ``` A is +, -, +/- F F F + B is T F ? - ? F ? +/- ``` The related optimizations are flipping the 'slt' for 'sge' which always NOTs the result (if the result is known), and swapping the LHS and RHS while swapping the comparison predicate. There are more idioms left to implement (aren't there always!) but I've stopped here because any more would risk becoming unreasonable for reviewers. llvm-svn: 266939
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp36
1 files changed, 8 insertions, 28 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9fae8521064..7053195e2f3 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -195,6 +195,14 @@ bool llvm::isKnownPositive(Value *V, const DataLayout &DL, unsigned Depth,
isKnownNonZero(V, DL, Depth, AC, CxtI, DT);
}
+bool llvm::isKnownNegative(Value *V, const DataLayout &DL, unsigned Depth,
+ AssumptionCache *AC, const Instruction *CxtI,
+ const DominatorTree *DT) {
+ bool NonNegative, Negative;
+ ComputeSignBit(V, NonNegative, Negative, DL, Depth, AC, CxtI, DT);
+ return Negative;
+}
+
static bool isKnownNonEqual(Value *V1, Value *V2, const Query &Q);
bool llvm::isKnownNonEqual(Value *V1, Value *V2, const DataLayout &DL,
@@ -508,34 +516,6 @@ bool llvm::isValidAssumeForContext(const Instruction *I,
return ::isValidAssumeForContext(const_cast<Instruction *>(I), CxtI, DT);
}
-template<typename LHS, typename RHS>
-inline match_combine_or<CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>,
- CmpClass_match<RHS, LHS, ICmpInst, ICmpInst::Predicate>>
-m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
- return m_CombineOr(m_ICmp(Pred, L, R), m_ICmp(Pred, R, L));
-}
-
-template<typename LHS, typename RHS>
-inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::And>,
- BinaryOp_match<RHS, LHS, Instruction::And>>
-m_c_And(const LHS &L, const RHS &R) {
- return m_CombineOr(m_And(L, R), m_And(R, L));
-}
-
-template<typename LHS, typename RHS>
-inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Or>,
- BinaryOp_match<RHS, LHS, Instruction::Or>>
-m_c_Or(const LHS &L, const RHS &R) {
- return m_CombineOr(m_Or(L, R), m_Or(R, L));
-}
-
-template<typename LHS, typename RHS>
-inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Xor>,
- BinaryOp_match<RHS, LHS, Instruction::Xor>>
-m_c_Xor(const LHS &L, const RHS &R) {
- return m_CombineOr(m_Xor(L, R), m_Xor(R, L));
-}
-
static void computeKnownBitsFromAssume(Value *V, APInt &KnownZero,
APInt &KnownOne, unsigned Depth,
const Query &Q) {
OpenPOWER on IntegriCloud