Fix some bugs, straighten stuff out, more work needs to be done.
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index a77bcb95864ca1b9331b2d061dbabd83094c77cf..385c07004d4e7d304f2e7634d81edea69c2d7956 100644 (file)
@@ -180,6 +180,19 @@ Instruction *InstCombiner::visitSub(BinaryOperator *I) {
   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;
 }
 
@@ -330,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;
   }