diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-03-04 10:06:52 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-03-04 10:06:52 +0000 |
commit | 786792784e898f29febb3e7270d54b0e21e3c904 (patch) | |
tree | f78e6e1fe0cbd54096297b2eb788daf50719d749 /lib/Analysis/InstructionSimplify.cpp | |
parent | 3a73e343d02ba3a00adf03311183cc0ccc960978 (diff) |
Fold "icmp pred (srem X, Y), Y" like we do for urem. Handle signed comparisons
in the urem case, though not the other way around. This is enough to get #3 from
PR9343!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126991 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | lib/Analysis/InstructionSimplify.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 3cfb2b7637..44b0247e5a 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1671,14 +1671,28 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, } } - if (LBO && match(LBO, m_URem(m_Value(), m_Specific(RHS)))) { + Value *V; + if (LBO && match(LBO, m_URem(m_Value(V), m_Specific(RHS)))) { + bool KnownNonNegative, KnownNegative; switch (Pred) { default: break; + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_SGE: + ComputeSignBit(LHS, KnownNonNegative, KnownNegative, TD); + if (!KnownNonNegative) + break; + // fall-through case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: return ConstantInt::getFalse(RHS->getContext()); + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_SLE: + ComputeSignBit(LHS, KnownNonNegative, KnownNegative, TD); + if (!KnownNonNegative) + break; + // fall-through case ICmpInst::ICMP_NE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: @@ -1686,6 +1700,21 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, } } + if (LBO && match(LBO, m_SRem(m_Value(), m_Specific(RHS)))) { + switch (Pred) { + default: + break; + case ICmpInst::ICMP_EQ: + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_SGE: + return ConstantInt::getFalse(RHS->getContext()); + case ICmpInst::ICMP_NE: + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_SLE: + return ConstantInt::getTrue(RHS->getContext()); + } + } + // If the comparison is with the result of a select instruction, check whether // comparing with either branch of the select always yields the same value. if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS)) |