summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadav Rotem <nrotem@apple.com>2015-03-03 21:39:02 +0000
committerNadav Rotem <nrotem@apple.com>2015-03-03 21:39:02 +0000
commit029c5c7fdb07366d14577f789e43498f49a4450d (patch)
treeff0e43f9ee1b0e9c5efd4e2da1f070905cc8c708
parent82ca5e72d2aa95a3a3b26dd3570ae358c267c224 (diff)
downloadbcm5719-llvm-029c5c7fdb07366d14577f789e43498f49a4450d.tar.gz
bcm5719-llvm-029c5c7fdb07366d14577f789e43498f49a4450d.zip
Teach ComputeNumSignBits about signed divisions.
http://reviews.llvm.org/D8028 rdar://20023136 llvm-svn: 231140
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp17
-rw-r--r--llvm/test/Transforms/InstCombine/intrinsics.ll23
2 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 0458d284eb4..d5202664ae5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1723,6 +1723,23 @@ unsigned ComputeNumSignBits(Value *V, const DataLayout *TD,
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;
+
+ // Calculate the incoming numerator bits.
+ unsigned NumBits = ComputeNumSignBits(U->getOperand(0), TD, Depth+1, Q);
+
+ // Add floor(log(C)) bits to the numerator bits.
+ return std::min(TyBits, 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.
diff --git a/llvm/test/Transforms/InstCombine/intrinsics.ll b/llvm/test/Transforms/InstCombine/intrinsics.ll
index 2791adf8feb..cfdda9405a8 100644
--- a/llvm/test/Transforms/InstCombine/intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/intrinsics.ll
@@ -363,3 +363,26 @@ define i32 @cttz_select(i32 %Value) nounwind {
; CHECK-NEXT: call i32 @llvm.cttz.i32(i32 %Value, i1 false)
; CHECK-NEXT: ret i32
}
+
+; CHECK-LABEL: @overflow_div_add(
+; CHECK: ret i1 false
+define i1 @overflow_div_add(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
+}
+
+; CHECK-LABEL: @overflow_div_sub(
+; CHECK: ret i1 false
+define i1 @overflow_div_sub(i32 %v1, i32 %v2) nounwind {
+entry:
+ ; Check cases where the known sign bits are larger than the word size.
+ %a = ashr i32 %v1, 18
+ %div = sdiv i32 %a, 65536
+ %t = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 %div, i32 1)
+ %obit = extractvalue %ov.result.32 %t, 1
+ ret i1 %obit
+}
+
OpenPOWER on IntegriCloud