[llvm] r362216 - [InstCombine] 'add (sub C1, X), C2 --> sub (add C1, C2), X' constant-fold

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Fri May 31 02:47:04 PDT 2019


Author: lebedevri
Date: Fri May 31 02:47:04 2019
New Revision: 362216

URL: http://llvm.org/viewvc/llvm-project?rev=362216&view=rev
Log:
[InstCombine] 'add (sub C1, X), C2 --> sub (add C1, C2), X' constant-fold

https://rise4fun.com/Alive/qJQ

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

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp?rev=362216&r1=362215&r2=362216&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Fri May 31 02:47:04 2019
@@ -872,7 +872,14 @@ Instruction *InstCombiner::foldAddWithCo
   if (Instruction *NV = foldBinOpIntoSelectOrPhi(Add))
     return NV;
 
-  Value *X, *Y;
+  Value *X;
+  Constant *Op00C;
+
+  // add (sub C1, X), C2 --> sub (add C1, C2), X
+  if (match(Op0, m_Sub(m_Constant(Op00C), m_Value(X))))
+    return BinaryOperator::CreateSub(ConstantExpr::getAdd(Op00C, Op1C), X);
+
+  Value *Y;
 
   // add (sub X, Y), -1 --> add (not Y), X
   if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y)))) &&

Modified: llvm/trunk/test/Transforms/InstCombine/addsub-constant-folding.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/addsub-constant-folding.ll?rev=362216&r1=362215&r2=362216&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/addsub-constant-folding.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/addsub-constant-folding.ll Fri May 31 02:47:04 2019
@@ -353,12 +353,10 @@ define <4 x i32> @vec_sub_const_const_su
 }
 
 ; (c1-x)+c2
-; FIXME
 
 define i32 @const_sub_add_const(i32 %arg) {
 ; CHECK-LABEL: @const_sub_add_const(
-; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], 2
+; CHECK-NEXT:    [[T1:%.*]] = sub i32 10, [[ARG:%.*]]
 ; CHECK-NEXT:    ret i32 [[T1]]
 ;
   %t0 = sub i32 8, %arg
@@ -370,7 +368,7 @@ define i32 @const_sub_add_const_extrause
 ; CHECK-LABEL: @const_sub_add_const_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
 ; CHECK-NEXT:    call void @use(i32 [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], 2
+; CHECK-NEXT:    [[T1:%.*]] = sub i32 10, [[ARG]]
 ; CHECK-NEXT:    ret i32 [[T1]]
 ;
   %t0 = sub i32 8, %arg
@@ -381,8 +379,7 @@ define i32 @const_sub_add_const_extrause
 
 define <4 x i32> @vec_const_sub_add_const(<4 x i32> %arg) {
 ; CHECK-LABEL: @vec_const_sub_add_const(
-; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, [[ARG:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[T0]], <i32 2, i32 2, i32 2, i32 2>
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 10, i32 10, i32 10, i32 10>, [[ARG:%.*]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
@@ -394,7 +391,7 @@ define <4 x i32> @vec_const_sub_add_cons
 ; CHECK-LABEL: @vec_const_sub_add_const_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, [[ARG:%.*]]
 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[T0]], <i32 2, i32 2, i32 2, i32 2>
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 10, i32 10, i32 10, i32 10>, [[ARG]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
@@ -405,8 +402,7 @@ define <4 x i32> @vec_const_sub_add_cons
 
 define <4 x i32> @vec_const_sub_add_const_nonsplat(<4 x i32> %arg) {
 ; CHECK-LABEL: @vec_const_sub_add_const_nonsplat(
-; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, [[ARG:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[T0]], <i32 2, i32 3, i32 undef, i32 2>
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 23, i32 undef, i32 undef, i32 10>, [[ARG:%.*]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg
@@ -415,12 +411,10 @@ define <4 x i32> @vec_const_sub_add_cons
 }
 
 ; (c1-x)-c2
-; FIXME
 
 define i32 @const_sub_sub_const(i32 %arg) {
 ; CHECK-LABEL: @const_sub_sub_const(
-; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], -2
+; CHECK-NEXT:    [[T1:%.*]] = sub i32 6, [[ARG:%.*]]
 ; CHECK-NEXT:    ret i32 [[T1]]
 ;
   %t0 = sub i32 8, %arg
@@ -432,7 +426,7 @@ define i32 @const_sub_sub_const_extrause
 ; CHECK-LABEL: @const_sub_sub_const_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
 ; CHECK-NEXT:    call void @use(i32 [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], -2
+; CHECK-NEXT:    [[T1:%.*]] = sub i32 6, [[ARG]]
 ; CHECK-NEXT:    ret i32 [[T1]]
 ;
   %t0 = sub i32 8, %arg
@@ -443,8 +437,7 @@ define i32 @const_sub_sub_const_extrause
 
 define <4 x i32> @vec_const_sub_sub_const(<4 x i32> %arg) {
 ; CHECK-LABEL: @vec_const_sub_sub_const(
-; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, [[ARG:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[T0]], <i32 -2, i32 -2, i32 -2, i32 -2>
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 6, i32 6, i32 6, i32 6>, [[ARG:%.*]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
@@ -456,7 +449,7 @@ define <4 x i32> @vec_const_sub_sub_cons
 ; CHECK-LABEL: @vec_const_sub_sub_const_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, [[ARG:%.*]]
 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[T0]], <i32 -2, i32 -2, i32 -2, i32 -2>
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 6, i32 6, i32 6, i32 6>, [[ARG]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
@@ -467,8 +460,7 @@ define <4 x i32> @vec_const_sub_sub_cons
 
 define <4 x i32> @vec_const_sub_sub_const_nonsplat(<4 x i32> %arg) {
 ; CHECK-LABEL: @vec_const_sub_sub_const_nonsplat(
-; CHECK-NEXT:    [[T0:%.*]] = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, [[ARG:%.*]]
-; CHECK-NEXT:    [[T1:%.*]] = add <4 x i32> [[T0]], <i32 -2, i32 -3, i32 undef, i32 -2>
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 19, i32 undef, i32 undef, i32 6>, [[ARG:%.*]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg




More information about the llvm-commits mailing list