[llvm] r231433 - Teach ComputeNumSignBits about signed reminder.
Nadav Rotem
nrotem at apple.com
Thu Mar 5 16:23:58 PST 2015
Author: nadav
Date: Thu Mar 5 18:23:58 2015
New Revision: 231433
URL: http://llvm.org/viewvc/llvm-project?rev=231433&view=rev
Log:
Teach ComputeNumSignBits about signed reminder.
This optimization a continuation of r231140 that reasoned about signed div.
Modified:
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/test/Transforms/InstCombine/intrinsics.ll
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=231433&r1=231432&r2=231433&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Thu Mar 5 18:23:58 2015
@@ -1723,7 +1723,7 @@ unsigned ComputeNumSignBits(Value *V, co
Tmp = TyBits - U->getOperand(0)->getType()->getScalarSizeInBits();
return ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q) + Tmp;
- case Instruction::SDiv:
+ case Instruction::SDiv: {
const APInt *Denominator;
// sdiv X, C -> adds log(C) sign bits.
if (match(U->getOperand(1), m_APInt(Denominator))) {
@@ -1739,6 +1739,32 @@ unsigned ComputeNumSignBits(Value *V, co
return std::min(TyBits, NumBits + Denominator->logBase2());
}
break;
+ }
+
+ case Instruction::SRem: {
+ const APInt *Denominator;
+ // srem X, C -> we know that the result is within 0..C-1 when C is a
+ // positive constant and the sign bits are at most TypeBits - log2(C).
+ if (match(U->getOperand(1), m_APInt(Denominator))) {
+
+ // Ignore non-positive denominator.
+ if (!Denominator->isStrictlyPositive())
+ break;
+
+ // Calculate the incoming numerator bits. SRem by a positive constant
+ // can't lower the number of sign bits.
+ unsigned NumrBits = ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q);
+
+ // Calculate the leading sign bit constraints by examining the
+ // denominator. The remainder is in the range 0..C-1, which is
+ // calculated by the log2(denominator). The sign bits are the bit-width
+ // minus this value. The result of this subtraction has to be positive.
+ unsigned ResBits = TyBits - Denominator->logBase2();
+
+ return std::max(NumrBits, ResBits);
+ }
+ break;
+ }
case Instruction::AShr: {
Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q);
Modified: llvm/trunk/test/Transforms/InstCombine/intrinsics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/intrinsics.ll?rev=231433&r1=231432&r2=231433&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/intrinsics.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/intrinsics.ll Thu Mar 5 18:23:58 2015
@@ -386,3 +386,24 @@ entry:
ret i1 %obit
}
+; CHECK-LABEL: @overflow_mod_mul(
+; CHECK: ret i1 false
+define i1 @overflow_mod_mul(i32 %v1, i32 %v2) nounwind {
+entry:
+ %rem = srem i32 %v1, 1000
+ %t = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %rem, i32 %rem)
+ %obit = extractvalue %ov.result.32 %t, 1
+ ret i1 %obit
+}
+
+; CHECK-LABEL: @overflow_mod_overflow_mul(
+; CHECK-NOT: ret i1 false
+define i1 @overflow_mod_overflow_mul(i32 %v1, i32 %v2) nounwind {
+entry:
+ %rem = srem i32 %v1, 65537
+ ; This may overflow because the result of the mul operands may be greater than 16bits
+ ; and the result greater than 32.
+ %t = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %rem, i32 %rem)
+ %obit = extractvalue %ov.result.32 %t, 1
+ ret i1 %obit
+}
More information about the llvm-commits
mailing list