summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-22 18:16:54 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-22 18:16:54 +0000
commit218fe23f410b3b05bdd30a5f0778a77f05228f18 (patch)
tree254303f70b9bd75e101942cbcc5761e087bbdfb3
parente915b4b7c83e7fc7178d1336d6eb48c4101b274a (diff)
InstCombine: Propagate exact in (udiv (lshr X,C1),C2) -> (udiv x,C1<<C2)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222620 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp9
-rw-r--r--test/Transforms/InstCombine/div.ll9
2 files changed, 16 insertions, 2 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 010625a7157..2befe1934f4 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -997,9 +997,14 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
match(Op1, m_APInt(C2))) {
bool Overflow;
APInt C2ShlC1 = C2->ushl_ov(*C1, Overflow);
- if (!Overflow)
- return BinaryOperator::CreateUDiv(
+ if (!Overflow) {
+ bool IsExact = I.isExact() && match(Op0, m_Exact(m_Value()));
+ BinaryOperator *BO = BinaryOperator::CreateUDiv(
X, ConstantInt::get(X->getType(), C2ShlC1));
+ if (IsExact)
+ BO->setIsExact();
+ return BO;
+ }
}
}
diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll
index 5af86680697..585b04a4d5d 100644
--- a/test/Transforms/InstCombine/div.ll
+++ b/test/Transforms/InstCombine/div.ll
@@ -286,3 +286,12 @@ define i32 @test32(i32 %a, i32 %b) {
; CHECK-NEXT: %[[div:.*]] = udiv i32 %a, %[[shr]]
; CHECK-NEXT: ret i32
}
+
+define <2 x i64> @test33(<2 x i64> %x) nounwind {
+ %shr = lshr exact <2 x i64> %x, <i64 5, i64 5>
+ %div = udiv exact <2 x i64> %shr, <i64 6, i64 6>
+ ret <2 x i64> %div
+; CHECK-LABEL: @test33(
+; CHECK-NEXT: udiv exact <2 x i64> %x, <i64 192, i64 192>
+; CHECK-NEXT: ret <2 x i64>
+}