[PATCH] D70462: [InstCombine] Change InstCombineAddSub to not perform constant folding when there is an intermediate use of the source register.

Danilo Carvalho Grael via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 19 14:06:16 PST 2019


dancgr created this revision.
dancgr added a reviewer: amehsan.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
dancgr changed the visibility from "Public (No Login Required)" to "No One".
dancgr edited the summary of this revision.
dancgr changed the visibility from "No One" to "Custom Policy".
dancgr edited reviewers, added: majnemer, spatel; removed: amehsan.
dancgr changed the visibility from "Custom Policy" to "Public (No Login Required)".

The add/sub with constant folding does not provide substantial gains when there is an intermediate use of the initial result, resulting in the same number of instructions.

Also, this behaviour can interfere with other optimizations which sometimes can result in an extra instruction.

  %a = load i32 ...
  %b = load i32 ...
  
  %1 = sub %a, 10
  %2 = store %1
  %3 = sub 0, %1
  %4 = add %b, %3

-> The statement (%3 = sub 0, %1) will get folded as follows:

  %1 = sub %a, 10
  %2 = store %1
  %3 = sub 0, %1 => %3 = sub 10, %a
  %4 = add %b, %3

-> Preventing the combination of (%3 = sub 0, %1) and (%4 = add %b, %3) into (%3 = sub %b, %1)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D70462

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


Index: llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
===================================================================
--- llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
+++ llvm/test/Transforms/InstCombine/addsub-constant-folding.ll
@@ -136,7 +136,7 @@
 ; CHECK-LABEL: @add_const_const_sub_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], 8
 ; CHECK-NEXT:    call void @use(i32 [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = sub i32 -6, [[ARG]]
+; CHECK-NEXT:    [[T1:%.*]] = sub i32 2, [[T0:%.*]]
 ; CHECK-NEXT:    ret i32 [[T1]]
 ;
   %t0 = add i32 %arg, 8
@@ -159,7 +159,7 @@
 ; CHECK-LABEL: @vec_add_const_const_sub_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 8, i32 8, i32 8, i32 8>
 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 -6, i32 -6, i32 -6, i32 -6>, [[ARG]]
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, [[T0:%.*]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
@@ -310,7 +310,7 @@
 ; CHECK-LABEL: @sub_const_const_sub_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = add i32 [[ARG:%.*]], -8
 ; CHECK-NEXT:    call void @use(i32 [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = sub i32 10, [[ARG]]
+; CHECK-NEXT:    [[T1:%.*]] = sub i32 2, [[T0:%.*]]
 ; CHECK-NEXT:    ret i32 [[T1]]
 ;
   %t0 = sub i32 %arg, 8
@@ -333,7 +333,7 @@
 ; CHECK-LABEL: @vec_sub_const_const_sub_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = add <4 x i32> [[ARG:%.*]], <i32 -8, i32 -8, i32 -8, i32 -8>
 ; CHECK-NEXT:    call void @vec_use(<4 x i32> [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 10, i32 10, i32 10, i32 10>, [[ARG]]
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, [[T0:%.*]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8>
@@ -485,7 +485,7 @@
 ; CHECK-LABEL: @const_sub_const_sub_extrause(
 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 8, [[ARG:%.*]]
 ; CHECK-NEXT:    call void @use(i32 [[T0]])
-; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG]], -6
+; CHECK-NEXT:    [[T1:%.*]] = sub i32 2, [[T0:%.*]]
 ; CHECK-NEXT:    ret i32 [[T1]]
 ;
   %t0 = sub i32 8, %arg
@@ -508,7 +508,7 @@
 ; CHECK-LABEL: @vec_const_sub_const_sub_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> [[ARG]], <i32 -6, i32 -6, i32 -6, i32 -6>
+; CHECK-NEXT:    [[T1:%.*]] = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, [[T0:%.*]]
 ; CHECK-NEXT:    ret <4 x i32> [[T1]]
 ;
   %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -877,7 +877,13 @@
 
   // 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);
+      if (Op0->hasOneUse())
+        return BinaryOperator::CreateSub(ConstantExpr::getAdd(Op00C, Op1C), X);
+
+  // add (add C1, X), C2 -> add (C1, C2), X
+  if (match(Op0, m_Add(m_Constant(Op00C), m_Value(X))))
+      if (Op0->hasOneUse())
+        return BinaryOperator::CreateAdd(ConstantExpr::getAdd(Op00C, Op1C), X);
 
   Value *Y;
 
@@ -1762,11 +1768,15 @@
 
     // C-(C2-X) --> X+(C-C2)
     if (match(Op1, m_Sub(m_Constant(C2), m_Value(X))))
-      return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
+      // Skip combine if Op1 (C2-X) is used somewhere else, as it will add an extra unnecessary instruction, since the original (C2-X) won't be able to be removed.
+      if (Op1->hasOneUse())
+        return BinaryOperator::CreateAdd(X, ConstantExpr::getSub(C, C2));
 
     // C-(X+C2) --> (C-C2)-X
     if (match(Op1, m_Add(m_Value(X), m_Constant(C2))))
-      return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);
+      // Skip combine if Op1 (X+C2) is used somewhere else, as it will add an extra unnecessary instruction, since the original (X+C2) won't be able to be removed.
+      if (Op1->hasOneUse())
+        return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);
   }
 
   const APInt *Op0C;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70462.230145.patch
Type: text/x-patch
Size: 4425 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191119/aa5ee925/attachment-0001.bin>


More information about the llvm-commits mailing list