Skip to content

Commit 911129a

Browse files
committed
[InstCombine] Fold X - Y + Y * C -> X + Y * (C - 1)
Alive2 Proof: https://alive2.llvm.org/ce/z/gS9Wb7 This is based on and closes #108451 Note that no nsw or nuw saving works because they all result in poison or undef mismatches.
1 parent e7bc7db commit 911129a

File tree

2 files changed

+24
-17
lines changed

2 files changed

+24
-17
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,18 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
16121612
Value *Sub = Builder.CreateSub(B, A, "reass.sub");
16131613
return BinaryOperator::CreateAdd(Sub, C1);
16141614
}
1615+
1616+
// A - B + B * C -> A + B * (C - 1)
1617+
const APInt *C;
1618+
if (((match(LHS, m_Sub(m_Value(A), m_Value(B))) &&
1619+
match(RHS, m_Mul(m_Specific(B), m_APInt(C)))) ||
1620+
(match(RHS, m_Sub(m_Value(A), m_Value(B))) &&
1621+
match(LHS, m_Mul(m_Specific(B), m_APInt(C))))) &&
1622+
LHS->hasOneUse() && RHS->hasOneUse()) {
1623+
Value *Mul =
1624+
Builder.CreateMul(B, ConstantInt::get(RHS->getType(), *C - 1));
1625+
return BinaryOperator::CreateAdd(A, Mul);
1626+
}
16151627
}
16161628

16171629
// X % C0 + (( X / C0 ) % C1) * C0 => X % (C0 * C1)

llvm/test/Transforms/InstCombine/addsub-constant-folding.ll

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -753,9 +753,8 @@ define i8 @sub_from_constant_extra_use(i8 %x, i8 %y) {
753753

754754
define i32 @sub_plus_mul(i32 %x, i32 %y) {
755755
; CHECK-LABEL: @sub_plus_mul(
756-
; CHECK-NEXT: [[A:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
757-
; CHECK-NEXT: [[B:%.*]] = mul i32 [[Y]], 10
758-
; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
756+
; CHECK-NEXT: [[B:%.*]] = mul i32 [[Y:%.*]], 9
757+
; CHECK-NEXT: [[C:%.*]] = add i32 [[A:%.*]], [[B]]
759758
; CHECK-NEXT: ret i32 [[C]]
760759
;
761760
%a = sub i32 %x, %y
@@ -766,9 +765,8 @@ define i32 @sub_plus_mul(i32 %x, i32 %y) {
766765

767766
define i32 @sub_plus_mul_2(i32 %x, i32 %y) {
768767
; CHECK-LABEL: @sub_plus_mul_2(
769-
; CHECK-NEXT: [[A:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
770-
; CHECK-NEXT: [[B:%.*]] = mul i32 [[Y]], -10
771-
; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
768+
; CHECK-NEXT: [[B:%.*]] = mul i32 [[Y:%.*]], -11
769+
; CHECK-NEXT: [[C:%.*]] = add i32 [[A:%.*]], [[B]]
772770
; CHECK-NEXT: ret i32 [[C]]
773771
;
774772
%a = sub i32 %x, %y
@@ -779,9 +777,8 @@ define i32 @sub_plus_mul_2(i32 %x, i32 %y) {
779777

780778
define i32 @sub_plus_mul3(i32 %x, i32 %y) {
781779
; CHECK-LABEL: @sub_plus_mul3(
782-
; CHECK-NEXT: [[A:%.*]] = mul i32 [[Y:%.*]], 10
783-
; CHECK-NEXT: [[B:%.*]] = sub i32 [[X:%.*]], [[Y]]
784-
; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], [[A]]
780+
; CHECK-NEXT: [[A:%.*]] = mul i32 [[Y:%.*]], 9
781+
; CHECK-NEXT: [[C:%.*]] = add i32 [[B:%.*]], [[A]]
785782
; CHECK-NEXT: ret i32 [[C]]
786783
;
787784
%a = mul i32 %y, 10
@@ -792,9 +789,8 @@ define i32 @sub_plus_mul3(i32 %x, i32 %y) {
792789

793790
define i32 @sub_plus_mul4(i32 %x, i32 %y) {
794791
; CHECK-LABEL: @sub_plus_mul4(
795-
; CHECK-NEXT: [[A:%.*]] = mul i32 [[Y:%.*]], -10
796-
; CHECK-NEXT: [[B:%.*]] = sub i32 [[X:%.*]], [[Y]]
797-
; CHECK-NEXT: [[C:%.*]] = add i32 [[B]], [[A]]
792+
; CHECK-NEXT: [[A:%.*]] = mul i32 [[Y:%.*]], -11
793+
; CHECK-NEXT: [[C:%.*]] = add i32 [[B:%.*]], [[A]]
798794
; CHECK-NEXT: ret i32 [[C]]
799795
;
800796
%a = mul i32 %y, -10
@@ -805,9 +801,8 @@ define i32 @sub_plus_mul4(i32 %x, i32 %y) {
805801

806802
define <2 x i8> @sub_plus_mul_splat(<2 x i8> %x, <2 x i8> %y) {
807803
; CHECK-LABEL: @sub_plus_mul_splat(
808-
; CHECK-NEXT: [[A:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
809-
; CHECK-NEXT: [[B:%.*]] = mul <2 x i8> [[Y]], splat (i8 7)
810-
; CHECK-NEXT: [[C:%.*]] = add <2 x i8> [[A]], [[B]]
804+
; CHECK-NEXT: [[B:%.*]] = mul <2 x i8> [[Y:%.*]], splat (i8 6)
805+
; CHECK-NEXT: [[C:%.*]] = add <2 x i8> [[A:%.*]], [[B]]
811806
; CHECK-NEXT: ret <2 x i8> [[C]]
812807
;
813808
%a = sub <2 x i8> %x, %y
@@ -832,8 +827,8 @@ define i32 @neg_sub_plus_mul_pow2(i32 %x, i32 %y) {
832827
ret i32 %c
833828
}
834829

835-
define <2 x i8> @sub_plus_mul_splat_shl(<2 x i8> %x, <2 x i8> %y) {
836-
; CHECK-LABEL: @sub_plus_mul_splat_shl(
830+
define <2 x i8> @neg_sub_plus_mul_splat_shl(<2 x i8> %x, <2 x i8> %y) {
831+
; CHECK-LABEL: @neg_sub_plus_mul_splat_shl(
837832
; CHECK-NEXT: [[A:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
838833
; CHECK-NEXT: [[B:%.*]] = shl <2 x i8> [[Y]], splat (i8 3)
839834
; CHECK-NEXT: [[C:%.*]] = add <2 x i8> [[A]], [[B]]

0 commit comments

Comments
 (0)