Add cannonicalization of shl X, 1 -> add X, X
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index fda64ab49adf9b7522a7788fd8fbd6efe14c5725..9c1076e448148f2d3d072bfbb0857ea5c427dd85 100644 (file)
@@ -1,9 +1,8 @@
-//===- InstructionCombining.cpp - Combine multiple instructions -------------=//
+//===- InstructionCombining.cpp - Combine multiple instructions -----------===//
 //
 // InstructionCombining - Combine instructions to form fewer, simple
-//   instructions.  This pass does not modify the CFG, and has a tendancy to
-//   make instructions dead, so a subsequent DIE pass is useful.  This pass is
-//   where algebraic simplification happens.
+// instructions.  This pass does not modify the CFG This pass is where algebraic
+// simplification happens.
 //
 // This pass combines things like:
 //    %Y = add int 1, %X
@@ -15,7 +14,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Transforms/Scalar/InstructionCombining.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
 #include "llvm/ConstantHandling.h"
 #include "llvm/iMemory.h"
 #include "llvm/iOther.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/InstVisitor.h"
-#include "../TransformInternals.h"
+#include "Support/StatisticReporter.h"
+#include <algorithm>
 
+static Statistic<> NumCombined ("instcombine\t- Number of insts combined");
+static Statistic<> NumConstProp("instcombine\t- Number of constant folds");
+static Statistic<> NumDeadInst ("instcombine\t- Number of dead inst eliminate");
 
 namespace {
   class InstCombiner : public FunctionPass,
@@ -33,19 +38,19 @@ namespace {
     // Worklist of all of the instructions that need to be simplified.
     std::vector<Instruction*> WorkList;
 
-    void AddUsesToWorkList(Instruction *I) {
+    void AddUsesToWorkList(Instruction &I) {
       // The instruction was simplified, add all users of the instruction to
       // the work lists because they might get more simplified now...
       //
-      for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
+      for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
            UI != UE; ++UI)
         WorkList.push_back(cast<Instruction>(*UI));
     }
 
+    // removeFromWorkList - remove all instances of I from the worklist.
+    void removeFromWorkList(Instruction *I);
   public:
-    const char *getPassName() const { return "Instruction Combining"; }
-
-    virtual bool runOnFunction(Function *F);
+    virtual bool runOnFunction(Function &F);
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.preservesCFG();
@@ -55,51 +60,60 @@ namespace {
     // instruction types.  The semantics are as follows:
     // Return Value:
     //    null        - No change was made
-    //     I          - Change was made, I is still valid
+    //     I          - Change was made, I is still valid, I may be dead though
     //   otherwise    - Change was made, replace I with returned instruction
     //   
-    Instruction *visitNot(UnaryOperator *I);
-    Instruction *visitAdd(BinaryOperator *I);
-    Instruction *visitSub(BinaryOperator *I);
-    Instruction *visitMul(BinaryOperator *I);
-    Instruction *visitDiv(BinaryOperator *I);
-    Instruction *visitRem(BinaryOperator *I);
-    Instruction *visitAnd(BinaryOperator *I);
-    Instruction *visitOr (BinaryOperator *I);
-    Instruction *visitXor(BinaryOperator *I);
-    Instruction *visitSetCondInst(BinaryOperator *I);
-    Instruction *visitShiftInst(Instruction *I);
-    Instruction *visitCastInst(CastInst *CI);
-    Instruction *visitPHINode(PHINode *PN);
-    Instruction *visitGetElementPtrInst(GetElementPtrInst *GEP);
-    Instruction *visitMemAccessInst(MemAccessInst *MAI);
+    Instruction *visitAdd(BinaryOperator &I);
+    Instruction *visitSub(BinaryOperator &I);
+    Instruction *visitMul(BinaryOperator &I);
+    Instruction *visitDiv(BinaryOperator &I);
+    Instruction *visitRem(BinaryOperator &I);
+    Instruction *visitAnd(BinaryOperator &I);
+    Instruction *visitOr (BinaryOperator &I);
+    Instruction *visitXor(BinaryOperator &I);
+    Instruction *visitSetCondInst(BinaryOperator &I);
+    Instruction *visitShiftInst(Instruction &I);
+    Instruction *visitCastInst(CastInst &CI);
+    Instruction *visitPHINode(PHINode &PN);
+    Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);
 
     // visitInstruction - Specify what to return for unhandled instructions...
-    Instruction *visitInstruction(Instruction *I) { return 0; }
-  };
-}
-
-
-Instruction *InstCombiner::visitNot(UnaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
+    Instruction *visitInstruction(Instruction &I) { return 0; }
+
+    // InsertNewInstBefore - insert an instruction New before instruction Old
+    // in the program.  Add the new instruction to the worklist.
+    //
+    void InsertNewInstBefore(Instruction *New, Instruction &Old) {
+      assert(New && New->getParent() == 0 &&
+             "New instruction already inserted into a basic block!");
+      BasicBlock *BB = Old.getParent();
+      BB->getInstList().insert(&Old, New);  // Insert inst
+      WorkList.push_back(New);              // Add to worklist
+    }
 
-  // not (not X) = X
-  if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(0)))
-    if (Op->getOpcode() == Instruction::Not) {
+    // ReplaceInstUsesWith - This method is to be used when an instruction is
+    // found to be dead, replacable with another preexisting expression.  Here
+    // we add all uses of I to the worklist, replace all uses of I with the new
+    // value, then return I, so that the inst combiner will know that I was
+    // modified.
+    //
+    Instruction *ReplaceInstUsesWith(Instruction &I, Value *V) {
       AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(Op->getOperand(0));
-      return I;
+      I.replaceAllUsesWith(V);
+      return &I;
     }
-  return 0;
+  };
+
+  RegisterOpt<InstCombiner> X("instcombine", "Combine redundant instructions");
 }
 
 
 // Make sure that this instruction has a constant on the right hand side if it
 // has any constant arguments.  If not, fix it an return true.
 //
-static bool SimplifyBinOp(BinaryOperator *I) {
-  if (isa<Constant>(I->getOperand(0)) && !isa<Constant>(I->getOperand(1)))
-    return !I->swapOperands();
+static bool SimplifyBinOp(BinaryOperator &I) {
+  if (isa<Constant>(I.getOperand(0)) && !isa<Constant>(I.getOperand(1)))
+    return !I.swapOperands();
   return false;
 }
 
@@ -115,26 +129,31 @@ static inline Value *dyn_castNegInst(Value *V) {
   return 0;
 }
 
-Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead add instructions...
+static inline Value *dyn_castNotInst(Value *V) {
+  Instruction *I = dyn_cast<Instruction>(V);
+  if (!I || I->getOpcode() != Instruction::Xor) return 0;
+
+  if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(I->getOperand(1)))
+    if (CI->isAllOnesValue())
+      return I->getOperand(0);
+  return 0;
+}
+
+Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   bool Changed = SimplifyBinOp(I);
-  Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
+  Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
 
   // Eliminate 'add int %X, 0'
-  if (I->getType()->isIntegral() &&
-      RHS == Constant::getNullValue(I->getType())) {
-    AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(LHS);
-    return I;
-  }
+  if (RHS == Constant::getNullValue(I.getType()))
+    return ReplaceInstUsesWith(I, LHS);
 
-  // -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)) {
@@ -148,236 +167,341 @@ Instruction *InstCombiner::visitAdd(BinaryOperator *I) {
         //    %Z = add int %X, 2
         //
         if (Constant *Val = *Op2 + *cast<Constant>(ILHS->getOperand(1))) {
-          I->setOperand(0, ILHS->getOperand(0));
-          I->setOperand(1, Val);
-          return I;
+          I.setOperand(0, ILHS->getOperand(0));
+          I.setOperand(1, Val);
+          return &I;
         }
       }
     }
   }
 
-  return Changed ? I : 0;
+  return Changed ? &I : 0;
 }
 
-Instruction *InstCombiner::visitSub(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead add instructions...
-  Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
+Instruction *InstCombiner::visitSub(BinaryOperator &I) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
-  if (Op0 == Op1) {         // sub X, X  -> 0
-    AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
-    return I;
-  }
+  if (Op0 == Op1)         // sub X, X  -> 0
+    return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
   // If this is a subtract instruction with a constant RHS, convert it to an add
   // instruction of a negative constant
   //
   if (Constant *Op2 = dyn_cast<Constant>(Op1))
-    if (Constant *RHS = *Constant::getNullValue(I->getType()) - *Op2) // 0 - RHS
-      return BinaryOperator::create(Instruction::Add, Op0, RHS, I->getName());
+    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 'B = x-(-A)', change to B = 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 && Op1I->getOpcode() == Instruction::Sub) {
+      // 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;
 }
 
-Instruction *InstCombiner::visitMul(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
+Instruction *InstCombiner::visitMul(BinaryOperator &I) {
   bool Changed = SimplifyBinOp(I);
-  Value *Op1 = I->getOperand(0);
+  Value *Op1 = I.getOperand(0);
 
-  // Simplify add instructions with a constant RHS...
-  if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1))) {
-    if (I->getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(1)){
-      // Eliminate 'mul int %X, 1'
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(Op1);
-      return I;
+  // Simplify mul instructions with a constant RHS...
+  if (Constant *Op2 = dyn_cast<Constant>(I.getOperand(1))) {
+    if (I.getType()->isInteger() && cast<ConstantInt>(Op2)->equalsInt(1))
+      return ReplaceInstUsesWith(I, Op1);  // Eliminate 'mul int %X, 1'
 
-    } else if (I->getType()->isIntegral() &&
-               cast<ConstantInt>(Op2)->equalsInt(2)) {
+    if (I.getType()->isInteger() && cast<ConstantInt>(Op2)->equalsInt(2))
       // Convert 'mul int %X, 2' to 'add int %X, %X'
-      return BinaryOperator::create(Instruction::Add, Op1, Op1, I->getName());
+      return BinaryOperator::create(Instruction::Add, Op1, Op1, I.getName());
 
-    } else if (Op2->isNullValue()) {
-      // Eliminate 'mul int %X, 0'
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(Op2);   // Set this value to zero directly
-      return I;
-    }
+    if (Op2->isNullValue())
+      return ReplaceInstUsesWith(I, Op2);  // Eliminate 'mul int %X, 0'
   }
 
-  return Changed ? I : 0;
+  return Changed ? &I : 0;
 }
 
 
-Instruction *InstCombiner::visitDiv(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
-
+Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
   // div X, 1 == X
-  if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1)))
-    if (RHS->equalsInt(1)) {
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(I->getOperand(0));
-      return I;
-    }
+  if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1)))
+    if (RHS->equalsInt(1))
+      return ReplaceInstUsesWith(I, I.getOperand(0));
   return 0;
 }
 
 
-Instruction *InstCombiner::visitRem(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
-
+Instruction *InstCombiner::visitRem(BinaryOperator &I) {
   // rem X, 1 == 0
-  if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1)))
-    if (RHS->equalsInt(1)) {
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
-      return I;
-    }
+  if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1)))
+    if (RHS->equalsInt(1))
+      return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
   return 0;
 }
 
-static Constant *getMaxValue(const Type *Ty) {
-  assert(Ty == Type::BoolTy || Ty->isIntegral());
-  if (Ty == Type::BoolTy)
-    return ConstantBool::True;
-
-  if (Ty->isSigned())
-    return ConstantSInt::get(Ty, -1);
-  else if (Ty->isUnsigned()) {
+// isMaxValueMinusOne - return true if this is Max-1
+static bool isMaxValueMinusOne(const ConstantInt *C) {
+  if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(C)) {
     // Calculate -1 casted to the right type...
-    unsigned TypeBits = Ty->getPrimitiveSize()*8;
-    uint64_t Val = (uint64_t)-1LL;       // All ones
+    unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+    uint64_t Val = ~0ULL;                // All ones
     Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
-    return ConstantUInt::get(Ty, Val);
+    return CU->getValue() == Val-1;
   }
-  return 0;
+
+  const ConstantSInt *CS = cast<ConstantSInt>(C);
+  
+  // Calculate 0111111111..11111
+  unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+  int64_t Val = INT64_MAX;             // All ones
+  Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
+  return CS->getValue() == Val-1;
+}
+
+// isMinValuePlusOne - return true if this is Min+1
+static bool isMinValuePlusOne(const ConstantInt *C) {
+  if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(C))
+    return CU->getValue() == 1;
+
+  const ConstantSInt *CS = cast<ConstantSInt>(C);
+  
+  // Calculate 1111111111000000000000 
+  unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+  int64_t Val = -1;                    // All ones
+  Val <<= TypeBits-1;                  // Shift over to the right spot
+  return CS->getValue() == Val+1;
 }
 
 
-Instruction *InstCombiner::visitAnd(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
+Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
   bool Changed = SimplifyBinOp(I);
-  Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
   // and X, X = X   and X, 0 == 0
-  if (Op0 == Op1 || Op1 == Constant::getNullValue(I->getType())) {
-    AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(Op1);
-    return I;
-  }
+  if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
+    return ReplaceInstUsesWith(I, Op1);
 
   // and X, -1 == X
-  if (Constant *RHS = dyn_cast<Constant>(Op1))
-    if (RHS == getMaxValue(I->getType())) {
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(Op0);
-      return I;
-    }
+  if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1))
+    if (RHS->isAllOnesValue())
+      return ReplaceInstUsesWith(I, Op0);
+
+  // and (not A), (not B) == not (or A, B)
+  if (Op0->use_size() == 1 && Op1->use_size() == 1)
+    if (Value *A = dyn_castNotInst(Op0))
+      if (Value *B = dyn_castNotInst(Op1)) {
+        Instruction *Or = BinaryOperator::create(Instruction::Or, A, B,
+                                                 I.getName()+".demorgan");
+        InsertNewInstBefore(Or, I);
+        return BinaryOperator::createNot(Or, I.getName());
+      }
 
-  return Changed ? I : 0;
+  return Changed ? &I : 0;
 }
 
 
 
-Instruction *InstCombiner::visitOr(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
+Instruction *InstCombiner::visitOr(BinaryOperator &I) {
   bool Changed = SimplifyBinOp(I);
-  Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
   // or X, X = X   or X, 0 == X
-  if (Op0 == Op1 || Op1 == Constant::getNullValue(I->getType())) {
-    AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(Op0);
-    return I;
-  }
+  if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
+    return ReplaceInstUsesWith(I, Op0);
 
   // or X, -1 == -1
-  if (Constant *RHS = dyn_cast<Constant>(Op1))
-    if (RHS == getMaxValue(I->getType())) {
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(Op1);
-      return I;
-    }
+  if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1))
+    if (RHS->isAllOnesValue())
+      return ReplaceInstUsesWith(I, Op1);
 
-  return Changed ? I : 0;
+  return Changed ? &I : 0;
 }
 
 
 
-Instruction *InstCombiner::visitXor(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
+Instruction *InstCombiner::visitXor(BinaryOperator &I) {
   bool Changed = SimplifyBinOp(I);
-  Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
   // xor X, X = 0
-  if (Op0 == Op1) {
-    AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
-    return I;
+  if (Op0 == Op1)
+    return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
+  if (ConstantIntegral *Op1C = dyn_cast<ConstantIntegral>(Op1)) {
+    // xor X, 0 == X
+    if (Op1C->isNullValue())
+      return ReplaceInstUsesWith(I, Op0);
+
+    // Is this a "NOT" instruction?
+    if (Op1C->isAllOnesValue()) {
+      // xor (xor X, -1), -1 = not (not X) = X
+      if (Value *X = dyn_castNotInst(Op0))
+        return ReplaceInstUsesWith(I, X);
+
+      // xor (setcc A, B), true = not (setcc A, B) = setncc A, B
+      if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0))
+        if (SCI->use_size() == 1)
+          return new SetCondInst(SCI->getInverseCondition(),
+                                 SCI->getOperand(0), SCI->getOperand(1));
+    }
   }
 
-  // xor X, 0 == X
-  if (Op1 == Constant::getNullValue(I->getType())) {
-    AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(Op0);
-    return I;
-  }
+  return Changed ? &I : 0;
+}
 
-  return Changed ? I : 0;
+// AddOne, SubOne - Add or subtract a constant one from an integer constant...
+static Constant *AddOne(ConstantInt *C) {
+  Constant *Result = *C + *ConstantInt::get(C->getType(), 1);
+  assert(Result && "Constant folding integer addition failed!");
+  return Result;
+}
+static Constant *SubOne(ConstantInt *C) {
+  Constant *Result = *C - *ConstantInt::get(C->getType(), 1);
+  assert(Result && "Constant folding integer addition failed!");
+  return Result;
 }
 
-Instruction *InstCombiner::visitSetCondInst(BinaryOperator *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
+// 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) {
   bool Changed = SimplifyBinOp(I);
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+  const Type *Ty = Op0->getType();
 
   // 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));
-    return I;
+  if (Op0 == Op1)
+    return ReplaceInstUsesWith(I, ConstantBool::get(isTrueWhenEqual(I)));
+
+  // setcc <global*>, 0 - Global value addresses are never null!
+  if (isa<GlobalValue>(Op0) && isa<ConstantPointerNull>(Op1))
+    return ReplaceInstUsesWith(I, ConstantBool::get(!isTrueWhenEqual(I)));
+
+  // setcc's with boolean values can always be turned into bitwise operations
+  if (Ty == Type::BoolTy) {
+    // If this is <, >, or !=, we can change this into a simple xor instruction
+    if (!isTrueWhenEqual(I))
+      return BinaryOperator::create(Instruction::Xor, Op0, Op1, I.getName());
+
+    // Otherwise we need to make a temporary intermediate instruction and insert
+    // it into the instruction stream.  This is what we are after:
+    //
+    //  seteq bool %A, %B -> ~(A^B)
+    //  setle bool %A, %B -> ~A | B
+    //  setge bool %A, %B -> A | ~B
+    //
+    if (I.getOpcode() == Instruction::SetEQ) {  // seteq case
+      Instruction *Xor = BinaryOperator::create(Instruction::Xor, Op0, Op1,
+                                                I.getName()+"tmp");
+      InsertNewInstBefore(Xor, I);
+      return BinaryOperator::createNot(Xor, I.getName());
+    }
+
+    // Handle the setXe cases...
+    assert(I.getOpcode() == Instruction::SetGE ||
+           I.getOpcode() == Instruction::SetLE);
+
+    if (I.getOpcode() == Instruction::SetGE)
+      std::swap(Op0, Op1);                   // Change setge -> setle
+
+    // Now we just have the SetLE case.
+    Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
+    InsertNewInstBefore(Not, I);
+    return BinaryOperator::create(Instruction::Or, Not, Op1, I.getName());
   }
 
-  return Changed ? I : 0;
+  // Check to see if we are doing one of many comparisons against constant
+  // integers at the end of their ranges...
+  //
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+    // Check to see if we are comparing against the minimum or maximum value...
+    if (CI->isMinValue()) {
+      if (I.getOpcode() == Instruction::SetLT)       // A < MIN -> FALSE
+        return ReplaceInstUsesWith(I, ConstantBool::False);
+      if (I.getOpcode() == Instruction::SetGE)       // A >= MIN -> TRUE
+        return ReplaceInstUsesWith(I, ConstantBool::True);
+      if (I.getOpcode() == Instruction::SetLE)       // A <= MIN -> A == MIN
+        return BinaryOperator::create(Instruction::SetEQ, Op0,Op1, I.getName());
+      if (I.getOpcode() == Instruction::SetGT)       // A > MIN -> A != MIN
+        return BinaryOperator::create(Instruction::SetNE, Op0,Op1, I.getName());
+
+    } else if (CI->isMaxValue()) {
+      if (I.getOpcode() == Instruction::SetGT)       // A > MAX -> FALSE
+        return ReplaceInstUsesWith(I, ConstantBool::False);
+      if (I.getOpcode() == Instruction::SetLE)       // A <= MAX -> TRUE
+        return ReplaceInstUsesWith(I, ConstantBool::True);
+      if (I.getOpcode() == Instruction::SetGE)       // A >= MAX -> A == MAX
+        return BinaryOperator::create(Instruction::SetEQ, Op0,Op1, I.getName());
+      if (I.getOpcode() == Instruction::SetLT)       // A < MAX -> A != MAX
+        return BinaryOperator::create(Instruction::SetNE, Op0,Op1, I.getName());
+
+      // Comparing against a value really close to min or max?
+    } else if (isMinValuePlusOne(CI)) {
+      if (I.getOpcode() == Instruction::SetLT)       // A < MIN+1 -> A == MIN
+        return BinaryOperator::create(Instruction::SetEQ, Op0,
+                                      SubOne(CI), I.getName());
+      if (I.getOpcode() == Instruction::SetGE)       // A >= MIN-1 -> A != MIN
+        return BinaryOperator::create(Instruction::SetNE, Op0,
+                                      SubOne(CI), I.getName());
+
+    } else if (isMaxValueMinusOne(CI)) {
+      if (I.getOpcode() == Instruction::SetGT)       // A > MAX-1 -> A == MAX
+        return BinaryOperator::create(Instruction::SetEQ, Op0,
+                                      AddOne(CI), I.getName());
+      if (I.getOpcode() == Instruction::SetLE)       // A <= MAX-1 -> A != MAX
+        return BinaryOperator::create(Instruction::SetNE, Op0,
+                                      AddOne(CI), I.getName());
+    }
+  }
+
+  return Changed ? &I : 0;
 }
 
 
 
-Instruction *InstCombiner::visitShiftInst(Instruction *I) {
-  if (I->use_empty()) return 0;       // Don't fix dead instructions...
-  assert(I->getOperand(1)->getType() == Type::UByteTy);
-  Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1);
+Instruction *InstCombiner::visitShiftInst(Instruction &I) {
+  assert(I.getOperand(1)->getType() == Type::UByteTy);
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
   // shl X, 0 == X and shr X, 0 == X
   // shl 0, X == 0 and shr 0, X == 0
   if (Op1 == Constant::getNullValue(Type::UByteTy) ||
-      Op0 == Constant::getNullValue(Op0->getType())) {
-    AddUsesToWorkList(I);         // Add all modified instrs to worklist
-    I->replaceAllUsesWith(Op0);
-    return I;
-  }
+      Op0 == Constant::getNullValue(Op0->getType()))
+    return ReplaceInstUsesWith(I, Op0);
 
-  // shl int X, 32 = 0 and shr sbyte Y, 9 = 0, ... just don't eliminate shr of
+  // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr of
   // a signed value.
   //
   if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
-    unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
-    if (CUI->getValue() >= TypeBits &&
-        !(Op0->getType()->isSigned() && I->getOpcode() == Instruction::Shr)) {
-      AddUsesToWorkList(I);         // Add all modified instrs to worklist
-      I->replaceAllUsesWith(Constant::getNullValue(Op0->getType()));
-      return I;
+    if (I.getOpcode() == Instruction::Shr) {
+      unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
+      if (CUI->getValue() >= TypeBits && !(Op0->getType()->isSigned()))
+        return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
     }
+
+    // Check to see if we are shifting left by 1.  If so, turn it into an add
+    // instruction.
+    if (I.getOpcode() == Instruction::Shl && CUI->equalsInt(1))
+      // Convert 'shl int %X, 2' to 'add int %X, %X'
+      return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName());
+
   }
   return 0;
 }
@@ -386,21 +510,62 @@ Instruction *InstCombiner::visitShiftInst(Instruction *I) {
 // isEliminableCastOfCast - Return true if it is valid to eliminate the CI
 // instruction.
 //
-static inline bool isEliminableCastOfCast(const CastInst *CI,
+static inline bool isEliminableCastOfCast(const CastInst &CI,
                                           const CastInst *CSrc) {
-  assert(CI->getOperand(0) == CSrc);
+  assert(CI.getOperand(0) == CSrc);
   const Type *SrcTy = CSrc->getOperand(0)->getType();
   const Type *MidTy = CSrc->getType();
-  const Type *DstTy = CI->getType();
+  const Type *DstTy = CI.getType();
 
-  // It is legal to eliminate the instruction if casting A->B->A
-  if (SrcTy == DstTy) return true;
+  // It is legal to eliminate the instruction if casting A->B->A if the sizes
+  // are identical and the bits don't get reinterpreted (for example 
+  // int->float->int would not be allowed)
+  if (SrcTy == DstTy && SrcTy->isLosslesslyConvertableTo(MidTy))
+    return true;
 
   // Allow free casting and conversion of sizes as long as the sign doesn't
   // change...
-  if (SrcTy->isSigned() == MidTy->isSigned() &&
-      MidTy->isSigned() == DstTy->isSigned())
-    return true;
+  if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) {
+    unsigned SrcSize = SrcTy->getPrimitiveSize();
+    unsigned MidSize = MidTy->getPrimitiveSize();
+    unsigned DstSize = DstTy->getPrimitiveSize();
+
+    // Cases where we are monotonically decreasing the size of the type are
+    // always ok, regardless of what sign changes are going on.
+    //
+    if (SrcSize >= MidSize && MidSize >= DstSize)
+      return true;
+
+    // If we are monotonically growing, things are more complex.
+    //
+    if (SrcSize <= MidSize && MidSize <= DstSize) {
+      // We have eight combinations of signedness to worry about. Here's the
+      // table:
+      static const int SignTable[8] = {
+        // CODE, SrcSigned, MidSigned, DstSigned, Comment
+        1,     //   U          U          U       Always ok
+        1,     //   U          U          S       Always ok
+        3,     //   U          S          U       Ok iff SrcSize != MidSize
+        3,     //   U          S          S       Ok iff SrcSize != MidSize
+        0,     //   S          U          U       Never ok
+        2,     //   S          U          S       Ok iff MidSize == DstSize
+        1,     //   S          S          U       Always ok
+        1,     //   S          S          S       Always ok
+      };
+
+      // Choose an action based on the current entry of the signtable that this
+      // cast of cast refers to...
+      unsigned Row = SrcTy->isSigned()*4+MidTy->isSigned()*2+DstTy->isSigned();
+      switch (SignTable[Row]) {
+      case 0: return false;              // Never ok
+      case 1: return true;               // Always ok
+      case 2: return MidSize == DstSize; // Ok iff MidSize == DstSize
+      case 3:                            // Ok iff SrcSize != MidSize
+        return SrcSize != MidSize || SrcTy == Type::BoolTy;
+      default: assert(0 && "Bad entry in sign table!");
+      }
+    }
+  }
 
   // Otherwise, we cannot succeed.  Specifically we do not want to allow things
   // like:  short -> ushort -> uint, because this can create wrong results if
@@ -412,107 +577,136 @@ static inline bool isEliminableCastOfCast(const CastInst *CI,
 
 // CastInst simplification
 //
-Instruction *InstCombiner::visitCastInst(CastInst *CI) {
-  if (CI->use_empty()) return 0;       // Don't fix dead instructions...
-
+Instruction *InstCombiner::visitCastInst(CastInst &CI) {
   // If the user is casting a value to the same type, eliminate this cast
   // instruction...
-  if (CI->getType() == CI->getOperand(0)->getType() && !CI->use_empty()) {
-    AddUsesToWorkList(CI);         // Add all modified instrs to worklist
-    CI->replaceAllUsesWith(CI->getOperand(0));
-    return CI;
-  }
-
+  if (CI.getType() == CI.getOperand(0)->getType())
+    return ReplaceInstUsesWith(CI, CI.getOperand(0));
 
   // If casting the result of another cast instruction, try to eliminate this
   // one!
   //
-  if (CastInst *CSrc = dyn_cast<CastInst>(CI->getOperand(0)))
+  if (CastInst *CSrc = dyn_cast<CastInst>(CI.getOperand(0))) {
     if (isEliminableCastOfCast(CI, CSrc)) {
       // This instruction now refers directly to the cast's src operand.  This
       // has a good chance of making CSrc dead.
-      CI->setOperand(0, CSrc->getOperand(0));
-      return CI;
+      CI.setOperand(0, CSrc->getOperand(0));
+      return &CI;
     }
 
+    // If this is an A->B->A cast, and we are dealing with integral types, try
+    // to convert this into a logical 'and' instruction.
+    //
+    if (CSrc->getOperand(0)->getType() == CI.getType() &&
+        CI.getType()->isInteger() && CSrc->getType()->isInteger() &&
+        CI.getType()->isUnsigned() && CSrc->getType()->isUnsigned() &&
+        CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()){
+      assert(CSrc->getType() != Type::ULongTy &&
+             "Cannot have type bigger than ulong!");
+      unsigned AndValue = (1U << CSrc->getType()->getPrimitiveSize()*8)-1;
+      Constant *AndOp = ConstantUInt::get(CI.getType(), AndValue);
+      return BinaryOperator::create(Instruction::And, CSrc->getOperand(0),
+                                    AndOp);
+    }
+  }
+
   return 0;
 }
 
 
 // PHINode simplification
 //
-Instruction *InstCombiner::visitPHINode(PHINode *PN) {
-  if (PN->use_empty()) return 0;       // Don't fix dead instructions...
-
+Instruction *InstCombiner::visitPHINode(PHINode &PN) {
   // If the PHI node only has one incoming value, eliminate the PHI node...
-  if (PN->getNumIncomingValues() == 1) {
-    AddUsesToWorkList(PN);         // Add all modified instrs to worklist
-    PN->replaceAllUsesWith(PN->getIncomingValue(0));
-    return PN;
-  }
+  if (PN.getNumIncomingValues() == 0)
+    return ReplaceInstUsesWith(PN, Constant::getNullValue(PN.getType()));
+  if (PN.getNumIncomingValues() == 1)
+    return ReplaceInstUsesWith(PN, PN.getIncomingValue(0));
+  
+  // Otherwise if all of the incoming values are the same for the PHI, replace
+  // the PHI node with the incoming value.
+  //
+  Value *InVal = 0;
+  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
+    if (PN.getIncomingValue(i) != &PN)  // Not the PHI node itself...
+      if (InVal && PN.getIncomingValue(i) != InVal)
+        return 0;  // Not the same, bail out.
+      else
+        InVal = PN.getIncomingValue(i);
+
+  // The only case that could cause InVal to be null is if we have a PHI node
+  // that only has entries for itself.  In this case, there is no entry into the
+  // loop, so kill the PHI.
+  //
+  if (InVal == 0) InVal = Constant::getNullValue(PN.getType());
 
-  return 0;
+  // All of the incoming values are the same, replace the PHI node now.
+  return ReplaceInstUsesWith(PN, InVal);
 }
 
 
-Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst *GEP) {
-  // Is it getelementptr %P, uint 0
-  // If so, elminate the noop.
-  if (GEP->getNumOperands() == 2 && !GEP->use_empty() &&
-      GEP->getOperand(1) == Constant::getNullValue(Type::UIntTy)) {
-    AddUsesToWorkList(GEP);         // Add all modified instrs to worklist
-    GEP->replaceAllUsesWith(GEP->getOperand(0));
-    return GEP;
-  }
+Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
+  // Is it 'getelementptr %P, uint 0'  or 'getelementptr %P'
+  // If so, eliminate the noop.
+  if ((GEP.getNumOperands() == 2 &&
+       GEP.getOperand(1) == Constant::getNullValue(Type::UIntTy)) ||
+      GEP.getNumOperands() == 1)
+    return ReplaceInstUsesWith(GEP, GEP.getOperand(0));
 
-  return visitMemAccessInst(GEP);
-}
+  // Combine Indices - If the source pointer to this getelementptr instruction
+  // is a getelementptr instruction, combine the indices of the two
+  // getelementptr instructions into a single instruction.
+  //
+  if (GetElementPtrInst *Src = dyn_cast<GetElementPtrInst>(GEP.getOperand(0))) {
+    std::vector<Value *> Indices;
+  
+    // Can we combine the two pointer arithmetics offsets?
+    if (Src->getNumOperands() == 2 && isa<Constant>(Src->getOperand(1)) &&
+        isa<Constant>(GEP.getOperand(1))) {
+      // Replace the index list on this GEP with the index on the getelementptr
+      Indices.insert(Indices.end(), GEP.idx_begin(), GEP.idx_end());
+      Indices[0] = *cast<Constant>(Src->getOperand(1)) +
+                   *cast<Constant>(GEP.getOperand(1));
+      assert(Indices[0] != 0 && "Constant folding of uint's failed!?");
+
+    } else if (*GEP.idx_begin() == ConstantUInt::get(Type::UIntTy, 0)) { 
+      // Otherwise we can do the fold if the first index of the GEP is a zero
+      Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
+      Indices.insert(Indices.end(), GEP.idx_begin()+1, GEP.idx_end());
+    }
 
+    if (!Indices.empty())
+      return new GetElementPtrInst(Src->getOperand(0), Indices, GEP.getName());
 
-// Combine Indices - If the source pointer to this mem access instruction is a
-// getelementptr instruction, combine the indices of the GEP into this
-// instruction
-//
-Instruction *InstCombiner::visitMemAccessInst(MemAccessInst *MAI) {
-  GetElementPtrInst *Src =
-    dyn_cast<GetElementPtrInst>(MAI->getPointerOperand());
-  if (!Src) return 0;
+  } else if (GlobalValue *GV = dyn_cast<GlobalValue>(GEP.getOperand(0))) {
+    // GEP of global variable.  If all of the indices for this GEP are
+    // constants, we can promote this to a constexpr instead of an instruction.
 
-  std::vector<Value *> Indices;
-  
-  // Only special case we have to watch out for is pointer arithmetic on the
-  // 0th index of MAI. 
-  unsigned FirstIdx = MAI->getFirstIndexOperandNumber();
-  if (FirstIdx == MAI->getNumOperands() || 
-      (FirstIdx == MAI->getNumOperands()-1 &&
-       MAI->getOperand(FirstIdx) == ConstantUInt::get(Type::UIntTy, 0))) { 
-    // Replace the index list on this MAI with the index on the getelementptr
-    Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
-  } else if (*MAI->idx_begin() == ConstantUInt::get(Type::UIntTy, 0)) { 
-    // Otherwise we can do the fold if the first index of the GEP is a zero
-    Indices.insert(Indices.end(), Src->idx_begin(), Src->idx_end());
-    Indices.insert(Indices.end(), MAI->idx_begin()+1, MAI->idx_end());
-  }
+    // Scan for nonconstants...
+    std::vector<Constant*> Indices;
+    User::op_iterator I = GEP.idx_begin(), E = GEP.idx_end();
+    for (; I != E && isa<Constant>(*I); ++I)
+      Indices.push_back(cast<Constant>(*I));
+
+    if (I == E) {  // If they are all constants...
+      ConstantExpr *CE =
+        ConstantExpr::getGetElementPtr(ConstantPointerRef::get(GV), Indices);
 
-  if (Indices.empty()) return 0;  // Can't do the fold?
-
-  switch (MAI->getOpcode()) {
-  case Instruction::GetElementPtr:
-    return new GetElementPtrInst(Src->getOperand(0), Indices, MAI->getName());
-  case Instruction::Load:
-    return new LoadInst(Src->getOperand(0), Indices, MAI->getName());
-  case Instruction::Store:
-    return new StoreInst(MAI->getOperand(0), Src->getOperand(0), Indices);
-  default:
-    assert(0 && "Unknown memaccessinst!");
-    break;
+      // Replace all uses of the GEP with the new constexpr...
+      return ReplaceInstUsesWith(GEP, CE);
+    }
   }
-  abort();
+
   return 0;
 }
 
 
-bool InstCombiner::runOnFunction(Function *F) {
+void InstCombiner::removeFromWorkList(Instruction *I) {
+  WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),
+                 WorkList.end());
+}
+
+bool InstCombiner::runOnFunction(Function &F) {
   bool Changed = false;
 
   WorkList.insert(WorkList.end(), inst_begin(F), inst_end(F));
@@ -521,15 +715,63 @@ bool InstCombiner::runOnFunction(Function *F) {
     Instruction *I = WorkList.back();  // Get an instruction from the worklist
     WorkList.pop_back();
 
+    // Check to see if we can DCE or ConstantPropogate the instruction...
+    // Check to see if we can DIE the instruction...
+    if (isInstructionTriviallyDead(I)) {
+      // Add operands to the worklist...
+      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+        if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(i)))
+          WorkList.push_back(Op);
+
+      ++NumDeadInst;
+      BasicBlock::iterator BBI = I;
+      if (dceInstruction(BBI)) {
+        removeFromWorkList(I);
+        continue;
+      }
+    } 
+
+    // Instruction isn't dead, see if we can constant propogate it...
+    if (Constant *C = ConstantFoldInstruction(I)) {
+      // Add operands to the worklist...
+      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+        if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(i)))
+          WorkList.push_back(Op);
+      I->replaceAllUsesWith(C);
+      ++NumConstProp;
+      BasicBlock::iterator BBI = I;
+      if (dceInstruction(BBI)) {
+        removeFromWorkList(I);
+        continue;
+      }
+    }
+    
     // Now that we have an instruction, try combining it to simplify it...
-    Instruction *Result = visit(I);
-    if (Result) {
+    if (Instruction *Result = visit(*I)) {
+      ++NumCombined;
       // Should we replace the old instruction with a new one?
-      if (Result != I)
+      if (Result != I) {
+        // Instructions can end up on the worklist more than once.  Make sure
+        // we do not process an instruction that has been deleted.
+        removeFromWorkList(I);
         ReplaceInstWithInst(I, Result);
+      } else {
+        BasicBlock::iterator II = I;
+
+        // If the instruction was modified, it's possible that it is now dead.
+        // if so, remove it.
+        if (dceInstruction(II)) {
+          // Instructions may end up in the worklist more than once.  Erase them
+          // all.
+          removeFromWorkList(I);
+          Result = 0;
+        }
+      }
 
-      WorkList.push_back(Result);
-      AddUsesToWorkList(Result);
+      if (Result) {
+        WorkList.push_back(Result);
+        AddUsesToWorkList(*Result);
+      }
       Changed = true;
     }
   }