Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1631,6 +1631,11 @@ return BinaryOperator::CreateAdd(Op0, Builder->CreateSub(Z, Y, Op1->getName())); + // (X + Y) - (X + Z) --> (Y - Z) + if (match(Op0, m_Add(m_Value(X), m_Value(Y))) && + match(Op1, m_Add(m_Value(X), m_Value(Z)))) + return BinaryOperator::CreateSub(Y, Z); + // (X - (X & Y)) --> (X & ~Y) // if (match(Op1, m_And(m_Value(Y), m_Specific(Op0))) || Index: test/Transforms/InstCombine/sub.ll =================================================================== --- test/Transforms/InstCombine/sub.ll +++ test/Transforms/InstCombine/sub.ll @@ -529,3 +529,13 @@ ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 %x, -32768 ; CHECK: ret i32 [[ADD]] } + +define i32 @test45(i32 %x, i32 %y, i32 %z) { + %add = add i32 %x, %y + %add1 = add i32 %x, %z + %sub = sub i32 %add, %add1 + ret i32 %sub +; CHECK-LABEL: @test45( +; CHECK-NEXT: %sub = sub i32 %y, %z +; CHECK-NEXT: ret i32 %sub +}