Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1537,6 +1537,22 @@ return getConstant(false); } +Instruction *InstCombiner::FoldICmpCstUDivCst(ICmpInst &I, Value *Op, + ConstantInt *CI1, + ConstantInt *CI2, Value *A) { + // (icmp eq/ne (udiv i32 CI2, A), 0) -> (icmp ugt/ule A, CI2) + if (I.isEquality() && CI1->isZero()) { + ICmpInst::Predicate Pred = I.getPredicate() == ICmpInst::ICMP_EQ + ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULE; + return new ICmpInst(Pred, A, + ConstantInt::get(A->getType(), CI2->getValue())); + } + // FIXME: Handle (icmp ugt (udiv i32 CI2, A), CI1) and + // (icmp ult (udiv i32 CI2, A), CI1). + return nullptr; +} + /// visitICmpInstWithInstAndIntCst - Handle "icmp (instr, intcst)". /// Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, @@ -3287,8 +3303,12 @@ if (Instruction *Inst = FoldICmpCstShlCst(I, Op0, A, CI, CI2)) return Inst; } + if (match(Op0, m_UDiv(m_ConstantInt(CI2), m_Value(A)))) { + // (icmp eq/ne (udiv const2, A), const1) + if (Instruction *Inst = FoldICmpCstUDivCst(I, Op0, CI, CI2, A)) + return Inst; + } } - // If this comparison is a normal comparison, it demands all // bits, if it is a sign bit comparison, it only demands the sign bit. bool UnusedBit; Index: lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- lib/Transforms/InstCombine/InstCombineInternal.h +++ lib/Transforms/InstCombine/InstCombineInternal.h @@ -280,6 +280,8 @@ ConstantInt *CI1, ConstantInt *CI2); Instruction *FoldICmpCstShlCst(ICmpInst &I, Value *Op, Value *A, ConstantInt *CI1, ConstantInt *CI2); + Instruction *FoldICmpCstUDivCst(ICmpInst &I, Value *Op, ConstantInt *CI1, + ConstantInt *CI2, Value *A); Instruction *FoldICmpAddOpCst(Instruction &ICI, Value *X, ConstantInt *CI, ICmpInst::Predicate Pred); Instruction *FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS, Index: test/Transforms/InstCombine/compare-udiv.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/compare-udiv.ll @@ -0,0 +1,17 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +; CHECK-LABEL: @test1 +; CHECK: %cmp1 = icmp ugt i32 %a, 64 +define i1 @test1(i32 %a) { + %div = udiv i32 64, %a + %cmp1 = icmp eq i32 %div, 0 + ret i1 %cmp1 +} + +; CHECK-LABEL: @test2 +; CHECK: %cmp1 = icmp ult i32 %a, 65 +define i1 @test2(i32 %a) { + %div = udiv i32 64, %a + %cmp1 = icmp ne i32 %div, 0 + ret i1 %cmp1 +}