summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp8
-rw-r--r--llvm/test/Transforms/InstCombine/div.ll18
2 files changed, 26 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index a554e9f628e..bb3d9281edb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -95,6 +95,14 @@ static bool IsMultiple(const APInt &C1, const APInt &C2, APInt &Quotient,
assert(C1.getBitWidth() == C2.getBitWidth() &&
"Inconsistent width of constants!");
+ // Bail if we will divide by zero.
+ if (C2.isMinValue())
+ return false;
+
+ // Bail if we would divide INT_MIN by -1.
+ if (IsSigned && C1.isMinSignedValue() && C2.isAllOnesValue())
+ return false;
+
APInt Remainder(C1.getBitWidth(), /*Val=*/0ULL, IsSigned);
if (IsSigned)
APInt::sdivrem(C1, C2, Quotient, Remainder);
diff --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll
index 933d9ec4b0d..3194c015fd7 100644
--- a/llvm/test/Transforms/InstCombine/div.ll
+++ b/llvm/test/Transforms/InstCombine/div.ll
@@ -325,3 +325,21 @@ define i32 @test36(i32 %A) {
; CHECK-NEXT: %[[shr:.*]] = lshr exact i32 %[[and]], %A
; CHECK-NEXT: ret i32 %[[shr]]
}
+
+define i32 @test37(i32* %b) {
+entry:
+ store i32 0, i32* %b, align 4
+ %0 = load i32, i32* %b, align 4
+ br i1 undef, label %lor.rhs, label %lor.end
+
+lor.rhs: ; preds = %entry
+ %mul = mul nsw i32 undef, %0
+ br label %lor.end
+
+lor.end: ; preds = %lor.rhs, %entry
+ %t.0 = phi i32 [ %0, %entry ], [ %mul, %lor.rhs ]
+ %div = sdiv i32 %t.0, 2
+ ret i32 %div
+; CHECK-LABEL: @test37(
+; CHECK: ret i32 0
+}
OpenPOWER on IntegriCloud