Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3287,7 +3287,16 @@ if (Instruction *Inst = FoldICmpCstShlCst(I, Op0, A, CI, CI2)) return Inst; } + // (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A) + if (CI->isZero() && match(Op0, m_UDiv(m_Value(A), m_Value(B)))) { + ICmpInst::Predicate Pred = I.getPredicate() == ICmpInst::ICMP_EQ + ? ICmpInst::ICMP_UGT + : ICmpInst::ICMP_ULE; + return new ICmpInst(Pred, B, A); + } } + // FIXME: Handle (icmp ugt (udiv i32 CI2, A), CI) and + // (icmp ult (udiv i32 CI2, A), CI). // If this comparison is a normal comparison, it demands all // bits, if it is a sign bit comparison, it only demands the sign bit. Index: test/Transforms/InstCombine/compare-udiv.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/compare-udiv.ll @@ -0,0 +1,41 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +; CHECK-LABEL: @test1 +; CHECK: %cmp1 = icmp ugt i32 %d, %n +define i1 @test1(i32 %n, i32 %d) { + %div = udiv i32 %n, %d + %cmp1 = icmp eq i32 %div, 0 + ret i1 %cmp1 +} + +; CHECK-LABEL: @test2 +; CHECK: %cmp1 = icmp ugt i32 %d, 64 +define i1 @test2(i32 %d) { + %div = udiv i32 64, %d + %cmp1 = icmp eq i32 %div, 0 + ret i1 %cmp1 +} + +; CHECK-LABEL: @test3 +; CHECK: %cmp1 = icmp ule i32 %d, %n +define i1 @test3(i32 %n, i32 %d) { + %div = udiv i32 %n, %d + %cmp1 = icmp ne i32 %div, 0 + ret i1 %cmp1 +} + +; CHECK-LABEL: @test4 +; CHECK: %cmp1 = icmp ult i32 %d, 65 +define i1 @test4(i32 %d) { + %div = udiv i32 64, %d + %cmp1 = icmp ne i32 %div, 0 + ret i1 %cmp1 +} + +; CHECK-LABEL: @test5 +; CHECK: ret i1 true +define i1 @test5(i32 %d) { + %div = udiv i32 -1, %d + %cmp1 = icmp ne i32 %div, 0 + ret i1 %cmp1 +}