Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -892,6 +892,10 @@ if (!match(Op1, m_APInt(C))) return nullptr; + // (X + ~Y) + 1 --> X - Y + if (C->isOneValue() && match(Op0, m_c_Add(m_Value(X), m_Not(m_Value(Y))))) + return BinaryOperator::CreateSub(X, Y); + if (C->isSignMask()) { // If wrapping is not allowed, then the addition must set the sign bit: // X + (signmask) --> X | signmask Index: test/Transforms/InstCombine/add.ll =================================================================== --- test/Transforms/InstCombine/add.ll +++ test/Transforms/InstCombine/add.ll @@ -951,9 +951,7 @@ define i32 @add_to_sub(i32 %M, i32 %B) { ; CHECK-LABEL: @add_to_sub( ; CHECK-NEXT: [[A:%.*]] = mul i32 [[M:%.*]], 42 -; CHECK-NEXT: [[C:%.*]] = xor i32 [[B:%.*]], -1 -; CHECK-NEXT: [[D:%.*]] = add i32 [[A]], [[C]] -; CHECK-NEXT: [[E:%.*]] = add i32 [[D]], 1 +; CHECK-NEXT: [[E:%.*]] = sub i32 [[A]], [[B:%.*]] ; CHECK-NEXT: ret i32 [[E]] ; %A = mul i32 %M, 42 ; thwart complexity-based ordering @@ -966,10 +964,8 @@ ; E = (~B + A) + 1 = A - B define i32 @add_to_sub2(i32 %A, i32 %M) { ; CHECK-LABEL: @add_to_sub2( -; CHECK-NEXT: [[B:%.*]] = mul i32 [[M:%.*]], 42 -; CHECK-NEXT: [[C:%.*]] = xor i32 [[B]], -1 -; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[A:%.*]] -; CHECK-NEXT: [[E:%.*]] = add i32 [[D]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[M:%.*]], -42 +; CHECK-NEXT: [[E:%.*]] = add i32 [[TMP1]], [[A:%.*]] ; CHECK-NEXT: ret i32 [[E]] ; %B = mul i32 %M, 42 ; thwart complexity-based ordering