diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 2befe1934f4..b79f55e1435 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1082,10 +1082,12 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) { return new ZExtInst(Builder->CreateICmpEQ(Op0, Op1), I.getType()); // -X/C --> X/-C provided the negation doesn't overflow. - if (SubOperator *Sub = dyn_cast(Op0)) - if (match(Sub->getOperand(0), m_Zero()) && Sub->hasNoSignedWrap()) - return BinaryOperator::CreateSDiv(Sub->getOperand(1), - ConstantExpr::getNeg(RHS)); + Value *X; + if (match(Op0, m_NSWSub(m_Zero(), m_Value(X)))) { + auto *BO = BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(RHS)); + BO->setIsExact(I.isExact()); + return BO; + } } // If the sign bits of both operands are zero (i.e. we can prove they are diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll index 585b04a4d5d..f4166ec5cbc 100644 --- a/test/Transforms/InstCombine/div.ll +++ b/test/Transforms/InstCombine/div.ll @@ -295,3 +295,12 @@ define <2 x i64> @test33(<2 x i64> %x) nounwind { ; CHECK-NEXT: udiv exact <2 x i64> %x, ; CHECK-NEXT: ret <2 x i64> } + +define <2 x i64> @test34(<2 x i64> %x) nounwind { + %neg = sub nsw <2 x i64> zeroinitializer, %x + %div = sdiv exact <2 x i64> %neg, + ret <2 x i64> %div +; CHECK-LABEL: @test34( +; CHECK-NEXT: sdiv exact <2 x i64> %x, +; CHECK-NEXT: ret <2 x i64> +}