Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1580,6 +1580,12 @@ if (match(Op1, m_OneUse(m_Add(m_Value(X), m_One())))) return BinaryOperator::CreateAdd(Builder.CreateNot(X), Op0); + // Y - ~X --> (X + 1) + Y + if (match(Op1, m_OneUse(m_Not(m_Value(X))))) { + return BinaryOperator::CreateAdd( + Builder.CreateAdd(Op0, ConstantInt::get(I.getType(), 1)), X); + } + if (Constant *C = dyn_cast(Op0)) { bool IsNegate = match(C, m_ZeroInt()); Value *X; Index: test/Transforms/InstCombine/fold-sub-of-not-to-inc-of-add.ll =================================================================== --- test/Transforms/InstCombine/fold-sub-of-not-to-inc-of-add.ll +++ test/Transforms/InstCombine/fold-sub-of-not-to-inc-of-add.ll @@ -4,7 +4,8 @@ ; Given: ; sub %y, (xor %x, -1) ; Transform it to: -; add (add %x, %y), 1 +; add (add %x, 1), %y +; We prefer this form because that is what -reassociate would produce. ;------------------------------------------------------------------------------; ; Scalar tests @@ -12,8 +13,8 @@ define i32 @p0_scalar(i32 %x, i32 %y) { ; CHECK-LABEL: @p0_scalar( -; CHECK-NEXT: [[T0:%.*]] = xor i32 [[X:%.*]], -1 -; CHECK-NEXT: [[T1:%.*]] = sub i32 [[Y:%.*]], [[T0]] +; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y:%.*]], 1 +; CHECK-NEXT: [[T1:%.*]] = add i32 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: ret i32 [[T1]] ; %t0 = xor i32 %x, -1 @@ -27,8 +28,8 @@ define <4 x i32> @p1_vector_splat(<4 x i32> %x, <4 x i32> %y) { ; CHECK-LABEL: @p1_vector_splat( -; CHECK-NEXT: [[T0:%.*]] = xor <4 x i32> [[X:%.*]], -; CHECK-NEXT: [[T1:%.*]] = sub <4 x i32> [[Y:%.*]], [[T0]] +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[Y:%.*]], +; CHECK-NEXT: [[T1:%.*]] = add <4 x i32> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: ret <4 x i32> [[T1]] ; %t0 = xor <4 x i32> %x, @@ -38,8 +39,8 @@ define <4 x i32> @p2_vector_undef(<4 x i32> %x, <4 x i32> %y) { ; CHECK-LABEL: @p2_vector_undef( -; CHECK-NEXT: [[T0:%.*]] = xor <4 x i32> [[X:%.*]], -; CHECK-NEXT: [[T1:%.*]] = sub <4 x i32> [[Y:%.*]], [[T0]] +; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> [[Y:%.*]], +; CHECK-NEXT: [[T1:%.*]] = add <4 x i32> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: ret <4 x i32> [[T1]] ; %t0 = xor <4 x i32> %x,