Index: llvm/trunk/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp @@ -2857,6 +2857,17 @@ return getTrue(ITy); } + // x >=u x >> y + // x >=u x udiv y. + if (RBO && (match(RBO, m_LShr(m_Specific(LHS), m_Value())) || + match(RBO, m_UDiv(m_Specific(LHS), m_Value())))) { + // icmp pred X, (X op Y) + if (Pred == ICmpInst::ICMP_ULT) + return getFalse(ITy); + if (Pred == ICmpInst::ICMP_UGE) + return getTrue(ITy); + } + // handle: // CI2 << X == CI // CI2 << X != CI Index: llvm/trunk/test/Transforms/InstSimplify/compare.ll =================================================================== --- llvm/trunk/test/Transforms/InstSimplify/compare.ll +++ llvm/trunk/test/Transforms/InstSimplify/compare.ll @@ -409,6 +409,22 @@ ; CHECK: ret i1 false } +define i1 @lshr6(i32 %X, i32 %Y) { +; CHECK-LABEL: @lshr6( + %A = lshr i32 %X, %Y + %C = icmp ult i32 %X, %A + ret i1 %C +; CHECK: ret i1 false +} + +define i1 @lshr7(i32 %X, i32 %Y) { +; CHECK-LABEL: @lshr7( + %A = lshr i32 %X, %Y + %C = icmp uge i32 %X, %A + ret i1 %C +; CHECK: ret i1 true +} + define i1 @ashr1(i32 %x) { ; CHECK-LABEL: @ashr1( %s = ashr i32 -1, %x @@ -583,6 +599,22 @@ ; CHECK: ret i1 %C } +define i1 @udiv7(i32 %X, i32 %Y) { +; CHECK-LABEL: @udiv7( + %A = udiv i32 %X, %Y + %C = icmp ult i32 %X, %A + ret i1 %C +; CHECK: ret i1 false +} + +define i1 @udiv8(i32 %X, i32 %Y) { +; CHECK-LABEL: @udiv8( + %A = udiv i32 %X, %Y + %C = icmp uge i32 %X, %A + ret i1 %C +; CHECK: ret i1 true +} + define i1 @mul1(i32 %X) { ; CHECK-LABEL: @mul1( ; Square of a non-zero number is non-zero if there is no overflow.