Fold (-x + -y) -> -(x+y) which promotes better association, fixing
authorChris Lattner <sabre@nondot.org>
Sun, 17 Feb 2008 21:03:36 +0000 (21:03 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 17 Feb 2008 21:03:36 +0000 (21:03 +0000)
the second half of PR2047

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47244 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/addnegneg.ll [new file with mode: 0644]

index c9ff01b90781c1e3027e83e5ec17688262fb8b45..1ecefeb82bcb1a09c268a80e018d8917f734d91d 100644 (file)
@@ -2090,8 +2090,16 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   }
 
   // -A + B  -->  B - A
-  if (Value *V = dyn_castNegVal(LHS))
-    return BinaryOperator::createSub(RHS, V);
+  // -A + -B  -->  -(A + B)
+  if (Value *LHSV = dyn_castNegVal(LHS)) {
+    if (Value *RHSV = dyn_castNegVal(RHS)) {
+      Instruction *NewAdd = BinaryOperator::createAdd(LHSV, RHSV, "sum");
+      InsertNewInstBefore(NewAdd, I);
+      return BinaryOperator::createNeg(NewAdd);
+    }
+    
+    return BinaryOperator::createSub(RHS, LHSV);
+  }
 
   // A + -B  -->  A - B
   if (!isa<Constant>(RHS))
diff --git a/test/Transforms/InstCombine/addnegneg.ll b/test/Transforms/InstCombine/addnegneg.ll
new file mode 100644 (file)
index 0000000..f3b9565
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep { sub } | count 1
+; PR2047
+
+define i32 @l(i32 %a, i32 %b, i32 %c, i32 %d) {
+entry:
+       %b.neg = sub i32 0, %b          ; <i32> [#uses=1]
+       %c.neg = sub i32 0, %c          ; <i32> [#uses=1]
+       %sub4 = add i32 %c.neg, %b.neg          ; <i32> [#uses=1]
+       %sub6 = add i32 %sub4, %d               ; <i32> [#uses=1]
+       ret i32 %sub6
+}
+