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 | 8e3a79da9f6e0b9f6c98f154d6ff2be8e66fc530 (patch) | |
tree | 1f8c95c55b0dd6d337b24c5fc9a772d84ea7c1ac /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 74186ab391c8e82b58efd015ae7fd91c322355ed (diff) | |
download | bcm5719-llvm-8e3a79da9f6e0b9f6c98f154d6ff2be8e66fc530.tar.gz bcm5719-llvm-8e3a79da9f6e0b9f6c98f154d6ff2be8e66fc530.zip |
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!
llvm-svn: 126991
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 3cfb2b7637e..44b0247e5ae 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/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)) |