[llvm] dbf6f30 - [InstCombine] Add folds for `(X + Y) - (W + Z)`

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 20 15:59:48 PST 2023


Author: Noah Goldstein
Date: 2023-11-20T17:59:26-06:00
New Revision: dbf6f30926891dfab4d59d0ff0e960c2a31ab472

URL: https://github.com/llvm/llvm-project/commit/dbf6f30926891dfab4d59d0ff0e960c2a31ab472
DIFF: https://github.com/llvm/llvm-project/commit/dbf6f30926891dfab4d59d0ff0e960c2a31ab472.diff

LOG: [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.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/sub.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 90b1c133461a408..65cafbdbe61cff6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2202,6 +2202,25 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
     return Sub;
   }
 
+  {
+    // (X + Z) - (Y + Z) --> (X - Y)
+    // This is done in other passes, but we want to be able to consume this
+    // pattern in InstCombine so we can generate it without creating infinite
+    // loops.
+    if (match(Op0, m_Add(m_Value(X), m_Value(Z))) &&
+        match(Op1, m_c_Add(m_Value(Y), m_Specific(Z))))
+      return BinaryOperator::CreateSub(X, Y);
+
+    // (X + C0) - (Y + C1) --> (X - Y) + (C0 - C1)
+    Constant *CX, *CY;
+    if (match(Op0, m_OneUse(m_Add(m_Value(X), m_ImmConstant(CX)))) &&
+        match(Op1, m_OneUse(m_Add(m_Value(Y), m_ImmConstant(CY))))) {
+      Value *OpsSub = Builder.CreateSub(X, Y);
+      Constant *ConstsSub = ConstantExpr::getSub(CX, CY);
+      return BinaryOperator::CreateAdd(OpsSub, ConstsSub);
+    }
+  }
+
   // (~X) - (~Y) --> Y - X
   // This is placed after the other reassociations and explicitly excludes a
   // sub-of-sub pattern to avoid infinite looping.

diff  --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll
index 08748d263ba1f78..1fceca321da124a 100644
--- a/llvm/test/Transforms/InstCombine/sub.ll
+++ b/llvm/test/Transforms/InstCombine/sub.ll
@@ -1110,8 +1110,8 @@ define i32 @test57(i32 %A, i32 %B) {
 
 define i64 @test58(ptr %foo, i64 %i, i64 %j) {
 ; CHECK-LABEL: @test58(
-; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
-; CHECK-NEXT:    ret i64 [[TMP1]]
+; CHECK-NEXT:    [[GEPDIFF:%.*]] = sub i64 [[I:%.*]], [[J:%.*]]
+; CHECK-NEXT:    ret i64 [[GEPDIFF]]
 ;
   %gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 %i
   %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) {
 ; CHECK-LABEL: @sub_of_adds_2xz_multiuse(
 ; CHECK-NEXT:    [[XZ:%.*]] = add i8 [[X:%.*]], [[Z:%.*]]
 ; CHECK-NEXT:    [[YZ:%.*]] = add i8 [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = sub i8 [[XZ]], [[YZ]]
+; CHECK-NEXT:    [[R:%.*]] = sub i8 [[X]], [[Y]]
 ; CHECK-NEXT:    call void @use8(i8 [[XZ]])
 ; CHECK-NEXT:    call void @use8(i8 [[YZ]])
 ; CHECK-NEXT:    ret i8 [[R]]


        


More information about the llvm-commits mailing list