From: Nick Lewycky Date: Fri, 4 Mar 2011 10:06:52 +0000 (+0000) Subject: Fold "icmp pred (srem X, Y), Y" like we do for urem. Handle signed comparisons X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=786792784e898f29febb3e7270d54b0e21e3c904;p=oota-llvm.git 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 --- diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 3cfb2b7637e..44b0247e5ae 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(LHS) || isa(RHS)) diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index ff11bbff77c..fba273550b1 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -379,7 +379,7 @@ define i1 @test38(i32 %x, i32 %y, i32 %z) { } ; PR9343 #1 -; CHECK: test39 +; CHECK: @test39 ; CHECK %B = icmp eq i32 %X, 0 define i1 @test39(i32 %X, i32 %Y) { %A = ashr exact i32 %X, %Y @@ -387,10 +387,19 @@ define i1 @test39(i32 %X, i32 %Y) { ret i1 %B } -; CHECK: test40 +; CHECK: @test40 ; CHECK: %B = icmp ne i32 %X, 0 define i1 @test40(i32 %X, i32 %Y) { %A = lshr exact i32 %X, %Y %B = icmp ne i32 %A, 0 ret i1 %B } + +; PR9343 #3 +; CHECK: @test41 +; CHECK: ret i1 true +define i1 @test41(i32 %X, i32 %Y) { + %A = urem i32 %X, %Y + %B = icmp ugt i32 %Y, %A + ret i1 %B +} diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll index 44c678c6f11..11295b7072b 100644 --- a/test/Transforms/InstSimplify/compare.ll +++ b/test/Transforms/InstSimplify/compare.ll @@ -236,6 +236,15 @@ define i1 @urem4(i32 %X) { ; CHECK: ret i1 %B } +define i1 @urem5(i16 %X, i32 %Y) { +; CHECK: @urem5 + %A = zext i16 %X to i32 + %B = urem i32 %A, %Y + %C = icmp slt i32 %B, %Y + ret i1 %C +; CHECK: ret i1 true +} + define i1 @srem1(i32 %X) { ; CHECK: @srem1 %A = srem i32 %X, -5 @@ -244,6 +253,15 @@ define i1 @srem1(i32 %X) { ; CHECK: ret i1 false } +define i1 @srem2(i32 %X, i32 %Y) { +; CHECK: @srem2 + %neg = sub i32 %Y, 0 + %A = srem i32 %X, %Y + %B = icmp slt i32 %A, %neg + ret i1 %B +; CHECK: ret i1 true +} + define i1 @udiv1(i32 %X) { ; CHECK: @udiv1 %A = udiv i32 %X, 1000000