Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2439,6 +2439,20 @@ return new ICmpInst(I.getPredicate(), A, B); } + // PR19753: + // (icmp (ashr exact const1, A), const2) -> icmp A, Log2(const1/const2) + { + ConstantInt *CI2; + Value *V; + if (match(Op0, m_AShr(m_ConstantInt(CI2), m_Value(V))) && + (cast(Op0)->isExact())) { + APInt Quotient = CI2->getValue().sdiv(CI->getValue()); + unsigned shift = Quotient.logBase2(); + return new ICmpInst(I.getPredicate(), V, + ConstantInt::get(V->getType(), shift)); + } + } + // If we have an icmp le or icmp ge instruction, turn it into the // appropriate icmp lt or icmp gt instruction. This allows us to rely on // them being folded in the code below. The SimplifyICmpInst code has Index: test/Transforms/InstCombine/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -1365,3 +1365,11 @@ %2 = icmp slt i32 %1, -10 ret i1 %2 } + +; CHECK-LABEL: @exact_ashr_eq_false +; CHECK-NEXT: icmp eq i32 %a, 1 +define i1 @exact_ashr_eq_false(i32 %a) { + %shr = ashr exact i32 -30, %a + %cmp = icmp eq i32 %shr, -15 + ret i1 %cmp +}