From 8e3ed0b6bc95e6b7bc9b1dad8649e490229ee63f Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sun, 6 Sep 2015 06:49:59 +0000 Subject: [PATCH] [InstCombine] Don't divide by zero when evaluating a potential transform Trivial multiplication by zero may survive the worklist. We tried to reassociate the multiplication with a division instruction, causing us to divide by zero; bail out instead. This fixes PR24726. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246939 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineMulDivRem.cpp | 8 ++++++++ test/Transforms/InstCombine/div.ll | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index a554e9f628e..bb3d9281edb 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/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/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll index 933d9ec4b0d..3194c015fd7 100644 --- a/test/Transforms/InstCombine/div.ll +++ b/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 +} -- 2.34.1