[llvm] 41af8f0 - [InstCombine] combine constants by reassociating add/sub/add

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 21 09:17:34 PDT 2021


Author: Sanjay Patel
Date: 2021-08-21T11:45:43-04:00
New Revision: 41af8f0ad5e85ed9065e70272acae6406186b970

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

LOG: [InstCombine] combine constants by reassociating add/sub/add

This may overlap partially with the reassociate pass,
but it seems simple enough that we should try it here
in InstCombine to enable other folds.

This shows up as an opportunity and potential regression
if we improve a subtract fold with 'not' ops to be more
general.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/addsub-constant-folding.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index d01a021bf3f40..aa4f0bdffe106 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1355,6 +1355,17 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
   if (match(RHS, m_OneUse(m_c_Add(m_Value(A), m_Specific(LHS)))))
     return BinaryOperator::CreateAdd(A, Builder.CreateShl(LHS, 1, "reass.add"));
 
+  {
+    // (A + C1) + (C2 - B) --> (A - B) + (C1 + C2)
+    Constant *C1, *C2;
+    if (match(&I, m_c_Add(m_Add(m_Value(A), m_ImmConstant(C1)),
+                          m_Sub(m_ImmConstant(C2), m_Value(B)))) &&
+        (LHS->hasOneUse() || RHS->hasOneUse())) {
+      Value *Sub = Builder.CreateSub(A, B);
+      return BinaryOperator::CreateAdd(Sub, ConstantExpr::getAdd(C1, C2));
+    }
+  }
+
   // X % C0 + (( X / C0 ) % C1) * C0 => X % (C0 * C1)
   if (Value *V = SimplifyAddWithRemainder(I)) return replaceInstUsesWith(I, V);
 

diff  --git a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
index ae634ba1adc77..e9584f35238e3 100644
--- a/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
+++ b/llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
@@ -529,9 +529,8 @@ define <4 x i32> @vec_const_sub_const_sub_nonsplat(<4 x i32> %arg) {
 
 define i7 @addsub_combine_constants(i7 %x, i7 %y) {
 ; CHECK-LABEL: @addsub_combine_constants(
-; CHECK-NEXT:    [[A1:%.*]] = add i7 [[X:%.*]], 42
-; CHECK-NEXT:    [[S:%.*]] = sub i7 10, [[Y:%.*]]
-; CHECK-NEXT:    [[A2:%.*]] = add nsw i7 [[A1]], [[S]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i7 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[A2:%.*]] = add i7 [[TMP1]], 52
 ; CHECK-NEXT:    ret i7 [[A2]]
 ;
   %a1 = add i7 %x, 42
@@ -544,8 +543,8 @@ define <4 x i32> @addsub_combine_constants_use1(<4 x i32> %x, <4 x i32> %y) {
 ; CHECK-LABEL: @addsub_combine_constants_use1(
 ; CHECK-NEXT:    [[A1:%.*]] = add <4 x i32> [[X:%.*]], <i32 42, i32 -7, i32 0, i32 -1>
 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[A1]])
-; CHECK-NEXT:    [[S:%.*]] = sub <4 x i32> <i32 -100, i32 1, i32 -1, i32 42>, [[Y:%.*]]
-; CHECK-NEXT:    [[A2:%.*]] = add nuw <4 x i32> [[S]], [[A1]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub <4 x i32> [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[A2:%.*]] = add <4 x i32> [[TMP1]], <i32 -58, i32 -6, i32 -1, i32 41>
 ; CHECK-NEXT:    ret <4 x i32> [[A2]]
 ;
   %a1 = add <4 x i32> %x, <i32 42, i32 -7, i32 0, i32 -1>
@@ -557,10 +556,10 @@ define <4 x i32> @addsub_combine_constants_use1(<4 x i32> %x, <4 x i32> %y) {
 
 define i32 @addsub_combine_constants_use2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @addsub_combine_constants_use2(
-; CHECK-NEXT:    [[A1:%.*]] = add i32 [[X:%.*]], 42
 ; CHECK-NEXT:    [[S:%.*]] = sub i32 100, [[Y:%.*]]
 ; CHECK-NEXT:    call void @use(i32 [[S]])
-; CHECK-NEXT:    [[A2:%.*]] = add i32 [[A1]], [[S]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[X:%.*]], [[Y]]
+; CHECK-NEXT:    [[A2:%.*]] = add i32 [[TMP1]], 142
 ; CHECK-NEXT:    ret i32 [[A2]]
 ;
   %a1 = add i32 %x, 42
@@ -570,6 +569,8 @@ define i32 @addsub_combine_constants_use2(i32 %x, i32 %y) {
   ret i32 %a2
 }
 
+; negative test - too many uses
+
 define i32 @addsub_combine_constants_use3(i32 %x, i32 %y) {
 ; CHECK-LABEL: @addsub_combine_constants_use3(
 ; CHECK-NEXT:    [[A1:%.*]] = add i32 [[X:%.*]], 42


        


More information about the llvm-commits mailing list