Implement InstCombine/2003-08-12-AllocaNonNull.ll
[oota-llvm.git] / lib / Transforms / Scalar / InstructionCombining.cpp
index 5d04d7737ffe2872ed28e0beaa73978b6f417316..8a3c0d47e97f0b41c51b77244a9203644c240639 100644 (file)
 //
 // This is a simple worklist driven algorithm.
 //
+// This pass guarantees that the following cannonicalizations are performed on
+// the program:
+//    1. If a binary operator has a constant operand, it is moved to the RHS
+//    2. Bitwise operators with constant operands are always grouped so that
+//       shifts are performed first, then or's, then and's, then xor's.
+//    3. SetCC instructions are converted from <,>,<=,>= to ==,!= if possible
+//    4. All SetCC instructions on boolean values are replaced with logical ops
+//    5. add X, X is represented as (X*2) => (X << 1)
+//    6. Multiplies with a power-of-two constant argument are transformed into
+//       shifts.
+//    N. This list is incomplete
+//
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Scalar.h"
@@ -112,6 +124,13 @@ namespace {
       return &I;
     }
 
+    /// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
+    /// InsertBefore instruction.  This is specialized a bit to avoid inserting
+    /// casts that are known to not do anything...
+    ///
+    Value *InsertOperandCastBefore(Value *V, const Type *DestTy,
+                                   Instruction *InsertBefore);
+
     // SimplifyCommutative - This performs a few simplifications for commutative
     // operators...
     bool SimplifyCommutative(BinaryOperator &I);
@@ -225,7 +244,8 @@ static inline Value *dyn_castFoldableMul(Value *V) {
 // dyn_castMaskingAnd - If this value is an And instruction masking a value with
 // a constant, return the constant being anded with.
 //
-static inline Constant *dyn_castMaskingAnd(Value *V) {
+template<class ValueType>
+static inline Constant *dyn_castMaskingAnd(ValueType *V) {
   if (Instruction *I = dyn_cast<Instruction>(V))
     if (I->getOpcode() == Instruction::And)
       return dyn_cast<Constant>(I->getOperand(1));
@@ -255,6 +275,11 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   if (RHS == Constant::getNullValue(I.getType()))
     return ReplaceInstUsesWith(I, LHS);
 
+  // Convert 'add X, X' to 'shl X, 1'
+  if (LHS == RHS && I.getType()->isInteger())
+    return new ShiftInst(Instruction::Shl, LHS,
+                         ConstantInt::get(Type::UByteTy, 1));
+
   // -A + B  -->  B - A
   if (Value *V = dyn_castNegVal(LHS))
     return BinaryOperator::create(Instruction::Sub, RHS, V);
@@ -291,6 +316,17 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
   return Changed ? &I : 0;
 }
 
+// isSignBit - Return true if the value represented by the constant only has the
+// highest order bit set.
+static bool isSignBit(ConstantInt *CI) {
+  unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+  return (CI->getRawValue() & ~(-1LL << NumBits)) == (1ULL << (NumBits-1));
+}
+
+static unsigned getTypeSizeInBits(const Type *Ty) {
+  return Ty == Type::BoolTy ? 1 : Ty->getPrimitiveSize()*8;
+}
+
 Instruction *InstCombiner::visitSub(BinaryOperator &I) {
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
@@ -362,9 +398,16 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
   // Simplify mul instructions with a constant RHS...
   if (Constant *Op1 = dyn_cast<Constant>(I.getOperand(1))) {
     if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+
+      // ((X << C1)*C2) == (X * (C2 << C1))
+      if (ShiftInst *SI = dyn_cast<ShiftInst>(Op0))
+        if (SI->getOpcode() == Instruction::Shl)
+          if (Constant *ShOp = dyn_cast<Constant>(SI->getOperand(1)))
+            return BinaryOperator::create(Instruction::Mul, SI->getOperand(0),
+                                          *CI << *ShOp);
+
       const Type *Ty = CI->getType();
-      int64_t Val = Ty->isSigned() ?        cast<ConstantSInt>(CI)->getValue() :
-                                   (int64_t)cast<ConstantUInt>(CI)->getValue();
+      int64_t Val = (int64_t)cast<ConstantInt>(CI)->getRawValue();
       switch (Val) {
       case -1:                               // X * -1 -> -X
         return BinaryOperator::createNeg(Op0, I.getName());
@@ -372,8 +415,6 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
         return ReplaceInstUsesWith(I, Op1);  // Eliminate 'mul double %X, 0'
       case 1:
         return ReplaceInstUsesWith(I, Op0);  // Eliminate 'mul int %X, 1'
-      case 2:                     // Convert 'mul int %X, 2' to 'add int %X, %X'
-        return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName());
       }
 
       if (uint64_t C = Log2(Val))            // Replace X*(2^C) with X << C
@@ -487,19 +528,56 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
     return ReplaceInstUsesWith(I, Op1);
 
   // and X, -1 == X
-  if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1))
+  if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
     if (RHS->isAllOnesValue())
       return ReplaceInstUsesWith(I, Op0);
 
+    if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
+      Value *X = Op0I->getOperand(0);
+      if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
+        if (Op0I->getOpcode() == Instruction::Xor) {
+          if ((*RHS & *Op0CI)->isNullValue()) {
+            // (X ^ C1) & C2 --> (X & C2) iff (C1&C2) == 0
+            return BinaryOperator::create(Instruction::And, X, RHS);
+          } else if (isOnlyUse(Op0)) {
+            // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
+            std::string Op0Name = Op0I->getName(); Op0I->setName("");
+            Instruction *And = BinaryOperator::create(Instruction::And,
+                                                      X, RHS, Op0Name);
+            InsertNewInstBefore(And, I);
+            return BinaryOperator::create(Instruction::Xor, And, *RHS & *Op0CI);
+          }
+        } else if (Op0I->getOpcode() == Instruction::Or) {
+          // (X | C1) & C2 --> X & C2 iff C1 & C1 == 0
+          if ((*RHS & *Op0CI)->isNullValue())
+            return BinaryOperator::create(Instruction::And, X, RHS);
+
+          Constant *Together = *RHS & *Op0CI;
+          if (Together == RHS) // (X | C) & C --> C
+            return ReplaceInstUsesWith(I, RHS);
+
+          if (isOnlyUse(Op0)) {
+            if (Together != Op0CI) {
+              // (X | C1) & C2 --> (X | (C1&C2)) & C2
+              std::string Op0Name = Op0I->getName(); Op0I->setName("");
+              Instruction *Or = BinaryOperator::create(Instruction::Or, X,
+                                                       Together, Op0Name);
+              InsertNewInstBefore(Or, I);
+              return BinaryOperator::create(Instruction::And, Or, RHS);
+            }
+          }
+        }
+    }
+  }
+
   Value *Op0NotVal = dyn_castNotVal(Op0);
   Value *Op1NotVal = dyn_castNotVal(Op1);
 
   // (~A & ~B) == (~(A | B)) - Demorgan's Law
   if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) {
     Instruction *Or = BinaryOperator::create(Instruction::Or, Op0NotVal,
-                                             Op1NotVal,I.getName()+".demorgan",
-                                             &I);
-    WorkList.push_back(Or);
+                                             Op1NotVal,I.getName()+".demorgan");
+    InsertNewInstBefore(Or, I);
     return BinaryOperator::createNot(Or);
   }
 
@@ -520,10 +598,44 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
     return ReplaceInstUsesWith(I, Op0);
 
   // or X, -1 == -1
-  if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1))
+  if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
     if (RHS->isAllOnesValue())
       return ReplaceInstUsesWith(I, Op1);
 
+    if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
+      // (X & C1) | C2 --> (X | C2) & (C1|C2)
+      if (Op0I->getOpcode() == Instruction::And && isOnlyUse(Op0))
+        if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
+          std::string Op0Name = Op0I->getName(); Op0I->setName("");
+          Instruction *Or = BinaryOperator::create(Instruction::Or,
+                                                   Op0I->getOperand(0), RHS,
+                                                   Op0Name);
+          InsertNewInstBefore(Or, I);
+          return BinaryOperator::create(Instruction::And, Or, *RHS | *Op0CI);
+        }
+
+      // (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
+      if (Op0I->getOpcode() == Instruction::Xor && isOnlyUse(Op0))
+        if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
+          std::string Op0Name = Op0I->getName(); Op0I->setName("");
+          Instruction *Or = BinaryOperator::create(Instruction::Or,
+                                                   Op0I->getOperand(0), RHS,
+                                                   Op0Name);
+          InsertNewInstBefore(Or, I);
+          return BinaryOperator::create(Instruction::Xor, Or, *Op0CI & *~*RHS);
+        }
+    }
+  }
+
+  // (A & C1)|(A & C2) == A & (C1|C2)
+  if (Instruction *LHS = dyn_cast<BinaryOperator>(Op0))
+    if (Instruction *RHS = dyn_cast<BinaryOperator>(Op1))
+      if (LHS->getOperand(0) == RHS->getOperand(0))
+        if (Constant *C0 = dyn_castMaskingAnd(LHS))
+          if (Constant *C1 = dyn_castMaskingAnd(RHS))
+            return BinaryOperator::create(Instruction::And, LHS->getOperand(0),
+                                          *C0 | *C1);            
+
   Value *Op0NotVal = dyn_castNotVal(Op0);
   Value *Op1NotVal = dyn_castNotVal(Op1);
 
@@ -557,22 +669,28 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
   if (Op0 == Op1)
     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
 
-  if (ConstantIntegral *Op1C = dyn_cast<ConstantIntegral>(Op1)) {
+  if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
     // xor X, 0 == X
-    if (Op1C->isNullValue())
+    if (RHS->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_castNotVal(Op0))
-        return ReplaceInstUsesWith(I, X);
-
+    if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
       // xor (setcc A, B), true = not (setcc A, B) = setncc A, B
-      if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0))
-        if (SCI->use_size() == 1)
+      if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0I))
+        if (RHS == ConstantBool::True && SCI->use_size() == 1)
           return new SetCondInst(SCI->getInverseCondition(),
                                  SCI->getOperand(0), SCI->getOperand(1));
+          
+      if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
+        if (Op0I->getOpcode() == Instruction::And) {
+          // (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0
+          if ((*RHS & *Op0CI)->isNullValue())
+            return BinaryOperator::create(Instruction::Or, Op0, RHS);
+        } else if (Op0I->getOpcode() == Instruction::Or) {
+          // (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
+          if ((*RHS & *Op0CI) == RHS)
+            return BinaryOperator::create(Instruction::And, Op0, ~*RHS);
+        }
     }
   }
 
@@ -650,10 +768,12 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &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))
+  // setcc <global/alloca*>, 0 - Global/Stack value addresses are never null!
+  if (isa<ConstantPointerNull>(Op1) && 
+      (isa<GlobalValue>(Op0) || isa<AllocaInst>(Op0)))
     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
@@ -691,14 +811,87 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
   // integers at the end of their ranges...
   //
   if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
-    if (CI->isNullValue()) {
-      if (I.getOpcode() == Instruction::SetNE)
-        return new CastInst(Op0, Type::BoolTy, I.getName());
-      else if (I.getOpcode() == Instruction::SetEQ) {
-        // seteq X, 0 -> not (cast X to bool)
-        Instruction *Val = new CastInst(Op0, Type::BoolTy, I.getName()+".not");
-        InsertNewInstBefore(Val, I);
-        return BinaryOperator::createNot(Val, I.getName());
+    // Simplify seteq and setne instructions...
+    if (I.getOpcode() == Instruction::SetEQ ||
+        I.getOpcode() == Instruction::SetNE) {
+      bool isSetNE = I.getOpcode() == Instruction::SetNE;
+
+      // If the first operand is (and|or|xor) with a constant, and the second
+      // operand is a constant, simplify a bit.
+      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0)) {
+        switch (BO->getOpcode()) {
+        case Instruction::Add:
+          if (CI->isNullValue()) {
+            // Replace ((add A, B) != 0) with (A != -B) if A or B is
+            // efficiently invertible, or if the add has just this one use.
+            Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1);
+            if (Value *NegVal = dyn_castNegVal(BOp1))
+              return new SetCondInst(I.getOpcode(), BOp0, NegVal);
+            else if (Value *NegVal = dyn_castNegVal(BOp0))
+              return new SetCondInst(I.getOpcode(), NegVal, BOp1);
+            else if (BO->use_size() == 1) {
+              Instruction *Neg = BinaryOperator::createNeg(BOp1, BO->getName());
+              BO->setName("");
+              InsertNewInstBefore(Neg, I);
+              return new SetCondInst(I.getOpcode(), BOp0, Neg);
+            }
+          }
+          break;
+        case Instruction::Xor:
+          // For the xor case, we can xor two constants together, eliminating
+          // the explicit xor.
+          if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1)))
+            return BinaryOperator::create(I.getOpcode(), BO->getOperand(0),
+                                          *CI ^ *BOC);
+
+          // FALLTHROUGH
+        case Instruction::Sub:
+          // Replace (([sub|xor] A, B) != 0) with (A != B)
+          if (CI->isNullValue())
+            return new SetCondInst(I.getOpcode(), BO->getOperand(0),
+                                   BO->getOperand(1));
+          break;
+
+        case Instruction::Or:
+          // If bits are being or'd in that are not present in the constant we
+          // are comparing against, then the comparison could never succeed!
+          if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1)))
+            if (!(*BOC & *~*CI)->isNullValue())
+              return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
+          break;
+
+        case Instruction::And:
+          if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
+            // If bits are being compared against that are and'd out, then the
+            // comparison can never succeed!
+            if (!(*CI & *~*BOC)->isNullValue())
+              return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
+
+            // Replace (and X, (1 << size(X)-1) != 0) with x < 0, converting X
+            // to be a signed value as appropriate.
+            if (isSignBit(BOC)) {
+              Value *X = BO->getOperand(0);
+              // If 'X' is not signed, insert a cast now...
+              if (!BOC->getType()->isSigned()) {
+                const Type *DestTy;
+                switch (BOC->getType()->getPrimitiveID()) {
+                case Type::UByteTyID:  DestTy = Type::SByteTy; break;
+                case Type::UShortTyID: DestTy = Type::ShortTy; break;
+                case Type::UIntTyID:   DestTy = Type::IntTy;   break;
+                case Type::ULongTyID:  DestTy = Type::LongTy;  break;
+                default: assert(0 && "Invalid unsigned integer type!"); abort();
+                }
+                CastInst *NewCI = new CastInst(X,DestTy,X->getName()+".signed");
+                InsertNewInstBefore(NewCI, I);
+                X = NewCI;
+              }
+              return new SetCondInst(isSetNE ? Instruction::SetLT :
+                                         Instruction::SetGE, X,
+                                     Constant::getNullValue(X->getType()));
+            }
+          }
+        default: break;
+        }
       }
     }
 
@@ -750,6 +943,7 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
 Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
   assert(I.getOperand(1)->getType() == Type::UByteTy);
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+  bool isLeftShift = I.getOpcode() == Instruction::Shl;
 
   // shl X, 0 == X and shr X, 0 == X
   // shl 0, X == 0 and shr 0, X == 0
@@ -757,69 +951,118 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
       Op0 == Constant::getNullValue(Op0->getType()))
     return ReplaceInstUsesWith(I, Op0);
 
-  // If this is a shift of a shift, see if we can fold the two together...
-  if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0)) {
-    if (isa<Constant>(Op1) && isa<Constant>(Op0SI->getOperand(1))) {
-      ConstantUInt *ShiftAmt1C = cast<ConstantUInt>(Op0SI->getOperand(1));
-      unsigned ShiftAmt1 = ShiftAmt1C->getValue();
-      unsigned ShiftAmt2 = cast<ConstantUInt>(Op1)->getValue();
-
-      // Check for (A << c1) << c2   and   (A >> c1) >> c2
-      if (I.getOpcode() == Op0SI->getOpcode()) {
-        unsigned Amt = ShiftAmt1+ShiftAmt2;   // Fold into one big shift...
-        return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0),
-                             ConstantUInt::get(Type::UByteTy, Amt));
-      }
-
-      if (I.getType()->isUnsigned()) { // Check for (A << c1) >> c2 or visaversa
-        // Calculate bitmask for what gets shifted off the edge...
-        Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
-        if (I.getOpcode() == Instruction::Shr)
-          C = ConstantExpr::getShift(Instruction::Shr, C, ShiftAmt1C);
-        else
-          C = ConstantExpr::getShift(Instruction::Shl, C, ShiftAmt1C);
-          
-        Instruction *Mask =
-          BinaryOperator::create(Instruction::And, Op0SI->getOperand(0),
-                                 C, Op0SI->getOperand(0)->getName()+".mask",&I);
-        WorkList.push_back(Mask);
-          
-        // Figure out what flavor of shift we should use...
-        if (ShiftAmt1 == ShiftAmt2)
-          return ReplaceInstUsesWith(I, Mask);  // (A << c) >> c  === A & c2
-        else if (ShiftAmt1 < ShiftAmt2) {
-          return new ShiftInst(I.getOpcode(), Mask,
-                         ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
-        } else {
-          return new ShiftInst(Op0SI->getOpcode(), Mask,
-                         ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
-        }
-      }
-    }
-  }
+  // shr int -1, X = -1   (for any arithmetic shift rights of ~0)
+  if (!isLeftShift)
+    if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
+      if (CSI->isAllOnesValue())
+        return ReplaceInstUsesWith(I, CSI);
 
-  // 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)) {
+    // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
+    // of a signed value.
+    //
     unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
     if (CUI->getValue() >= TypeBits &&
-        (!Op0->getType()->isSigned() || I.getOpcode() == Instruction::Shl))
+        (!Op0->getType()->isSigned() || isLeftShift))
       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, 1' to 'add int %X, %X'
-      return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName());
+    // ((X*C1) << C2) == (X * (C1 << C2))
+    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0))
+      if (BO->getOpcode() == Instruction::Mul && isLeftShift)
+        if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1)))
+          return BinaryOperator::create(Instruction::Mul, BO->getOperand(0),
+                                        *BOOp << *CUI);
+    
+
+    // If the operand is an bitwise operator with a constant RHS, and the
+    // shift is the only use, we can pull it out of the shift.
+    if (Op0->use_size() == 1)
+      if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0))
+        if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) {
+          bool isValid = true;     // Valid only for And, Or, Xor
+          bool highBitSet = false; // Transform if high bit of constant set?
+
+          switch (Op0BO->getOpcode()) {
+          default: isValid = false; break;   // Do not perform transform!
+          case Instruction::Or:
+          case Instruction::Xor:
+            highBitSet = false;
+            break;
+          case Instruction::And:
+            highBitSet = true;
+            break;
+          }
+
+          // If this is a signed shift right, and the high bit is modified
+          // by the logical operation, do not perform the transformation.
+          // The highBitSet boolean indicates the value of the high bit of
+          // the constant which would cause it to be modified for this
+          // operation.
+          //
+          if (isValid && !isLeftShift && !I.getType()->isUnsigned()) {
+            uint64_t Val = Op0C->getRawValue();
+            isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet;
+          }
+
+          if (isValid) {
+            Constant *NewRHS =
+              ConstantFoldShiftInstruction(I.getOpcode(), Op0C, CUI);
+
+            Instruction *NewShift =
+              new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), CUI,
+                            Op0BO->getName());
+            Op0BO->setName("");
+            InsertNewInstBefore(NewShift, I);
+
+            return BinaryOperator::create(Op0BO->getOpcode(), NewShift,
+                                          NewRHS);
+          }
+        }
 
+    // If this is a shift of a shift, see if we can fold the two together...
+    if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0))
+      if (ConstantUInt *ShiftAmt1C =
+                                 dyn_cast<ConstantUInt>(Op0SI->getOperand(1))) {
+        unsigned ShiftAmt1 = ShiftAmt1C->getValue();
+        unsigned ShiftAmt2 = CUI->getValue();
+        
+        // Check for (A << c1) << c2   and   (A >> c1) >> c2
+        if (I.getOpcode() == Op0SI->getOpcode()) {
+          unsigned Amt = ShiftAmt1+ShiftAmt2;   // Fold into one big shift...
+          return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0),
+                               ConstantUInt::get(Type::UByteTy, Amt));
+        }
+        
+        // Check for (A << c1) >> c2 or visaversa.  If we are dealing with
+        // signed types, we can only support the (A >> c1) << c2 configuration,
+        // because it can not turn an arbitrary bit of A into a sign bit.
+        if (I.getType()->isUnsigned() || isLeftShift) {
+          // Calculate bitmask for what gets shifted off the edge...
+          Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
+          if (isLeftShift)
+            C = ConstantExpr::getShift(Instruction::Shl, C, ShiftAmt1C);
+          else
+            C = ConstantExpr::getShift(Instruction::Shr, C, ShiftAmt1C);
+          
+          Instruction *Mask =
+            BinaryOperator::create(Instruction::And, Op0SI->getOperand(0),
+                                   C, Op0SI->getOperand(0)->getName()+".mask");
+          InsertNewInstBefore(Mask, I);
+          
+          // Figure out what flavor of shift we should use...
+          if (ShiftAmt1 == ShiftAmt2)
+            return ReplaceInstUsesWith(I, Mask);  // (A << c) >> c  === A & c2
+          else if (ShiftAmt1 < ShiftAmt2) {
+            return new ShiftInst(I.getOpcode(), Mask,
+                         ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
+          } else {
+            return new ShiftInst(Op0SI->getOpcode(), Mask,
+                         ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
+          }
+        }
+      }
   }
 
-  // shr int -1, X = -1   (for any arithmetic shift rights of ~0)
-  if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
-    if (I.getOpcode() == Instruction::Shr && CSI->isAllOnesValue())
-      return ReplaceInstUsesWith(I, CSI);
-  
   return 0;
 }
 
@@ -827,12 +1070,8 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
 // isEliminableCastOfCast - Return true if it is valid to eliminate the CI
 // instruction.
 //
-static inline bool isEliminableCastOfCast(const CastInst &CI,
-                                          const CastInst *CSrc) {
-  assert(CI.getOperand(0) == CSrc);
-  const Type *SrcTy = CSrc->getOperand(0)->getType();
-  const Type *MidTy = CSrc->getType();
-  const Type *DstTy = CI.getType();
+static inline bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy,
+                                          const Type *DstTy) {
 
   // 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 
@@ -897,6 +1136,28 @@ static inline bool isEliminableCastOfCast(const CastInst &CI,
   return false;
 }
 
+static bool ValueRequiresCast(const Value *V, const Type *Ty) {
+  if (V->getType() == Ty || isa<Constant>(V)) return false;
+  if (const CastInst *CI = dyn_cast<CastInst>(V))
+    if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty))
+      return false;
+  return true;
+}
+
+/// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
+/// InsertBefore instruction.  This is specialized a bit to avoid inserting
+/// casts that are known to not do anything...
+///
+Value *InstCombiner::InsertOperandCastBefore(Value *V, const Type *DestTy,
+                                             Instruction *InsertBefore) {
+  if (V->getType() == DestTy) return V;
+  if (Constant *C = dyn_cast<Constant>(V))
+    return ConstantExpr::getCast(C, DestTy);
+
+  CastInst *CI = new CastInst(V, DestTy, V->getName());
+  InsertNewInstBefore(CI, *InsertBefore);
+  return CI;
+}
 
 // CastInst simplification
 //
@@ -912,7 +1173,8 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
   // one!
   //
   if (CastInst *CSrc = dyn_cast<CastInst>(Src)) {
-    if (isEliminableCastOfCast(CI, CSrc)) {
+    if (isEliminableCastOfCast(CSrc->getOperand(0)->getType(),
+                               CSrc->getType(), CI.getType())) {
       // 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));
@@ -952,33 +1214,53 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
     }
   }
 
-  // If this is a cast to bool (which is effectively a "!=0" test), then we can
-  // perform a few optimizations...
-  //
-  if (CI.getType() == Type::BoolTy) {
-    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Src)) {
-      Value *Op0 = BO->getOperand(0), *Op1 = BO->getOperand(1);
-
-      // Replace (cast (sub A, B) to bool) with (setne A, B)
-      if (BO->getOpcode() == Instruction::Sub)
-        return new SetCondInst(Instruction::SetNE, Op0, Op1);
-
-      // Replace (cast (add A, B) to bool) with (setne A, -B) if B is
-      // efficiently invertible, or if the add has just this one use.
-      if (BO->getOpcode() == Instruction::Add)
-        if (Value *NegVal = dyn_castNegVal(Op1))
-          return new SetCondInst(Instruction::SetNE, Op0, NegVal);
-        else if (Value *NegVal = dyn_castNegVal(Op0))
-          return new SetCondInst(Instruction::SetNE, NegVal, Op1);
-        else if (BO->use_size() == 1) {
-          Instruction *Neg = BinaryOperator::createNeg(Op1, BO->getName());
-          BO->setName("");
-          InsertNewInstBefore(Neg, CI);
-          return new SetCondInst(Instruction::SetNE, Op0, Neg);
+  // If the source value is an instruction with only this use, we can attempt to
+  // propagate the cast into the instruction.  Also, only handle integral types
+  // for now.
+  if (Instruction *SrcI = dyn_cast<Instruction>(Src))
+    if (SrcI->use_size() == 1 && Src->getType()->isIntegral() &&
+        CI.getType()->isInteger()) {  // Don't mess with casts to bool here
+      const Type *DestTy = CI.getType();
+      unsigned SrcBitSize = getTypeSizeInBits(Src->getType());
+      unsigned DestBitSize = getTypeSizeInBits(DestTy);
+
+      Value *Op0 = SrcI->getNumOperands() > 0 ? SrcI->getOperand(0) : 0;
+      Value *Op1 = SrcI->getNumOperands() > 1 ? SrcI->getOperand(1) : 0;
+
+      switch (SrcI->getOpcode()) {
+      case Instruction::Add:
+      case Instruction::Mul:
+      case Instruction::And:
+      case Instruction::Or:
+      case Instruction::Xor:
+        // If we are discarding information, or just changing the sign, rewrite.
+        if (DestBitSize <= SrcBitSize && DestBitSize != 1) {
+          // Don't insert two casts if they cannot be eliminated.  We allow two
+          // casts to be inserted if the sizes are the same.  This could only be
+          // converting signedness, which is a noop.
+          if (DestBitSize == SrcBitSize || !ValueRequiresCast(Op1, DestTy) ||
+              !ValueRequiresCast(Op0, DestTy)) {
+            Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI);
+            Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI);
+            return BinaryOperator::create(cast<BinaryOperator>(SrcI)
+                             ->getOpcode(), Op0c, Op1c);
+          }
+        }
+        break;
+      case Instruction::Shl:
+        // Allow changing the sign of the source operand.  Do not allow changing
+        // the size of the shift, UNLESS the shift amount is a constant.  We
+        // mush not change variable sized shifts to a smaller size, because it
+        // is undefined to shift more bits out than exist in the value.
+        if (DestBitSize == SrcBitSize ||
+            (DestBitSize < SrcBitSize && isa<Constant>(Op1))) {
+          Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI);
+          return new ShiftInst(Instruction::Shl, Op0c, Op1);
         }
+        break;
+      }
     }
-  }
-
+  
   return 0;
 }
 
@@ -1294,7 +1576,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
 
   // Instcombine load (constant global) into the value loaded...
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
-    if (GV->isConstant())
+    if (GV->isConstant() && !GV->isExternal())
       return ReplaceInstUsesWith(LI, GV->getInitializer());
 
   // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded...
@@ -1302,7 +1584,7 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
     if (CE->getOpcode() == Instruction::GetElementPtr)
       if (ConstantPointerRef *G=dyn_cast<ConstantPointerRef>(CE->getOperand(0)))
         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getValue()))
-          if (GV->isConstant())
+          if (GV->isConstant() && !GV->isExternal())
             if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
               return ReplaceInstUsesWith(LI, V);
   return 0;