Skip to content

Commit 8b0f425

Browse files
committed
[InstCombine] Add folds for (X + Y) - (W + Z)
If `Y` and `Z` are constant then we can simplify to `(X - W) + (Y - Z)`. If `Y == Z` we can fold to `X - W`. Note these transform exist outside of InstCombine. The purpose of this commit is primarily to make it so that folds can generate these simplifiable patterns without having to worry about creating an inf loop.
1 parent 424df78 commit 8b0f425

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,6 +2202,25 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
22022202
return Sub;
22032203
}
22042204

2205+
{
2206+
// (X + Z) - (Y + Z) --> (X - Y)
2207+
// This is done in other passes, but we want to be able to consume this
2208+
// pattern in InstCombine so we can generate it without creating infinite
2209+
// loops.
2210+
if (match(Op0, m_Add(m_Value(X), m_Value(Z))) &&
2211+
match(Op1, m_c_Add(m_Value(Y), m_Specific(Z))))
2212+
return BinaryOperator::CreateSub(X, Y);
2213+
2214+
// (X + C0) - (Y + C1) --> (X - Y) + (C0 - C1)
2215+
Constant *CX, *CY;
2216+
if (match(Op0, m_OneUse(m_Add(m_Value(X), m_ImmConstant(CX)))) &&
2217+
match(Op1, m_OneUse(m_Add(m_Value(Y), m_ImmConstant(CY))))) {
2218+
Value *OpsSub = Builder.CreateSub(X, Y);
2219+
Constant *ConstsSub = ConstantExpr::getSub(CX, CY);
2220+
return BinaryOperator::CreateAdd(OpsSub, ConstsSub);
2221+
}
2222+
}
2223+
22052224
// (~X) - (~Y) --> Y - X
22062225
// This is placed after the other reassociations and explicitly excludes a
22072226
// sub-of-sub pattern to avoid infinite looping.

llvm/test/Transforms/InstCombine/sub.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,8 +1110,8 @@ define i32 @test57(i32 %A, i32 %B) {
11101110

11111111
define i64 @test58(ptr %foo, i64 %i, i64 %j) {
11121112
; CHECK-LABEL: @test58(
1113-
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
1114-
; CHECK-NEXT: ret i64 [[TMP1]]
1113+
; CHECK-NEXT: [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
1114+
; CHECK-NEXT: ret i64 [[GEPDIFF]]
11151115
;
11161116
%gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 %i
11171117
%gep2 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 %j
@@ -2585,7 +2585,7 @@ define i8 @sub_of_adds_2xz_multiuse(i8 %x, i8 %y, i8 %z) {
25852585
; CHECK-LABEL: @sub_of_adds_2xz_multiuse(
25862586
; CHECK-NEXT: [[XZ:%.*]] = add i8 [[X:%.*]], [[Z:%.*]]
25872587
; CHECK-NEXT: [[YZ:%.*]] = add i8 [[Z]], [[Y:%.*]]
2588-
; CHECK-NEXT: [[R:%.*]] = sub i8 [[XZ]], [[YZ]]
2588+
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X]], [[Y]]
25892589
; CHECK-NEXT: call void @use8(i8 [[XZ]])
25902590
; CHECK-NEXT: call void @use8(i8 [[YZ]])
25912591
; CHECK-NEXT: ret i8 [[R]]

0 commit comments

Comments
 (0)