Index: ../llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- ../llvm/lib/Analysis/ValueTracking.cpp +++ ../llvm/lib/Analysis/ValueTracking.cpp @@ -1723,6 +1723,22 @@ Tmp = TyBits - U->getOperand(0)->getType()->getScalarSizeInBits(); return ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q) + Tmp; + case Instruction::SDiv: + const APInt *Denominator; + // sdiv X, C -> adds log(C) sign bits. + if (match(U->getOperand(1), m_APInt(Denominator))) { + + // Ignore non-positive denominator. + if (!Denominator->isStrictlyPositive()) + break; + + unsigned NumBits = ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q); + + // Add floor(log(c)) bits. + return NumBits + Denominator->logBase2(); + } + break; + case Instruction::AShr: { Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q); // ashr X, C -> adds C sign bits. Vectors too. Index: ../llvm/test/Transforms/InstCombine/intrinsics.ll =================================================================== --- ../llvm/test/Transforms/InstCombine/intrinsics.ll +++ ../llvm/test/Transforms/InstCombine/intrinsics.ll @@ -363,3 +363,14 @@ ; CHECK-NEXT: call i32 @llvm.cttz.i32(i32 %Value, i1 false) ; CHECK-NEXT: ret i32 } + +; CHECK-LABEL: @overflow_div( +; CHECK: ret i1 false +define i1 @overflow_div(i32 %v1, i32 %v2) nounwind { +entry: + %div = sdiv i32 %v1, 2 + %t = call %ov.result.32 @llvm.sadd.with.overflow.i32(i32 %div, i32 1) + %obit = extractvalue %ov.result.32 %t, 1 + ret i1 %obit +} +