Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1654,9 +1654,10 @@ return BinaryOperator::CreateAdd(Op0, Builder.CreateMul(A, B)); // X - A*CI -> X + A*-CI + // We have to make sure we do not undo the 0 - (X * Y) canonicalization. // No need to handle commuted multiply because multiply handling will // ensure constant will be move to the right hand side. - if (match(Op1, m_Mul(m_Value(A), m_Constant(CI)))) { + if (!match(Op0, m_ZeroInt()) && match(Op1, m_Mul(m_Value(A), m_Constant(CI)))) { Value *NewMul = Builder.CreateMul(A, ConstantExpr::getNeg(CI)); return BinaryOperator::CreateAdd(Op0, NewMul); } Index: test/Transforms/InstCombine/mul.ll =================================================================== --- test/Transforms/InstCombine/mul.ll +++ test/Transforms/InstCombine/mul.ll @@ -501,3 +501,17 @@ %mul2 = mul i32 %mul, %neg ret i32 %mul2 } + +@X = global i32 5 + +define i64 @test_mul_canonicalize_neg_is_not_undone(i64 %L1) { +; CHECK-LABEL: @test_mul_canonicalize_neg_is_not_undone( +; CHECK-NEXT: [[TMP1:%.*]] = mul i64 [[L1:%.*]], ptrtoint (i32* @X to i64) +; CHECK-NEXT: [[B4:%.*]] = sub i64 0, [[TMP1]] +; CHECK-NEXT: ret i64 [[B4]] +; + %v1 = ptrtoint i32* @X to i64 + %B8 = sub i64 0, %v1 + %B4 = mul i64 %B8, %L1 + ret i64 %B4 +}