Fix some bugs, straighten stuff out, more work needs to be done.
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index fda64ab49adf9b7522a7788fd8fbd6efe14c5725..385c07004d4e7d304f2e7634d81edea69c2d7956 100644 (file)
@@ -15,7 +15,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Transforms/Scalar/InstructionCombining.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/ConstantHandling.h"
 #include "llvm/iMemory.h"
 #include "llvm/iOther.h"
@@ -24,7 +25,6 @@
 #include "llvm/Pass.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/InstVisitor.h"
-#include "../TransformInternals.h"
 
 
 namespace {
@@ -128,13 +128,13 @@ Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
     return I;
   }
 
-  // -B + A  -->  A - B
+  // -A + B  -->  B - A
   if (Value *V = dyn_castNegInst(LHS))
-    return BinaryOperator::create(Instruction::Sub, RHS, LHS);
+    return BinaryOperator::create(Instruction::Sub, RHS, V);
 
   // A + -B  -->  A - B
   if (Value *V = dyn_castNegInst(RHS))
-    return BinaryOperator::create(Instruction::Sub, LHS, RHS);
+    return BinaryOperator::create(Instruction::Sub, LHS, V);
 
   // Simplify add instructions with a constant RHS...
   if (Constant *Op2 = dyn_cast<Constant>(RHS)) {
@@ -176,14 +176,23 @@ Instruction *InstCombiner::visitSub(BinaryOperator *I) {
     if (Constant *RHS = *Constant::getNullValue(I->getType()) - *Op2) // 0 - RHS
       return BinaryOperator::create(Instruction::Add, Op0, RHS, I->getName());
 
-  // If this is a 'C = -B', check to see if 'B = -A', so that C = A...
-  if (Op0 == Constant::getNullValue(I->getType())) 
-    if (Value *V = dyn_castNegInst(Op1)) {
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(V);
-      return I;
-    }
+  // If this is a 'C = x-B', check to see if 'B = -A', so that C = x+A...
+  if (Value *V = dyn_castNegInst(Op1))
+    return BinaryOperator::create(Instruction::Add, Op0, V);
 
+  // Replace (x - (y - z)) with (x + (z - y)) if the (y - z) subexpression is
+  // not used by anyone else...
+  //
+  if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1))
+    if (Op1I->use_size() == 1) {
+      // Swap the two operands of the subexpr...
+      Value *IIOp0 = Op1I->getOperand(0), *IIOp1 = Op1I->getOperand(1);
+      Op1I->setOperand(0, IIOp1);
+      Op1I->setOperand(1, IIOp0);
+
+      // Create the new top level add instruction...
+      return BinaryOperator::create(Instruction::Add, Op0, Op1);
+    }
   return 0;
 }
 
@@ -334,17 +343,31 @@ Instruction *InstCombiner::visitXor(BinaryOperator *I) {
   return Changed ? I : 0;
 }
 
+// isTrueWhenEqual - Return true if the specified setcondinst instruction is
+// true when both operands are equal...
+//
+static bool isTrueWhenEqual(Instruction *I) {
+  return I->getOpcode() == Instruction::SetEQ ||
+         I->getOpcode() == Instruction::SetGE ||
+         I->getOpcode() == Instruction::SetLE;
+}
+
 Instruction *InstCombiner::visitSetCondInst(BinaryOperator *I) {
   if (I->use_empty()) return 0;       // Don't fix dead instructions...
   bool Changed = SimplifyBinOp(I);
 
   // setcc X, X
   if (I->getOperand(0) == I->getOperand(1)) {
-    bool NewVal = I->getOpcode() == Instruction::SetEQ ||
-                  I->getOpcode() == Instruction::SetGE ||
-                  I->getOpcode() == Instruction::SetLE;
     AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(ConstantBool::get(NewVal));
+    I->replaceAllUsesWith(ConstantBool::get(isTrueWhenEqual(I)));
+    return I;
+  }
+
+  // setcc <global*>, 0 - Global value addresses are never null!
+  if (isa<GlobalValue>(I->getOperand(0)) &&
+      isa<ConstantPointerNull>(I->getOperand(1))) {
+    AddUsesToWorkList(I);         // Add all modified instrs to worklist
+    I->replaceAllUsesWith(ConstantBool::get(!isTrueWhenEqual(I)));
     return I;
   }