We need to propagate the debug location information even when dealing with the
[oota-llvm.git] / lib / VMCore / ConstantFold.cpp
index 7644c1e4196183bc9b7c34febf2e54ef839910fa..ff4d897e54a8b945d1d49ff959a424f49452b943 100644 (file)
-//===- ConstantHandling.cpp - Implement ConstantHandling.h ----------------===//
+//===- ConstantFold.cpp - LLVM constant folder ----------------------------===//
 //
-// This file implements the various intrinsic operations, on constant values.
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements folding of constants for LLVM.  This implements the
+// (internal) ConstantFold.h interface, which is used by the
+// ConstantExpr::get* methods to automatically fold constants when possible.
+//
+// The current constant folding implementation is implemented in two pieces: the
+// template-based folder for simple primitive constants like ConstantInt, and
+// the special case hackery that we use to symbolically evaluate expressions
+// that use ConstantExprs.
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/ConstantHandling.h"
-#include "llvm/iPHINode.h"
-#include "llvm/InstrTypes.h"
+#include "ConstantFold.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
 #include "llvm/DerivedTypes.h"
-#include <cmath>
-
-AnnotationID ConstRules::AID(AnnotationManager::getID("opt::ConstRules",
-                                                     &ConstRules::find));
-
-// ConstantFoldInstruction - Attempt to constant fold the specified instruction.
-// If successful, the constant result is returned, if not, null is returned.
-//
-Constant *ConstantFoldInstruction(Instruction *I) {
-  if (PHINode *PN = dyn_cast<PHINode>(I)) {
-    if (PN->getNumIncomingValues() == 0)
-      return Constant::getNullValue(PN->getType());
-    
-    Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
-    if (Result == 0) return 0;
+#include "llvm/Function.h"
+#include "llvm/GlobalAlias.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
+#include <limits>
+using namespace llvm;
 
-    // Handle PHI nodes specially here...
-    for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
-      if (PN->getIncomingValue(i) != Result)
-        return 0;   // Not all the same incoming constants...
+//===----------------------------------------------------------------------===//
+//                ConstantFold*Instruction Implementations
+//===----------------------------------------------------------------------===//
 
-    // If we reach here, all incoming values are the same constant.
-    return Result;
+/// BitCastConstantVector - Convert the specified ConstantVector node to the
+/// specified vector type.  At this point, we know that the elements of the
+/// input vector constant are all simple integer or FP values.
+static Constant *BitCastConstantVector(ConstantVector *CV,
+                                       const VectorType *DstTy) {
+  // If this cast changes element count then we can't handle it here:
+  // doing so requires endianness information.  This should be handled by
+  // Analysis/ConstantFolding.cpp
+  unsigned NumElts = DstTy->getNumElements();
+  if (NumElts != CV->getNumOperands())
+    return 0;
+  
+  // Check to verify that all elements of the input are simple.
+  for (unsigned i = 0; i != NumElts; ++i) {
+    if (!isa<ConstantInt>(CV->getOperand(i)) &&
+        !isa<ConstantFP>(CV->getOperand(i)))
+      return 0;
   }
 
-  Constant *Op0 = 0;
-  Constant *Op1 = 0;
+  // Bitcast each element now.
+  std::vector<Constant*> Result;
+  const Type *DstEltTy = DstTy->getElementType();
+  for (unsigned i = 0; i != NumElts; ++i)
+    Result.push_back(ConstantExpr::getBitCast(CV->getOperand(i), DstEltTy));
+  return ConstantVector::get(Result);
+}
 
-  if (I->getNumOperands() != 0) {    // Get first operand if it's a constant...
-    Op0 = dyn_cast<Constant>(I->getOperand(0));
-    if (Op0 == 0) return 0;          // Not a constant?, can't fold
+/// This function determines which opcode to use to fold two constant cast 
+/// expressions together. It uses CastInst::isEliminableCastPair to determine
+/// the opcode. Consequently its just a wrapper around that function.
+/// @brief Determine if it is valid to fold a cast of a cast
+static unsigned
+foldConstantCastPair(
+  unsigned opc,          ///< opcode of the second cast constant expression
+  const ConstantExpr*Op, ///< the first cast constant expression
+  const Type *DstTy      ///< desintation type of the first cast
+) {
+  assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!");
+  assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type");
+  assert(CastInst::isCast(opc) && "Invalid cast opcode");
+  
+  // The the types and opcodes for the two Cast constant expressions
+  const Type *SrcTy = Op->getOperand(0)->getType();
+  const Type *MidTy = Op->getType();
+  Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode());
+  Instruction::CastOps secondOp = Instruction::CastOps(opc);
+
+  // Let CastInst::isEliminableCastPair do the heavy lifting.
+  return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy,
+                                        Type::Int64Ty);
+}
 
-    if (I->getNumOperands() != 1) {  // Get second operand if it's a constant...
-      Op1 = dyn_cast<Constant>(I->getOperand(1));
-      if (Op1 == 0) return 0;        // Not a constant?, can't fold
+static Constant *FoldBitCast(Constant *V, const Type *DestTy) {
+  const Type *SrcTy = V->getType();
+  if (SrcTy == DestTy)
+    return V; // no-op cast
+  
+  // Check to see if we are casting a pointer to an aggregate to a pointer to
+  // the first element.  If so, return the appropriate GEP instruction.
+  if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
+    if (const PointerType *DPTy = dyn_cast<PointerType>(DestTy))
+      if (PTy->getAddressSpace() == DPTy->getAddressSpace()) {
+        SmallVector<Value*, 8> IdxList;
+        IdxList.push_back(Constant::getNullValue(Type::Int32Ty));
+        const Type *ElTy = PTy->getElementType();
+        while (ElTy != DPTy->getElementType()) {
+          if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
+            if (STy->getNumElements() == 0) break;
+            ElTy = STy->getElementType(0);
+            IdxList.push_back(Constant::getNullValue(Type::Int32Ty));
+          } else if (const SequentialType *STy = 
+                     dyn_cast<SequentialType>(ElTy)) {
+            if (isa<PointerType>(ElTy)) break;  // Can't index into pointers!
+            ElTy = STy->getElementType();
+            IdxList.push_back(IdxList[0]);
+          } else {
+            break;
+          }
+        }
+        
+        if (ElTy == DPTy->getElementType())
+          return ConstantExpr::getGetElementPtr(V, &IdxList[0], IdxList.size());
+      }
+  
+  // Handle casts from one vector constant to another.  We know that the src 
+  // and dest type have the same size (otherwise its an illegal cast).
+  if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
+    if (const VectorType *SrcTy = dyn_cast<VectorType>(V->getType())) {
+      assert(DestPTy->getBitWidth() == SrcTy->getBitWidth() &&
+             "Not cast between same sized vectors!");
+      SrcTy = NULL;
+      // First, check for null.  Undef is already handled.
+      if (isa<ConstantAggregateZero>(V))
+        return Constant::getNullValue(DestTy);
+      
+      if (ConstantVector *CV = dyn_cast<ConstantVector>(V))
+        return BitCastConstantVector(CV, DestPTy);
     }
-  }
 
-  if (isa<BinaryOperator>(I))
-    return ConstantExpr::get(I->getOpcode(), Op0, Op1);    
-
-  switch (I->getOpcode()) {
-  case Instruction::Cast:
-    return ConstantExpr::getCast(Op0, I->getType());
-  case Instruction::Shl:
-  case Instruction::Shr:
-    return ConstantExpr::getShift(I->getOpcode(), Op0, Op1);
-  case Instruction::GetElementPtr: {
-    std::vector<Constant*> IdxList;
-    IdxList.reserve(I->getNumOperands()-1);
-    if (Op1) IdxList.push_back(Op1);
-    for (unsigned i = 2, e = I->getNumOperands(); i != e; ++i)
-      if (Constant *C = dyn_cast<Constant>(I->getOperand(i)))
-        IdxList.push_back(C);
-      else
-        return 0;  // Non-constant operand
-    return ConstantExpr::getGetElementPtr(Op0, IdxList);
+    // Canonicalize scalar-to-vector bitcasts into vector-to-vector bitcasts
+    // This allows for other simplifications (although some of them
+    // can only be handled by Analysis/ConstantFolding.cpp).
+    if (isa<ConstantInt>(V) || isa<ConstantFP>(V))
+      return ConstantExpr::getBitCast(ConstantVector::get(&V, 1), DestPTy);
   }
-  default:
+  
+  // Finally, implement bitcast folding now.   The code below doesn't handle
+  // bitcast right.
+  if (isa<ConstantPointerNull>(V))  // ptr->ptr cast.
+    return ConstantPointerNull::get(cast<PointerType>(DestTy));
+  
+  // Handle integral constant input.
+  if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+    if (DestTy->isInteger())
+      // Integral -> Integral. This is a no-op because the bit widths must
+      // be the same. Consequently, we just fold to V.
+      return V;
+
+    if (DestTy->isFloatingPoint())
+      return ConstantFP::get(APFloat(CI->getValue(),
+                                     DestTy != Type::PPC_FP128Ty));
+
+    // Otherwise, can't fold this (vector?)
     return 0;
   }
-}
 
-static unsigned getSize(const Type *Ty) {
-  unsigned S = Ty->getPrimitiveSize();
-  return S ? S : 8;  // Treat pointers at 8 bytes
+  // Handle ConstantFP input.
+  if (const ConstantFP *FP = dyn_cast<ConstantFP>(V))
+    // FP -> Integral.
+    return ConstantInt::get(FP->getValueAPF().bitcastToAPInt());
+
+  return 0;
 }
 
-Constant *ConstantFoldCastInstruction(const Constant *V, const Type *DestTy) {
-  if (V->getType() == DestTy) return (Constant*)V;
-
-  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
-    if (CE->getOpcode() == Instruction::Cast) {
-      Constant *Op = const_cast<Constant*>(CE->getOperand(0));
-      // Try to not produce a cast of a cast, which is almost always redundant.
-      if (!Op->getType()->isFloatingPoint() &&
-          !CE->getType()->isFloatingPoint() &&
-          !DestTy->getType()->isFloatingPoint()) {
-        unsigned S1 = getSize(Op->getType()), S2 = getSize(CE->getType());
-        unsigned S3 = getSize(DestTy);
-        if (Op->getType() == DestTy && S3 >= S2)
-          return Op;
-        if (S1 >= S2 && S2 >= S3)
-          return ConstantExpr::getCast(Op, DestTy);
-        if (S1 <= S2 && S2 >= S3 && S1 <= S3)
-          return ConstantExpr::getCast(Op, DestTy);
-      }
+
+Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
+                                            const Type *DestTy) {
+  if (isa<UndefValue>(V)) {
+    // zext(undef) = 0, because the top bits will be zero.
+    // sext(undef) = 0, because the top bits will all be the same.
+    // [us]itofp(undef) = 0, because the result value is bounded.
+    if (opc == Instruction::ZExt || opc == Instruction::SExt ||
+        opc == Instruction::UIToFP || opc == Instruction::SIToFP)
+      return Constant::getNullValue(DestTy);
+    return UndefValue::get(DestTy);
+  }
+  // No compile-time operations on this type yet.
+  if (V->getType() == Type::PPC_FP128Ty || DestTy == Type::PPC_FP128Ty)
+    return 0;
+
+  // If the cast operand is a constant expression, there's a few things we can
+  // do to try to simplify it.
+  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+    if (CE->isCast()) {
+      // Try hard to fold cast of cast because they are often eliminable.
+      if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy))
+        return ConstantExpr::getCast(newOpc, CE->getOperand(0), DestTy);
+    } else if (CE->getOpcode() == Instruction::GetElementPtr) {
+      // If all of the indexes in the GEP are null values, there is no pointer
+      // adjustment going on.  We might as well cast the source pointer.
+      bool isAllNull = true;
+      for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
+        if (!CE->getOperand(i)->isNullValue()) {
+          isAllNull = false;
+          break;
+        }
+      if (isAllNull)
+        // This is casting one pointer type to another, always BitCast
+        return ConstantExpr::getPointerCast(CE->getOperand(0), DestTy);
+    }
+  }
+
+  // We actually have to do a cast now. Perform the cast according to the
+  // opcode specified.
+  switch (opc) {
+  case Instruction::FPTrunc:
+  case Instruction::FPExt:
+    if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
+      bool ignored;
+      APFloat Val = FPC->getValueAPF();
+      Val.convert(DestTy == Type::FloatTy ? APFloat::IEEEsingle :
+                  DestTy == Type::DoubleTy ? APFloat::IEEEdouble :
+                  DestTy == Type::X86_FP80Ty ? APFloat::x87DoubleExtended :
+                  DestTy == Type::FP128Ty ? APFloat::IEEEquad :
+                  APFloat::Bogus,
+                  APFloat::rmNearestTiesToEven, &ignored);
+      return ConstantFP::get(Val);
+    }
+    return 0; // Can't fold.
+  case Instruction::FPToUI: 
+  case Instruction::FPToSI:
+    if (const ConstantFP *FPC = dyn_cast<ConstantFP>(V)) {
+      const APFloat &V = FPC->getValueAPF();
+      bool ignored;
+      uint64_t x[2]; 
+      uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth();
+      (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI,
+                                APFloat::rmTowardZero, &ignored);
+      APInt Val(DestBitWidth, 2, x);
+      return ConstantInt::get(Val);
+    }
+    if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
+      std::vector<Constant*> res;
+      const VectorType *DestVecTy = cast<VectorType>(DestTy);
+      const Type *DstEltTy = DestVecTy->getElementType();
+      for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
+        res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy));
+      return ConstantVector::get(DestVecTy, res);
+    }
+    return 0; // Can't fold.
+  case Instruction::IntToPtr:   //always treated as unsigned
+    if (V->isNullValue())       // Is it an integral null value?
+      return ConstantPointerNull::get(cast<PointerType>(DestTy));
+    return 0;                   // Other pointer types cannot be casted
+  case Instruction::PtrToInt:   // always treated as unsigned
+    if (V->isNullValue())       // is it a null pointer value?
+      return ConstantInt::get(DestTy, 0);
+    return 0;                   // Other pointer types cannot be casted
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      APInt api = CI->getValue();
+      const uint64_t zero[] = {0, 0};
+      APFloat apf = APFloat(APInt(DestTy->getPrimitiveSizeInBits(),
+                                  2, zero));
+      (void)apf.convertFromAPInt(api, 
+                                 opc==Instruction::SIToFP,
+                                 APFloat::rmNearestTiesToEven);
+      return ConstantFP::get(apf);
+    }
+    if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
+      std::vector<Constant*> res;
+      const VectorType *DestVecTy = cast<VectorType>(DestTy);
+      const Type *DstEltTy = DestVecTy->getElementType();
+      for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
+        res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy));
+      return ConstantVector::get(DestVecTy, res);
+    }
+    return 0;
+  case Instruction::ZExt:
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
+      APInt Result(CI->getValue());
+      Result.zext(BitWidth);
+      return ConstantInt::get(Result);
+    }
+    return 0;
+  case Instruction::SExt:
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
+      APInt Result(CI->getValue());
+      Result.sext(BitWidth);
+      return ConstantInt::get(Result);
+    }
+    return 0;
+  case Instruction::Trunc:
+    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+      uint32_t BitWidth = cast<IntegerType>(DestTy)->getBitWidth();
+      APInt Result(CI->getValue());
+      Result.trunc(BitWidth);
+      return ConstantInt::get(Result);
     }
+    return 0;
+  case Instruction::BitCast:
+    return FoldBitCast(const_cast<Constant*>(V), DestTy);
+  default:
+    assert(!"Invalid CE CastInst opcode");
+    break;
+  }
 
-  return ConstRules::get(*V, *V)->castTo(V, DestTy);
+  assert(0 && "Failed to cast constant expression");
+  return 0;
 }
 
-Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1,
-                                        const Constant *V2) {
-  switch (Opcode) {
-  case Instruction::Add:     return *V1 + *V2;
-  case Instruction::Sub:     return *V1 - *V2;
-  case Instruction::Mul:     return *V1 * *V2;
-  case Instruction::Div:     return *V1 / *V2;
-  case Instruction::Rem:     return *V1 % *V2;
-  case Instruction::And:     return *V1 & *V2;
-  case Instruction::Or:      return *V1 | *V2;
-  case Instruction::Xor:     return *V1 ^ *V2;
-
-  case Instruction::SetEQ:   return *V1 == *V2;
-  case Instruction::SetNE:   return *V1 != *V2;
-  case Instruction::SetLE:   return *V1 <= *V2;
-  case Instruction::SetGE:   return *V1 >= *V2;
-  case Instruction::SetLT:   return *V1 <  *V2;
-  case Instruction::SetGT:   return *V1 >  *V2;
-  }
+Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond,
+                                              const Constant *V1,
+                                              const Constant *V2) {
+  if (const ConstantInt *CB = dyn_cast<ConstantInt>(Cond))
+    return const_cast<Constant*>(CB->getZExtValue() ? V1 : V2);
+
+  if (isa<UndefValue>(V1)) return const_cast<Constant*>(V2);
+  if (isa<UndefValue>(V2)) return const_cast<Constant*>(V1);
+  if (isa<UndefValue>(Cond)) return const_cast<Constant*>(V1);
+  if (V1 == V2) return const_cast<Constant*>(V1);
   return 0;
 }
 
-Constant *ConstantFoldShiftInstruction(unsigned Opcode, const Constant *V1, 
-                                       const Constant *V2) {
-  switch (Opcode) {
-  case Instruction::Shl:     return *V1 << *V2;
-  case Instruction::Shr:     return *V1 >> *V2;
-  default:                   return 0;
+Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val,
+                                                      const Constant *Idx) {
+  if (isa<UndefValue>(Val))  // ee(undef, x) -> undef
+    return UndefValue::get(cast<VectorType>(Val->getType())->getElementType());
+  if (Val->isNullValue())  // ee(zero, x) -> zero
+    return Constant::getNullValue(
+                          cast<VectorType>(Val->getType())->getElementType());
+  
+  if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) {
+    if (const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) {
+      return CVal->getOperand(CIdx->getZExtValue());
+    } else if (isa<UndefValue>(Idx)) {
+      // ee({w,x,y,z}, undef) -> w (an arbitrary value).
+      return CVal->getOperand(0);
+    }
   }
+  return 0;
 }
 
-Constant *ConstantFoldGetElementPtr(const Constant *C,
-                                    const std::vector<Constant*> &IdxList) {
-  if (IdxList.size() == 0 ||
-      (IdxList.size() == 1 && IdxList[0]->isNullValue()))
-    return const_cast<Constant*>(C);
-
-  // If C is null and all idx's are null, return null of the right type.
+Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val,
+                                                     const Constant *Elt,
+                                                     const Constant *Idx) {
+  const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx);
+  if (!CIdx) return 0;
+  APInt idxVal = CIdx->getValue();
+  if (isa<UndefValue>(Val)) { 
+    // Insertion of scalar constant into vector undef
+    // Optimize away insertion of undef
+    if (isa<UndefValue>(Elt))
+      return const_cast<Constant*>(Val);
+    // Otherwise break the aggregate undef into multiple undefs and do
+    // the insertion
+    unsigned numOps = 
+      cast<VectorType>(Val->getType())->getNumElements();
+    std::vector<Constant*> Ops; 
+    Ops.reserve(numOps);
+    for (unsigned i = 0; i < numOps; ++i) {
+      const Constant *Op =
+        (idxVal == i) ? Elt : UndefValue::get(Elt->getType());
+      Ops.push_back(const_cast<Constant*>(Op));
+    }
+    return ConstantVector::get(Ops);
+  }
+  if (isa<ConstantAggregateZero>(Val)) {
+    // Insertion of scalar constant into vector aggregate zero
+    // Optimize away insertion of zero
+    if (Elt->isNullValue())
+      return const_cast<Constant*>(Val);
+    // Otherwise break the aggregate zero into multiple zeros and do
+    // the insertion
+    unsigned numOps = 
+      cast<VectorType>(Val->getType())->getNumElements();
+    std::vector<Constant*> Ops; 
+    Ops.reserve(numOps);
+    for (unsigned i = 0; i < numOps; ++i) {
+      const Constant *Op =
+        (idxVal == i) ? Elt : Constant::getNullValue(Elt->getType());
+      Ops.push_back(const_cast<Constant*>(Op));
+    }
+    return ConstantVector::get(Ops);
+  }
+  if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) {
+    // Insertion of scalar constant into vector constant
+    std::vector<Constant*> Ops; 
+    Ops.reserve(CVal->getNumOperands());
+    for (unsigned i = 0; i < CVal->getNumOperands(); ++i) {
+      const Constant *Op =
+        (idxVal == i) ? Elt : cast<Constant>(CVal->getOperand(i));
+      Ops.push_back(const_cast<Constant*>(Op));
+    }
+    return ConstantVector::get(Ops);
+  }
 
-  // FIXME: Implement folding of GEP constant exprs the same as instcombine does
+  return 0;
+}
 
-  // Implement folding of:
-  //    int* getelementptr ([2 x int]* cast ([3 x int]* %X to [2 x int]*),
-  //                        long 0, long 0)
-  // To: int* getelementptr ([3 x int]* %X, long 0, long 0)
-  //
-  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
-    if (CE->getOpcode() == Instruction::Cast && IdxList.size() > 1 &&
-        IdxList[0]->isNullValue())
-      if (const PointerType *SPT = 
-          dyn_cast<PointerType>(CE->getOperand(0)->getType()))
-        if (const ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType()))
-          if (const ArrayType *CAT =
-              dyn_cast<ArrayType>(cast<PointerType>(C->getType())->getElementType()))
-            if (CAT->getElementType() == SAT->getElementType())
-              return ConstantExpr::getGetElementPtr(
-                      (Constant*)CE->getOperand(0), IdxList);
+/// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef
+/// return the specified element value.  Otherwise return null.
+static Constant *GetVectorElement(const Constant *C, unsigned EltNo) {
+  if (const ConstantVector *CV = dyn_cast<ConstantVector>(C))
+    return CV->getOperand(EltNo);
+  
+  const Type *EltTy = cast<VectorType>(C->getType())->getElementType();
+  if (isa<ConstantAggregateZero>(C))
+    return Constant::getNullValue(EltTy);
+  if (isa<UndefValue>(C))
+    return UndefValue::get(EltTy);
   return 0;
 }
 
+Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1,
+                                                     const Constant *V2,
+                                                     const Constant *Mask) {
+  // Undefined shuffle mask -> undefined value.
+  if (isa<UndefValue>(Mask)) return UndefValue::get(V1->getType());
+
+  unsigned MaskNumElts = cast<VectorType>(Mask->getType())->getNumElements();
+  unsigned SrcNumElts = cast<VectorType>(V1->getType())->getNumElements();
+  const Type *EltTy = cast<VectorType>(V1->getType())->getElementType();
+
+  // Loop over the shuffle mask, evaluating each element.
+  SmallVector<Constant*, 32> Result;
+  for (unsigned i = 0; i != MaskNumElts; ++i) {
+    Constant *InElt = GetVectorElement(Mask, i);
+    if (InElt == 0) return 0;
+
+    if (isa<UndefValue>(InElt))
+      InElt = UndefValue::get(EltTy);
+    else if (ConstantInt *CI = dyn_cast<ConstantInt>(InElt)) {
+      unsigned Elt = CI->getZExtValue();
+      if (Elt >= SrcNumElts*2)
+        InElt = UndefValue::get(EltTy);
+      else if (Elt >= SrcNumElts)
+        InElt = GetVectorElement(V2, Elt - SrcNumElts);
+      else
+        InElt = GetVectorElement(V1, Elt);
+      if (InElt == 0) return 0;
+    } else {
+      // Unknown value.
+      return 0;
+    }
+    Result.push_back(InElt);
+  }
 
-//===----------------------------------------------------------------------===//
-//                             TemplateRules Class
-//===----------------------------------------------------------------------===//
-//
-// TemplateRules - Implement a subclass of ConstRules that provides all 
-// operations as noops.  All other rules classes inherit from this class so 
-// that if functionality is needed in the future, it can simply be added here 
-// and to ConstRules without changing anything else...
-// 
-// This class also provides subclasses with typesafe implementations of methods
-// so that don't have to do type casting.
-//
-template<class ArgType, class SubClassName>
-class TemplateRules : public ConstRules {
+  return ConstantVector::get(&Result[0], Result.size());
+}
 
-  //===--------------------------------------------------------------------===//
-  // Redirecting functions that cast to the appropriate types
-  //===--------------------------------------------------------------------===//
+Constant *llvm::ConstantFoldExtractValueInstruction(const Constant *Agg,
+                                                    const unsigned *Idxs,
+                                                    unsigned NumIdx) {
+  // Base case: no indices, so return the entire value.
+  if (NumIdx == 0)
+    return const_cast<Constant *>(Agg);
+
+  if (isa<UndefValue>(Agg))  // ev(undef, x) -> undef
+    return UndefValue::get(ExtractValueInst::getIndexedType(Agg->getType(),
+                                                            Idxs,
+                                                            Idxs + NumIdx));
+
+  if (isa<ConstantAggregateZero>(Agg))  // ev(0, x) -> 0
+    return
+      Constant::getNullValue(ExtractValueInst::getIndexedType(Agg->getType(),
+                                                              Idxs,
+                                                              Idxs + NumIdx));
+
+  // Otherwise recurse.
+  return ConstantFoldExtractValueInstruction(Agg->getOperand(*Idxs),
+                                             Idxs+1, NumIdx-1);
+}
 
-  virtual Constant *add(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);  
-  }
-  virtual Constant *sub(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);  
-  }
-  virtual Constant *mul(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);  
-  }
-  virtual Constant *div(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2);  
-  }
-  virtual Constant *rem(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Rem((const ArgType *)V1, (const ArgType *)V2);  
-  }
-  virtual Constant *op_and(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::And((const ArgType *)V1, (const ArgType *)V2);  
-  }
-  virtual Constant *op_or(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Or((const ArgType *)V1, (const ArgType *)V2);  
-  }
-  virtual Constant *op_xor(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Xor((const ArgType *)V1, (const ArgType *)V2);  
+Constant *llvm::ConstantFoldInsertValueInstruction(const Constant *Agg,
+                                                   const Constant *Val,
+                                                   const unsigned *Idxs,
+                                                   unsigned NumIdx) {
+  // Base case: no indices, so replace the entire value.
+  if (NumIdx == 0)
+    return const_cast<Constant *>(Val);
+
+  if (isa<UndefValue>(Agg)) {
+    // Insertion of constant into aggregate undef
+    // Optimize away insertion of undef
+    if (isa<UndefValue>(Val))
+      return const_cast<Constant*>(Agg);
+    // Otherwise break the aggregate undef into multiple undefs and do
+    // the insertion
+    const CompositeType *AggTy = cast<CompositeType>(Agg->getType());
+    unsigned numOps;
+    if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy))
+      numOps = AR->getNumElements();
+    else
+      numOps = cast<StructType>(AggTy)->getNumElements();
+    std::vector<Constant*> Ops(numOps); 
+    for (unsigned i = 0; i < numOps; ++i) {
+      const Type *MemberTy = AggTy->getTypeAtIndex(i);
+      const Constant *Op =
+        (*Idxs == i) ?
+        ConstantFoldInsertValueInstruction(UndefValue::get(MemberTy),
+                                           Val, Idxs+1, NumIdx-1) :
+        UndefValue::get(MemberTy);
+      Ops[i] = const_cast<Constant*>(Op);
+    }
+    if (isa<StructType>(AggTy))
+      return ConstantStruct::get(Ops);
+    else
+      return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
   }
-  virtual Constant *shl(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2);  
+  if (isa<ConstantAggregateZero>(Agg)) {
+    // Insertion of constant into aggregate zero
+    // Optimize away insertion of zero
+    if (Val->isNullValue())
+      return const_cast<Constant*>(Agg);
+    // Otherwise break the aggregate zero into multiple zeros and do
+    // the insertion
+    const CompositeType *AggTy = cast<CompositeType>(Agg->getType());
+    unsigned numOps;
+    if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy))
+      numOps = AR->getNumElements();
+    else
+      numOps = cast<StructType>(AggTy)->getNumElements();
+    std::vector<Constant*> Ops(numOps);
+    for (unsigned i = 0; i < numOps; ++i) {
+      const Type *MemberTy = AggTy->getTypeAtIndex(i);
+      const Constant *Op =
+        (*Idxs == i) ?
+        ConstantFoldInsertValueInstruction(Constant::getNullValue(MemberTy),
+                                           Val, Idxs+1, NumIdx-1) :
+        Constant::getNullValue(MemberTy);
+      Ops[i] = const_cast<Constant*>(Op);
+    }
+    if (isa<StructType>(AggTy))
+      return ConstantStruct::get(Ops);
+    else
+      return ConstantArray::get(cast<ArrayType>(AggTy), Ops);
   }
-  virtual Constant *shr(const Constant *V1, const Constant *V2) const { 
-    return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2);  
+  if (isa<ConstantStruct>(Agg) || isa<ConstantArray>(Agg)) {
+    // Insertion of constant into aggregate constant
+    std::vector<Constant*> Ops(Agg->getNumOperands());
+    for (unsigned i = 0; i < Agg->getNumOperands(); ++i) {
+      const Constant *Op =
+        (*Idxs == i) ?
+        ConstantFoldInsertValueInstruction(Agg->getOperand(i),
+                                           Val, Idxs+1, NumIdx-1) :
+        Agg->getOperand(i);
+      Ops[i] = const_cast<Constant*>(Op);
+    }
+    Constant *C;
+    if (isa<StructType>(Agg->getType()))
+      C = ConstantStruct::get(Ops);
+    else
+      C = ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops);
+    return C;
   }
 
-  virtual ConstantBool *lessthan(const Constant *V1, 
-                                 const Constant *V2) const { 
-    return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
-  }
+  return 0;
+}
 
-  // Casting operators.  ick
-  virtual ConstantBool *castToBool(const Constant *V) const {
-    return SubClassName::CastToBool((const ArgType*)V);
-  }
-  virtual ConstantSInt *castToSByte(const Constant *V) const {
-    return SubClassName::CastToSByte((const ArgType*)V);
-  }
-  virtual ConstantUInt *castToUByte(const Constant *V) const {
-    return SubClassName::CastToUByte((const ArgType*)V);
-  }
-  virtual ConstantSInt *castToShort(const Constant *V) const {
-    return SubClassName::CastToShort((const ArgType*)V);
-  }
-  virtual ConstantUInt *castToUShort(const Constant *V) const {
-    return SubClassName::CastToUShort((const ArgType*)V);
-  }
-  virtual ConstantSInt *castToInt(const Constant *V) const {
-    return SubClassName::CastToInt((const ArgType*)V);
-  }
-  virtual ConstantUInt *castToUInt(const Constant *V) const {
-    return SubClassName::CastToUInt((const ArgType*)V);
-  }
-  virtual ConstantSInt *castToLong(const Constant *V) const {
-    return SubClassName::CastToLong((const ArgType*)V);
-  }
-  virtual ConstantUInt *castToULong(const Constant *V) const {
-    return SubClassName::CastToULong((const ArgType*)V);
-  }
-  virtual ConstantFP   *castToFloat(const Constant *V) const {
-    return SubClassName::CastToFloat((const ArgType*)V);
-  }
-  virtual ConstantFP   *castToDouble(const Constant *V) const {
-    return SubClassName::CastToDouble((const ArgType*)V);
-  }
-  virtual Constant *castToPointer(const Constant *V, 
-                                  const PointerType *Ty) const {
-    return SubClassName::CastToPointer((const ArgType*)V, Ty);
+/// EvalVectorOp - Given two vector constants and a function pointer, apply the
+/// function pointer to each element pair, producing a new ConstantVector
+/// constant. Either or both of V1 and V2 may be NULL, meaning a
+/// ConstantAggregateZero operand.
+static Constant *EvalVectorOp(const ConstantVector *V1, 
+                              const ConstantVector *V2,
+                              const VectorType *VTy,
+                              Constant *(*FP)(Constant*, Constant*)) {
+  std::vector<Constant*> Res;
+  const Type *EltTy = VTy->getElementType();
+  for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
+    const Constant *C1 = V1 ? V1->getOperand(i) : Constant::getNullValue(EltTy);
+    const Constant *C2 = V2 ? V2->getOperand(i) : Constant::getNullValue(EltTy);
+    Res.push_back(FP(const_cast<Constant*>(C1),
+                     const_cast<Constant*>(C2)));
   }
+  return ConstantVector::get(Res);
+}
 
-  //===--------------------------------------------------------------------===//
-  // Default "noop" implementations
-  //===--------------------------------------------------------------------===//
-
-  static Constant *Add(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Sub(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Mul(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Div(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Rem(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *And(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Or (const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Xor(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Shl(const ArgType *V1, const ArgType *V2) { return 0; }
-  static Constant *Shr(const ArgType *V1, const ArgType *V2) { return 0; }
-  static ConstantBool *LessThan(const ArgType *V1, const ArgType *V2) {
+Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
+                                              const Constant *C1,
+                                              const Constant *C2) {
+  // No compile-time operations on this type yet.
+  if (C1->getType() == Type::PPC_FP128Ty)
     return 0;
-  }
-
-  // Casting operators.  ick
-  static ConstantBool *CastToBool  (const Constant *V) { return 0; }
-  static ConstantSInt *CastToSByte (const Constant *V) { return 0; }
-  static ConstantUInt *CastToUByte (const Constant *V) { return 0; }
-  static ConstantSInt *CastToShort (const Constant *V) { return 0; }
-  static ConstantUInt *CastToUShort(const Constant *V) { return 0; }
-  static ConstantSInt *CastToInt   (const Constant *V) { return 0; }
-  static ConstantUInt *CastToUInt  (const Constant *V) { return 0; }
-  static ConstantSInt *CastToLong  (const Constant *V) { return 0; }
-  static ConstantUInt *CastToULong (const Constant *V) { return 0; }
-  static ConstantFP   *CastToFloat (const Constant *V) { return 0; }
-  static ConstantFP   *CastToDouble(const Constant *V) { return 0; }
-  static Constant     *CastToPointer(const Constant *,
-                                     const PointerType *) {return 0;}
-};
-
-
-
-//===----------------------------------------------------------------------===//
-//                             EmptyRules Class
-//===----------------------------------------------------------------------===//
-//
-// EmptyRules provides a concrete base class of ConstRules that does nothing
-//
-struct EmptyRules : public TemplateRules<Constant, EmptyRules> {
-};
-
-
-
-//===----------------------------------------------------------------------===//
-//                              BoolRules Class
-//===----------------------------------------------------------------------===//
-//
-// BoolRules provides a concrete base class of ConstRules for the 'bool' type.
-//
-struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
 
-  static ConstantBool *LessThan(const ConstantBool *V1, const ConstantBool *V2){
-    return ConstantBool::get(V1->getValue() < V2->getValue());
+  // Handle UndefValue up front
+  if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) {
+    switch (Opcode) {
+    case Instruction::Xor:
+      if (isa<UndefValue>(C1) && isa<UndefValue>(C2))
+        // Handle undef ^ undef -> 0 special case. This is a common
+        // idiom (misuse).
+        return Constant::getNullValue(C1->getType());
+      // Fallthrough
+    case Instruction::Add:
+    case Instruction::Sub:
+      return UndefValue::get(C1->getType());
+    case Instruction::Mul:
+    case Instruction::And:
+      return Constant::getNullValue(C1->getType());
+    case Instruction::UDiv:
+    case Instruction::SDiv:
+    case Instruction::FDiv:
+    case Instruction::URem:
+    case Instruction::SRem:
+    case Instruction::FRem:
+      if (!isa<UndefValue>(C2))                    // undef / X -> 0
+        return Constant::getNullValue(C1->getType());
+      return const_cast<Constant*>(C2);            // X / undef -> undef
+    case Instruction::Or:                          // X | undef -> -1
+      if (const VectorType *PTy = dyn_cast<VectorType>(C1->getType()))
+        return ConstantVector::getAllOnesValue(PTy);
+      return ConstantInt::getAllOnesValue(C1->getType());
+    case Instruction::LShr:
+      if (isa<UndefValue>(C2) && isa<UndefValue>(C1))
+        return const_cast<Constant*>(C1);           // undef lshr undef -> undef
+      return Constant::getNullValue(C1->getType()); // X lshr undef -> 0
+                                                    // undef lshr X -> 0
+    case Instruction::AShr:
+      if (!isa<UndefValue>(C2))
+        return const_cast<Constant*>(C1);           // undef ashr X --> undef
+      else if (isa<UndefValue>(C1)) 
+        return const_cast<Constant*>(C1);           // undef ashr undef -> undef
+      else
+        return const_cast<Constant*>(C1);           // X ashr undef --> X
+    case Instruction::Shl:
+      // undef << X -> 0   or   X << undef -> 0
+      return Constant::getNullValue(C1->getType());
+    }
   }
 
-  static Constant *And(const ConstantBool *V1, const ConstantBool *V2) {
-    return ConstantBool::get(V1->getValue() & V2->getValue());
+  // Handle simplifications of the RHS when a constant int.
+  if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
+    switch (Opcode) {
+    case Instruction::Add:
+      if (CI2->equalsInt(0)) return const_cast<Constant*>(C1);  // X + 0 == X
+      break;
+    case Instruction::Sub:
+      if (CI2->equalsInt(0)) return const_cast<Constant*>(C1);  // X - 0 == X
+      break;
+    case Instruction::Mul:
+      if (CI2->equalsInt(0)) return const_cast<Constant*>(C2);  // X * 0 == 0
+      if (CI2->equalsInt(1))
+        return const_cast<Constant*>(C1);                       // X * 1 == X
+      break;
+    case Instruction::UDiv:
+    case Instruction::SDiv:
+      if (CI2->equalsInt(1))
+        return const_cast<Constant*>(C1);                     // X / 1 == X
+      if (CI2->equalsInt(0))
+        return UndefValue::get(CI2->getType());               // X / 0 == undef
+      break;
+    case Instruction::URem:
+    case Instruction::SRem:
+      if (CI2->equalsInt(1))
+        return Constant::getNullValue(CI2->getType());        // X % 1 == 0
+      if (CI2->equalsInt(0))
+        return UndefValue::get(CI2->getType());               // X % 0 == undef
+      break;
+    case Instruction::And:
+      if (CI2->isZero()) return const_cast<Constant*>(C2);    // X & 0 == 0
+      if (CI2->isAllOnesValue())
+        return const_cast<Constant*>(C1);                     // X & -1 == X
+      
+      if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
+        // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
+        if (CE1->getOpcode() == Instruction::ZExt) {
+          unsigned DstWidth = CI2->getType()->getBitWidth();
+          unsigned SrcWidth =
+            CE1->getOperand(0)->getType()->getPrimitiveSizeInBits();
+          APInt PossiblySetBits(APInt::getLowBitsSet(DstWidth, SrcWidth));
+          if ((PossiblySetBits & CI2->getValue()) == PossiblySetBits)
+            return const_cast<Constant*>(C1);
+        }
+        
+        // If and'ing the address of a global with a constant, fold it.
+        if (CE1->getOpcode() == Instruction::PtrToInt && 
+            isa<GlobalValue>(CE1->getOperand(0))) {
+          GlobalValue *GV = cast<GlobalValue>(CE1->getOperand(0));
+        
+          // Functions are at least 4-byte aligned.
+          unsigned GVAlign = GV->getAlignment();
+          if (isa<Function>(GV))
+            GVAlign = std::max(GVAlign, 4U);
+          
+          if (GVAlign > 1) {
+            unsigned DstWidth = CI2->getType()->getBitWidth();
+            unsigned SrcWidth = std::min(DstWidth, Log2_32(GVAlign));
+            APInt BitsNotSet(APInt::getLowBitsSet(DstWidth, SrcWidth));
+
+            // If checking bits we know are clear, return zero.
+            if ((CI2->getValue() & BitsNotSet) == CI2->getValue())
+              return Constant::getNullValue(CI2->getType());
+          }
+        }
+      }
+      break;
+    case Instruction::Or:
+      if (CI2->equalsInt(0)) return const_cast<Constant*>(C1);  // X | 0 == X
+      if (CI2->isAllOnesValue())
+        return const_cast<Constant*>(C2);  // X | -1 == -1
+      break;
+    case Instruction::Xor:
+      if (CI2->equalsInt(0)) return const_cast<Constant*>(C1);  // X ^ 0 == X
+      break;
+    case Instruction::AShr:
+      // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2
+      if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1))
+        if (CE1->getOpcode() == Instruction::ZExt)  // Top bits known zero.
+          return ConstantExpr::getLShr(const_cast<Constant*>(C1),
+                                       const_cast<Constant*>(C2));
+      break;
+    }
   }
-
-  static Constant *Or(const ConstantBool *V1, const ConstantBool *V2) {
-    return ConstantBool::get(V1->getValue() | V2->getValue());
+  
+  // At this point we know neither constant is an UndefValue.
+  if (const ConstantInt *CI1 = dyn_cast<ConstantInt>(C1)) {
+    if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
+      using namespace APIntOps;
+      const APInt &C1V = CI1->getValue();
+      const APInt &C2V = CI2->getValue();
+      switch (Opcode) {
+      default:
+        break;
+      case Instruction::Add:     
+        return ConstantInt::get(C1V + C2V);
+      case Instruction::Sub:     
+        return ConstantInt::get(C1V - C2V);
+      case Instruction::Mul:     
+        return ConstantInt::get(C1V * C2V);
+      case Instruction::UDiv:
+        assert(!CI2->isNullValue() && "Div by zero handled above");
+        return ConstantInt::get(C1V.udiv(C2V));
+      case Instruction::SDiv:
+        assert(!CI2->isNullValue() && "Div by zero handled above");
+        if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
+          return UndefValue::get(CI1->getType());   // MIN_INT / -1 -> undef
+        return ConstantInt::get(C1V.sdiv(C2V));
+      case Instruction::URem:
+        assert(!CI2->isNullValue() && "Div by zero handled above");
+        return ConstantInt::get(C1V.urem(C2V));
+      case Instruction::SRem:
+        assert(!CI2->isNullValue() && "Div by zero handled above");
+        if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
+          return UndefValue::get(CI1->getType());   // MIN_INT % -1 -> undef
+        return ConstantInt::get(C1V.srem(C2V));
+      case Instruction::And:
+        return ConstantInt::get(C1V & C2V);
+      case Instruction::Or:
+        return ConstantInt::get(C1V | C2V);
+      case Instruction::Xor:
+        return ConstantInt::get(C1V ^ C2V);
+      case Instruction::Shl: {
+        uint32_t shiftAmt = C2V.getZExtValue();
+        if (shiftAmt < C1V.getBitWidth())
+          return ConstantInt::get(C1V.shl(shiftAmt));
+        else
+          return UndefValue::get(C1->getType()); // too big shift is undef
+      }
+      case Instruction::LShr: {
+        uint32_t shiftAmt = C2V.getZExtValue();
+        if (shiftAmt < C1V.getBitWidth())
+          return ConstantInt::get(C1V.lshr(shiftAmt));
+        else
+          return UndefValue::get(C1->getType()); // too big shift is undef
+      }
+      case Instruction::AShr: {
+        uint32_t shiftAmt = C2V.getZExtValue();
+        if (shiftAmt < C1V.getBitWidth())
+          return ConstantInt::get(C1V.ashr(shiftAmt));
+        else
+          return UndefValue::get(C1->getType()); // too big shift is undef
+      }
+      }
+    }
+  } else if (const ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) {
+    if (const ConstantFP *CFP2 = dyn_cast<ConstantFP>(C2)) {
+      APFloat C1V = CFP1->getValueAPF();
+      APFloat C2V = CFP2->getValueAPF();
+      APFloat C3V = C1V;  // copy for modification
+      switch (Opcode) {
+      default:                   
+        break;
+      case Instruction::Add:
+        (void)C3V.add(C2V, APFloat::rmNearestTiesToEven);
+        return ConstantFP::get(C3V);
+      case Instruction::Sub:     
+        (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven);
+        return ConstantFP::get(C3V);
+      case Instruction::Mul:
+        (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven);
+        return ConstantFP::get(C3V);
+      case Instruction::FDiv:
+        (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven);
+        return ConstantFP::get(C3V);
+      case Instruction::FRem:
+        (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven);
+        return ConstantFP::get(C3V);
+      }
+    }
+  } else if (const VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
+    const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1);
+    const ConstantVector *CP2 = dyn_cast<ConstantVector>(C2);
+    if ((CP1 != NULL || isa<ConstantAggregateZero>(C1)) &&
+        (CP2 != NULL || isa<ConstantAggregateZero>(C2))) {
+      switch (Opcode) {
+      default:
+        break;
+      case Instruction::Add: 
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAdd);
+      case Instruction::Sub: 
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSub);
+      case Instruction::Mul: 
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getMul);
+      case Instruction::UDiv:
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getUDiv);
+      case Instruction::SDiv:
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSDiv);
+      case Instruction::FDiv:
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFDiv);
+      case Instruction::URem:
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getURem);
+      case Instruction::SRem:
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSRem);
+      case Instruction::FRem:
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFRem);
+      case Instruction::And: 
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAnd);
+      case Instruction::Or:  
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getOr);
+      case Instruction::Xor: 
+        return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getXor);
+      }
+    }
   }
 
-  static Constant *Xor(const ConstantBool *V1, const ConstantBool *V2) {
-    return ConstantBool::get(V1->getValue() ^ V2->getValue());
+  if (isa<ConstantExpr>(C1)) {
+    // There are many possible foldings we could do here.  We should probably
+    // at least fold add of a pointer with an integer into the appropriate
+    // getelementptr.  This will improve alias analysis a bit.
+  } else if (isa<ConstantExpr>(C2)) {
+    // If C2 is a constant expr and C1 isn't, flop them around and fold the
+    // other way if possible.
+    switch (Opcode) {
+    case Instruction::Add:
+    case Instruction::Mul:
+    case Instruction::And:
+    case Instruction::Or:
+    case Instruction::Xor:
+      // No change of opcode required.
+      return ConstantFoldBinaryInstruction(Opcode, C2, C1);
+      
+    case Instruction::Shl:
+    case Instruction::LShr:
+    case Instruction::AShr:
+    case Instruction::Sub:
+    case Instruction::SDiv:
+    case Instruction::UDiv:
+    case Instruction::FDiv:
+    case Instruction::URem:
+    case Instruction::SRem:
+    case Instruction::FRem:
+    default:  // These instructions cannot be flopped around.
+      break;
+    }
   }
-};
+  
+  // We don't know how to fold this.
+  return 0;
+}
 
+/// isZeroSizedType - This type is zero sized if its an array or structure of
+/// zero sized types.  The only leaf zero sized type is an empty structure.
+static bool isMaybeZeroSizedType(const Type *Ty) {
+  if (isa<OpaqueType>(Ty)) return true;  // Can't say.
+  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
 
-//===----------------------------------------------------------------------===//
-//                            PointerRules Class
-//===----------------------------------------------------------------------===//
-//
-// PointerRules provides a concrete base class of ConstRules for pointer types
-//
-struct PointerRules : public TemplateRules<ConstantPointer, PointerRules> {
-  static ConstantBool *CastToBool  (const Constant *V) {
-    if (V->isNullValue()) return ConstantBool::False;
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantSInt *CastToSByte (const Constant *V) {
-    if (V->isNullValue()) return ConstantSInt::get(Type::SByteTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantUInt *CastToUByte (const Constant *V) {
-    if (V->isNullValue()) return ConstantUInt::get(Type::UByteTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantSInt *CastToShort (const Constant *V) {
-    if (V->isNullValue()) return ConstantSInt::get(Type::ShortTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantUInt *CastToUShort(const Constant *V) {
-    if (V->isNullValue()) return ConstantUInt::get(Type::UShortTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantSInt *CastToInt   (const Constant *V) {
-    if (V->isNullValue()) return ConstantSInt::get(Type::IntTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantUInt *CastToUInt  (const Constant *V) {
-    if (V->isNullValue()) return ConstantUInt::get(Type::UIntTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantSInt *CastToLong  (const Constant *V) {
-    if (V->isNullValue()) return ConstantSInt::get(Type::LongTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantUInt *CastToULong (const Constant *V) {
-    if (V->isNullValue()) return ConstantUInt::get(Type::ULongTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantFP   *CastToFloat (const Constant *V) {
-    if (V->isNullValue()) return ConstantFP::get(Type::FloatTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
-  static ConstantFP   *CastToDouble(const Constant *V) {
-    if (V->isNullValue()) return ConstantFP::get(Type::DoubleTy, 0);
-    return 0;  // Can't const prop other types of pointers
-  }
+    // If all of elements have zero size, this does too.
+    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
+      if (!isMaybeZeroSizedType(STy->getElementType(i))) return false;
+    return true;
 
-  static Constant *CastToPointer(const ConstantPointer *V,
-                                 const PointerType *PTy) {
-    if (V->getType() == PTy)
-      return const_cast<ConstantPointer*>(V);  // Allow cast %PTy %ptr to %PTy
-    if (V->isNullValue())
-      return ConstantPointerNull::get(PTy);
-    return 0;  // Can't const prop other types of pointers
+  } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+    return isMaybeZeroSizedType(ATy->getElementType());
   }
-};
+  return false;
+}
 
+/// IdxCompare - Compare the two constants as though they were getelementptr
+/// indices.  This allows coersion of the types to be the same thing.
+///
+/// If the two constants are the "same" (after coersion), return 0.  If the
+/// first is less than the second, return -1, if the second is less than the
+/// first, return 1.  If the constants are not integral, return -2.
+///
+static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) {
+  if (C1 == C2) return 0;
+
+  // Ok, we found a different index.  If they are not ConstantInt, we can't do
+  // anything with them.
+  if (!isa<ConstantInt>(C1) || !isa<ConstantInt>(C2))
+    return -2; // don't know!
+
+  // Ok, we have two differing integer indices.  Sign extend them to be the same
+  // type.  Long is always big enough, so we use it.
+  if (C1->getType() != Type::Int64Ty)
+    C1 = ConstantExpr::getSExt(C1, Type::Int64Ty);
+
+  if (C2->getType() != Type::Int64Ty)
+    C2 = ConstantExpr::getSExt(C2, Type::Int64Ty);
+
+  if (C1 == C2) return 0;  // They are equal
+
+  // If the type being indexed over is really just a zero sized type, there is
+  // no pointer difference being made here.
+  if (isMaybeZeroSizedType(ElTy))
+    return -2; // dunno.
+
+  // If they are really different, now that they are the same type, then we
+  // found a difference!
+  if (cast<ConstantInt>(C1)->getSExtValue() < 
+      cast<ConstantInt>(C2)->getSExtValue())
+    return -1;
+  else
+    return 1;
+}
 
-//===----------------------------------------------------------------------===//
-//                             DirectRules Class
-//===----------------------------------------------------------------------===//
-//
-// DirectRules provides a concrete base classes of ConstRules for a variety of
-// different types.  This allows the C++ compiler to automatically generate our
-// constant handling operations in a typesafe and accurate manner.
-//
-template<class ConstantClass, class BuiltinType, Type **Ty, class SuperClass>
-struct DirectRules : public TemplateRules<ConstantClass, SuperClass> {
-  static Constant *Add(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() + (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
+/// evaluateFCmpRelation - This function determines if there is anything we can
+/// decide about the two constants provided.  This doesn't need to handle simple
+/// things like ConstantFP comparisons, but should instead handle ConstantExprs.
+/// If we can determine that the two constants have a particular relation to 
+/// each other, we should return the corresponding FCmpInst predicate, 
+/// otherwise return FCmpInst::BAD_FCMP_PREDICATE. This is used below in
+/// ConstantFoldCompareInstruction.
+///
+/// To simplify this code we canonicalize the relation so that the first
+/// operand is always the most "complex" of the two.  We consider ConstantFP
+/// to be the simplest, and ConstantExprs to be the most complex.
+static FCmpInst::Predicate evaluateFCmpRelation(const Constant *V1, 
+                                                const Constant *V2) {
+  assert(V1->getType() == V2->getType() &&
+         "Cannot compare values of different types!");
+
+  // No compile-time operations on this type yet.
+  if (V1->getType() == Type::PPC_FP128Ty)
+    return FCmpInst::BAD_FCMP_PREDICATE;
+
+  // Handle degenerate case quickly
+  if (V1 == V2) return FCmpInst::FCMP_OEQ;
+
+  if (!isa<ConstantExpr>(V1)) {
+    if (!isa<ConstantExpr>(V2)) {
+      // We distilled thisUse the standard constant folder for a few cases
+      ConstantInt *R = 0;
+      Constant *C1 = const_cast<Constant*>(V1);
+      Constant *C2 = const_cast<Constant*>(V2);
+      R = dyn_cast<ConstantInt>(
+                             ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, C1, C2));
+      if (R && !R->isZero()) 
+        return FCmpInst::FCMP_OEQ;
+      R = dyn_cast<ConstantInt>(
+                             ConstantExpr::getFCmp(FCmpInst::FCMP_OLT, C1, C2));
+      if (R && !R->isZero()) 
+        return FCmpInst::FCMP_OLT;
+      R = dyn_cast<ConstantInt>(
+                             ConstantExpr::getFCmp(FCmpInst::FCMP_OGT, C1, C2));
+      if (R && !R->isZero()) 
+        return FCmpInst::FCMP_OGT;
+
+      // Nothing more we can do
+      return FCmpInst::BAD_FCMP_PREDICATE;
+    }
+    
+    // If the first operand is simple and second is ConstantExpr, swap operands.
+    FCmpInst::Predicate SwappedRelation = evaluateFCmpRelation(V2, V1);
+    if (SwappedRelation != FCmpInst::BAD_FCMP_PREDICATE)
+      return FCmpInst::getSwappedPredicate(SwappedRelation);
+  } else {
+    // Ok, the LHS is known to be a constantexpr.  The RHS can be any of a
+    // constantexpr or a simple constant.
+    const ConstantExpr *CE1 = cast<ConstantExpr>(V1);
+    switch (CE1->getOpcode()) {
+    case Instruction::FPTrunc:
+    case Instruction::FPExt:
+    case Instruction::UIToFP:
+    case Instruction::SIToFP:
+      // We might be able to do something with these but we don't right now.
+      break;
+    default:
+      break;
+    }
   }
+  // There are MANY other foldings that we could perform here.  They will
+  // probably be added on demand, as they seem needed.
+  return FCmpInst::BAD_FCMP_PREDICATE;
+}
 
-  static Constant *Sub(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() - (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
-  }
+/// evaluateICmpRelation - This function determines if there is anything we can
+/// decide about the two constants provided.  This doesn't need to handle simple
+/// things like integer comparisons, but should instead handle ConstantExprs
+/// and GlobalValues.  If we can determine that the two constants have a
+/// particular relation to each other, we should return the corresponding ICmp
+/// predicate, otherwise return ICmpInst::BAD_ICMP_PREDICATE.
+///
+/// To simplify this code we canonicalize the relation so that the first
+/// operand is always the most "complex" of the two.  We consider simple
+/// constants (like ConstantInt) to be the simplest, followed by
+/// GlobalValues, followed by ConstantExpr's (the most complex).
+///
+static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, 
+                                                const Constant *V2,
+                                                bool isSigned) {
+  assert(V1->getType() == V2->getType() &&
+         "Cannot compare different types of values!");
+  if (V1 == V2) return ICmpInst::ICMP_EQ;
+
+  if (!isa<ConstantExpr>(V1) && !isa<GlobalValue>(V1)) {
+    if (!isa<GlobalValue>(V2) && !isa<ConstantExpr>(V2)) {
+      // We distilled this down to a simple case, use the standard constant
+      // folder.
+      ConstantInt *R = 0;
+      Constant *C1 = const_cast<Constant*>(V1);
+      Constant *C2 = const_cast<Constant*>(V2);
+      ICmpInst::Predicate pred = ICmpInst::ICMP_EQ;
+      R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, C1, C2));
+      if (R && !R->isZero()) 
+        return pred;
+      pred = isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
+      R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, C1, C2));
+      if (R && !R->isZero())
+        return pred;
+      pred = isSigned ?  ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+      R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, C1, C2));
+      if (R && !R->isZero())
+        return pred;
+      
+      // If we couldn't figure it out, bail.
+      return ICmpInst::BAD_ICMP_PREDICATE;
+    }
+    
+    // If the first operand is simple, swap operands.
+    ICmpInst::Predicate SwappedRelation = 
+      evaluateICmpRelation(V2, V1, isSigned);
+    if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE)
+      return ICmpInst::getSwappedPredicate(SwappedRelation);
+
+  } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(V1)) {
+    if (isa<ConstantExpr>(V2)) {  // Swap as necessary.
+      ICmpInst::Predicate SwappedRelation = 
+        evaluateICmpRelation(V2, V1, isSigned);
+      if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE)
+        return ICmpInst::getSwappedPredicate(SwappedRelation);
+      else
+        return ICmpInst::BAD_ICMP_PREDICATE;
+    }
 
-  static Constant *Mul(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() * (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
-  }
+    // Now we know that the RHS is a GlobalValue or simple constant,
+    // which (since the types must match) means that it's a ConstantPointerNull.
+    if (const GlobalValue *CPR2 = dyn_cast<GlobalValue>(V2)) {
+      // Don't try to decide equality of aliases.
+      if (!isa<GlobalAlias>(CPR1) && !isa<GlobalAlias>(CPR2))
+        if (!CPR1->hasExternalWeakLinkage() || !CPR2->hasExternalWeakLinkage())
+          return ICmpInst::ICMP_NE;
+    } else {
+      assert(isa<ConstantPointerNull>(V2) && "Canonicalization guarantee!");
+      // GlobalVals can never be null.  Don't try to evaluate aliases.
+      if (!CPR1->hasExternalWeakLinkage() && !isa<GlobalAlias>(CPR1))
+        return ICmpInst::ICMP_NE;
+    }
+  } else {
+    // Ok, the LHS is known to be a constantexpr.  The RHS can be any of a
+    // constantexpr, a CPR, or a simple constant.
+    const ConstantExpr *CE1 = cast<ConstantExpr>(V1);
+    const Constant *CE1Op0 = CE1->getOperand(0);
+
+    switch (CE1->getOpcode()) {
+    case Instruction::Trunc:
+    case Instruction::FPTrunc:
+    case Instruction::FPExt:
+    case Instruction::FPToUI:
+    case Instruction::FPToSI:
+      break; // We can't evaluate floating point casts or truncations.
+
+    case Instruction::UIToFP:
+    case Instruction::SIToFP:
+    case Instruction::BitCast:
+    case Instruction::ZExt:
+    case Instruction::SExt:
+      // If the cast is not actually changing bits, and the second operand is a
+      // null pointer, do the comparison with the pre-casted value.
+      if (V2->isNullValue() &&
+          (isa<PointerType>(CE1->getType()) || CE1->getType()->isInteger())) {
+        bool sgnd = isSigned;
+        if (CE1->getOpcode() == Instruction::ZExt) isSigned = false;
+        if (CE1->getOpcode() == Instruction::SExt) isSigned = true;
+        return evaluateICmpRelation(CE1Op0,
+                                    Constant::getNullValue(CE1Op0->getType()), 
+                                    sgnd);
+      }
 
-  static Constant *Div(const ConstantClass *V1, const ConstantClass *V2) {
-    if (V2->isNullValue()) return 0;
-    BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
+      // If the dest type is a pointer type, and the RHS is a constantexpr cast
+      // from the same type as the src of the LHS, evaluate the inputs.  This is
+      // important for things like "icmp eq (cast 4 to int*), (cast 5 to int*)",
+      // which happens a lot in compilers with tagged integers.
+      if (const ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2))
+        if (CE2->isCast() && isa<PointerType>(CE1->getType()) &&
+            CE1->getOperand(0)->getType() == CE2->getOperand(0)->getType() &&
+            CE1->getOperand(0)->getType()->isInteger()) {
+          bool sgnd = isSigned;
+          if (CE1->getOpcode() == Instruction::ZExt) isSigned = false;
+          if (CE1->getOpcode() == Instruction::SExt) isSigned = true;
+          return evaluateICmpRelation(CE1->getOperand(0), CE2->getOperand(0),
+                                      sgnd);
+        }
+      break;
+
+    case Instruction::GetElementPtr:
+      // Ok, since this is a getelementptr, we know that the constant has a
+      // pointer type.  Check the various cases.
+      if (isa<ConstantPointerNull>(V2)) {
+        // If we are comparing a GEP to a null pointer, check to see if the base
+        // of the GEP equals the null pointer.
+        if (const GlobalValue *GV = dyn_cast<GlobalValue>(CE1Op0)) {
+          if (GV->hasExternalWeakLinkage())
+            // Weak linkage GVals could be zero or not. We're comparing that
+            // to null pointer so its greater-or-equal
+            return isSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
+          else 
+            // If its not weak linkage, the GVal must have a non-zero address
+            // so the result is greater-than
+            return isSigned ? ICmpInst::ICMP_SGT :  ICmpInst::ICMP_UGT;
+        } else if (isa<ConstantPointerNull>(CE1Op0)) {
+          // If we are indexing from a null pointer, check to see if we have any
+          // non-zero indices.
+          for (unsigned i = 1, e = CE1->getNumOperands(); i != e; ++i)
+            if (!CE1->getOperand(i)->isNullValue())
+              // Offsetting from null, must not be equal.
+              return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+          // Only zero indexes from null, must still be zero.
+          return ICmpInst::ICMP_EQ;
+        }
+        // Otherwise, we can't really say if the first operand is null or not.
+      } else if (const GlobalValue *CPR2 = dyn_cast<GlobalValue>(V2)) {
+        if (isa<ConstantPointerNull>(CE1Op0)) {
+          if (CPR2->hasExternalWeakLinkage())
+            // Weak linkage GVals could be zero or not. We're comparing it to
+            // a null pointer, so its less-or-equal
+            return isSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
+          else
+            // If its not weak linkage, the GVal must have a non-zero address
+            // so the result is less-than
+            return isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
+        } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(CE1Op0)) {
+          if (CPR1 == CPR2) {
+            // If this is a getelementptr of the same global, then it must be
+            // different.  Because the types must match, the getelementptr could
+            // only have at most one index, and because we fold getelementptr's
+            // with a single zero index, it must be nonzero.
+            assert(CE1->getNumOperands() == 2 &&
+                   !CE1->getOperand(1)->isNullValue() &&
+                   "Suprising getelementptr!");
+            return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+          } else {
+            // If they are different globals, we don't know what the value is,
+            // but they can't be equal.
+            return ICmpInst::ICMP_NE;
+          }
+        }
+      } else {
+        const ConstantExpr *CE2 = cast<ConstantExpr>(V2);
+        const Constant *CE2Op0 = CE2->getOperand(0);
+
+        // There are MANY other foldings that we could perform here.  They will
+        // probably be added on demand, as they seem needed.
+        switch (CE2->getOpcode()) {
+        default: break;
+        case Instruction::GetElementPtr:
+          // By far the most common case to handle is when the base pointers are
+          // obviously to the same or different globals.
+          if (isa<GlobalValue>(CE1Op0) && isa<GlobalValue>(CE2Op0)) {
+            if (CE1Op0 != CE2Op0) // Don't know relative ordering, but not equal
+              return ICmpInst::ICMP_NE;
+            // Ok, we know that both getelementptr instructions are based on the
+            // same global.  From this, we can precisely determine the relative
+            // ordering of the resultant pointers.
+            unsigned i = 1;
+
+            // Compare all of the operands the GEP's have in common.
+            gep_type_iterator GTI = gep_type_begin(CE1);
+            for (;i != CE1->getNumOperands() && i != CE2->getNumOperands();
+                 ++i, ++GTI)
+              switch (IdxCompare(CE1->getOperand(i), CE2->getOperand(i),
+                                 GTI.getIndexedType())) {
+              case -1: return isSigned ? ICmpInst::ICMP_SLT:ICmpInst::ICMP_ULT;
+              case 1:  return isSigned ? ICmpInst::ICMP_SGT:ICmpInst::ICMP_UGT;
+              case -2: return ICmpInst::BAD_ICMP_PREDICATE;
+              }
+
+            // Ok, we ran out of things they have in common.  If any leftovers
+            // are non-zero then we have a difference, otherwise we are equal.
+            for (; i < CE1->getNumOperands(); ++i)
+              if (!CE1->getOperand(i)->isNullValue()) {
+                if (isa<ConstantInt>(CE1->getOperand(i)))
+                  return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+                else
+                  return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal.
+              }
+
+            for (; i < CE2->getNumOperands(); ++i)
+              if (!CE2->getOperand(i)->isNullValue()) {
+                if (isa<ConstantInt>(CE2->getOperand(i)))
+                  return isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
+                else
+                  return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal.
+              }
+            return ICmpInst::ICMP_EQ;
+          }
+        }
+      }
+    default:
+      break;
+    }
   }
 
-  static ConstantBool *LessThan(const ConstantClass *V1,
-                                const ConstantClass *V2) {
-    bool R = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
-    return ConstantBool::get(R);
-  } 
-
-  static Constant *CastToPointer(const ConstantClass *V,
-                                 const PointerType *PTy) {
-    if (V->isNullValue())    // Is it a FP or Integral null value?
-      return ConstantPointerNull::get(PTy);
-    return 0;  // Can't const prop other types of pointers
-  }
+  return ICmpInst::BAD_ICMP_PREDICATE;
+}
 
-  // Casting operators.  ick
-#define DEF_CAST(TYPE, CLASS, CTYPE) \
-  static CLASS *CastTo##TYPE  (const ConstantClass *V) {    \
-    return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
+Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, 
+                                               const Constant *C1, 
+                                               const Constant *C2) {
+  // Fold FCMP_FALSE/FCMP_TRUE unconditionally.
+  if (pred == FCmpInst::FCMP_FALSE) {
+    if (const VectorType *VT = dyn_cast<VectorType>(C1->getType()))
+      return Constant::getNullValue(VectorType::getInteger(VT));
+    else
+      return ConstantInt::getFalse();
+  }
+  
+  if (pred == FCmpInst::FCMP_TRUE) {
+    if (const VectorType *VT = dyn_cast<VectorType>(C1->getType()))
+      return Constant::getAllOnesValue(VectorType::getInteger(VT));
+    else
+      return ConstantInt::getTrue();
+  }
+      
+  // Handle some degenerate cases first
+  if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) {
+    // vicmp/vfcmp -> [vector] undef
+    if (const VectorType *VTy = dyn_cast<VectorType>(C1->getType()))
+      return UndefValue::get(VectorType::getInteger(VTy));
+    
+    // icmp/fcmp -> i1 undef
+    return UndefValue::get(Type::Int1Ty);
   }
 
-  DEF_CAST(Bool  , ConstantBool, bool)
-  DEF_CAST(SByte , ConstantSInt, signed char)
-  DEF_CAST(UByte , ConstantUInt, unsigned char)
-  DEF_CAST(Short , ConstantSInt, signed short)
-  DEF_CAST(UShort, ConstantUInt, unsigned short)
-  DEF_CAST(Int   , ConstantSInt, signed int)
-  DEF_CAST(UInt  , ConstantUInt, unsigned int)
-  DEF_CAST(Long  , ConstantSInt, int64_t)
-  DEF_CAST(ULong , ConstantUInt, uint64_t)
-  DEF_CAST(Float , ConstantFP  , float)
-  DEF_CAST(Double, ConstantFP  , double)
-#undef DEF_CAST
-};
-
+  // No compile-time operations on this type yet.
+  if (C1->getType() == Type::PPC_FP128Ty)
+    return 0;
 
-//===----------------------------------------------------------------------===//
-//                           DirectIntRules Class
-//===----------------------------------------------------------------------===//
-//
-// DirectIntRules provides implementations of functions that are valid on
-// integer types, but not all types in general.
-//
-template <class ConstantClass, class BuiltinType, Type **Ty>
-struct DirectIntRules
-  : public DirectRules<ConstantClass, BuiltinType, Ty,
-                       DirectIntRules<ConstantClass, BuiltinType, Ty> > {
-
-  static Constant *Div(const ConstantClass *V1, const ConstantClass *V2) {
-    if (V2->isNullValue()) return 0;
-    if (V2->isAllOnesValue() &&              // MIN_INT / -1
-        (BuiltinType)V1->getValue() == -(BuiltinType)V1->getValue())
-      return 0;
-    BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
+  // icmp eq/ne(null,GV) -> false/true
+  if (C1->isNullValue()) {
+    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C2))
+      // Don't try to evaluate aliases.  External weak GV can be null.
+      if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) {
+        if (pred == ICmpInst::ICMP_EQ)
+          return ConstantInt::getFalse();
+        else if (pred == ICmpInst::ICMP_NE)
+          return ConstantInt::getTrue();
+      }
+  // icmp eq/ne(GV,null) -> false/true
+  } else if (C2->isNullValue()) {
+    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C1))
+      // Don't try to evaluate aliases.  External weak GV can be null.
+      if (!isa<GlobalAlias>(GV) && !GV->hasExternalWeakLinkage()) {
+        if (pred == ICmpInst::ICMP_EQ)
+          return ConstantInt::getFalse();
+        else if (pred == ICmpInst::ICMP_NE)
+          return ConstantInt::getTrue();
+      }
   }
 
-  static Constant *Rem(const ConstantClass *V1,
-                       const ConstantClass *V2) {
-    if (V2->isNullValue()) return 0;         // X / 0
-    if (V2->isAllOnesValue() &&              // MIN_INT / -1
-        (BuiltinType)V1->getValue() == -(BuiltinType)V1->getValue())
-      return 0;
-    BuiltinType R = (BuiltinType)V1->getValue() % (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
+  if (isa<ConstantInt>(C1) && isa<ConstantInt>(C2)) {
+    APInt V1 = cast<ConstantInt>(C1)->getValue();
+    APInt V2 = cast<ConstantInt>(C2)->getValue();
+    switch (pred) {
+    default: assert(0 && "Invalid ICmp Predicate"); return 0;
+    case ICmpInst::ICMP_EQ: return ConstantInt::get(Type::Int1Ty, V1 == V2);
+    case ICmpInst::ICMP_NE: return ConstantInt::get(Type::Int1Ty, V1 != V2);
+    case ICmpInst::ICMP_SLT:return ConstantInt::get(Type::Int1Ty, V1.slt(V2));
+    case ICmpInst::ICMP_SGT:return ConstantInt::get(Type::Int1Ty, V1.sgt(V2));
+    case ICmpInst::ICMP_SLE:return ConstantInt::get(Type::Int1Ty, V1.sle(V2));
+    case ICmpInst::ICMP_SGE:return ConstantInt::get(Type::Int1Ty, V1.sge(V2));
+    case ICmpInst::ICMP_ULT:return ConstantInt::get(Type::Int1Ty, V1.ult(V2));
+    case ICmpInst::ICMP_UGT:return ConstantInt::get(Type::Int1Ty, V1.ugt(V2));
+    case ICmpInst::ICMP_ULE:return ConstantInt::get(Type::Int1Ty, V1.ule(V2));
+    case ICmpInst::ICMP_UGE:return ConstantInt::get(Type::Int1Ty, V1.uge(V2));
+    }
+  } else if (isa<ConstantFP>(C1) && isa<ConstantFP>(C2)) {
+    APFloat C1V = cast<ConstantFP>(C1)->getValueAPF();
+    APFloat C2V = cast<ConstantFP>(C2)->getValueAPF();
+    APFloat::cmpResult R = C1V.compare(C2V);
+    switch (pred) {
+    default: assert(0 && "Invalid FCmp Predicate"); return 0;
+    case FCmpInst::FCMP_FALSE: return ConstantInt::getFalse();
+    case FCmpInst::FCMP_TRUE:  return ConstantInt::getTrue();
+    case FCmpInst::FCMP_UNO:
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered);
+    case FCmpInst::FCMP_ORD:
+      return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpUnordered);
+    case FCmpInst::FCMP_UEQ:
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered ||
+                                            R==APFloat::cmpEqual);
+    case FCmpInst::FCMP_OEQ:   
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpEqual);
+    case FCmpInst::FCMP_UNE:
+      return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpEqual);
+    case FCmpInst::FCMP_ONE:   
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan ||
+                                            R==APFloat::cmpGreaterThan);
+    case FCmpInst::FCMP_ULT: 
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered ||
+                                            R==APFloat::cmpLessThan);
+    case FCmpInst::FCMP_OLT:   
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan);
+    case FCmpInst::FCMP_UGT:
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered ||
+                                            R==APFloat::cmpGreaterThan);
+    case FCmpInst::FCMP_OGT:
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan);
+    case FCmpInst::FCMP_ULE:
+      return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpGreaterThan);
+    case FCmpInst::FCMP_OLE: 
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan ||
+                                            R==APFloat::cmpEqual);
+    case FCmpInst::FCMP_UGE:
+      return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpLessThan);
+    case FCmpInst::FCMP_OGE: 
+      return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan ||
+                                            R==APFloat::cmpEqual);
+    }
+  } else if (isa<VectorType>(C1->getType())) {
+    SmallVector<Constant*, 16> C1Elts, C2Elts;
+    C1->getVectorElements(C1Elts);
+    C2->getVectorElements(C2Elts);
+    
+    // If we can constant fold the comparison of each element, constant fold
+    // the whole vector comparison.
+    SmallVector<Constant*, 4> ResElts;
+    const Type *InEltTy = C1Elts[0]->getType();
+    bool isFP = InEltTy->isFloatingPoint();
+    const Type *ResEltTy = InEltTy;
+    if (isFP)
+      ResEltTy = IntegerType::get(InEltTy->getPrimitiveSizeInBits());
+    
+    for (unsigned i = 0, e = C1Elts.size(); i != e; ++i) {
+      // Compare the elements, producing an i1 result or constant expr.
+      Constant *C;
+      if (isFP)
+        C = ConstantExpr::getFCmp(pred, C1Elts[i], C2Elts[i]);
+      else
+        C = ConstantExpr::getICmp(pred, C1Elts[i], C2Elts[i]);
+
+      // If it is a bool or undef result, convert to the dest type.
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(C)) {
+        if (CI->isZero())
+          ResElts.push_back(Constant::getNullValue(ResEltTy));
+        else
+          ResElts.push_back(Constant::getAllOnesValue(ResEltTy));
+      } else if (isa<UndefValue>(C)) {
+        ResElts.push_back(UndefValue::get(ResEltTy));
+      } else {
+        break;
+      }
+    }
+    
+    if (ResElts.size() == C1Elts.size())
+      return ConstantVector::get(&ResElts[0], ResElts.size());
   }
 
-  static Constant *And(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() & (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
-  }
-  static Constant *Or(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() | (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
-  }
-  static Constant *Xor(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() ^ (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
+  if (C1->getType()->isFloatingPoint()) {
+    int Result = -1;  // -1 = unknown, 0 = known false, 1 = known true.
+    switch (evaluateFCmpRelation(C1, C2)) {
+    default: assert(0 && "Unknown relation!");
+    case FCmpInst::FCMP_UNO:
+    case FCmpInst::FCMP_ORD:
+    case FCmpInst::FCMP_UEQ:
+    case FCmpInst::FCMP_UNE:
+    case FCmpInst::FCMP_ULT:
+    case FCmpInst::FCMP_UGT:
+    case FCmpInst::FCMP_ULE:
+    case FCmpInst::FCMP_UGE:
+    case FCmpInst::FCMP_TRUE:
+    case FCmpInst::FCMP_FALSE:
+    case FCmpInst::BAD_FCMP_PREDICATE:
+      break; // Couldn't determine anything about these constants.
+    case FCmpInst::FCMP_OEQ: // We know that C1 == C2
+      Result = (pred == FCmpInst::FCMP_UEQ || pred == FCmpInst::FCMP_OEQ ||
+                pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE ||
+                pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+      break;
+    case FCmpInst::FCMP_OLT: // We know that C1 < C2
+      Result = (pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
+                pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT ||
+                pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE);
+      break;
+    case FCmpInst::FCMP_OGT: // We know that C1 > C2
+      Result = (pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
+                pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT ||
+                pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+      break;
+    case FCmpInst::FCMP_OLE: // We know that C1 <= C2
+      // We can only partially decide this relation.
+      if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) 
+        Result = 0;
+      else if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT) 
+        Result = 1;
+      break;
+    case FCmpInst::FCMP_OGE: // We known that C1 >= C2
+      // We can only partially decide this relation.
+      if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT) 
+        Result = 0;
+      else if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) 
+        Result = 1;
+      break;
+    case ICmpInst::ICMP_NE: // We know that C1 != C2
+      // We can only partially decide this relation.
+      if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) 
+        Result = 0;
+      else if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) 
+        Result = 1;
+      break;
+    }
+    
+    // If we evaluated the result, return it now.
+    if (Result != -1) {
+      if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) {
+        if (Result == 0)
+          return Constant::getNullValue(VectorType::getInteger(VT));
+        else
+          return Constant::getAllOnesValue(VectorType::getInteger(VT));
+      }
+      return ConstantInt::get(Type::Int1Ty, Result);
+    }
+    
+  } else {
+    // Evaluate the relation between the two constants, per the predicate.
+    int Result = -1;  // -1 = unknown, 0 = known false, 1 = known true.
+    switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) {
+    default: assert(0 && "Unknown relational!");
+    case ICmpInst::BAD_ICMP_PREDICATE:
+      break;  // Couldn't determine anything about these constants.
+    case ICmpInst::ICMP_EQ:   // We know the constants are equal!
+      // If we know the constants are equal, we can decide the result of this
+      // computation precisely.
+      Result = (pred == ICmpInst::ICMP_EQ  ||
+                pred == ICmpInst::ICMP_ULE ||
+                pred == ICmpInst::ICMP_SLE ||
+                pred == ICmpInst::ICMP_UGE ||
+                pred == ICmpInst::ICMP_SGE);
+      break;
+    case ICmpInst::ICMP_ULT:
+      // If we know that C1 < C2, we can decide the result of this computation
+      // precisely.
+      Result = (pred == ICmpInst::ICMP_ULT ||
+                pred == ICmpInst::ICMP_NE  ||
+                pred == ICmpInst::ICMP_ULE);
+      break;
+    case ICmpInst::ICMP_SLT:
+      // If we know that C1 < C2, we can decide the result of this computation
+      // precisely.
+      Result = (pred == ICmpInst::ICMP_SLT ||
+                pred == ICmpInst::ICMP_NE  ||
+                pred == ICmpInst::ICMP_SLE);
+      break;
+    case ICmpInst::ICMP_UGT:
+      // If we know that C1 > C2, we can decide the result of this computation
+      // precisely.
+      Result = (pred == ICmpInst::ICMP_UGT ||
+                pred == ICmpInst::ICMP_NE  ||
+                pred == ICmpInst::ICMP_UGE);
+      break;
+    case ICmpInst::ICMP_SGT:
+      // If we know that C1 > C2, we can decide the result of this computation
+      // precisely.
+      Result = (pred == ICmpInst::ICMP_SGT ||
+                pred == ICmpInst::ICMP_NE  ||
+                pred == ICmpInst::ICMP_SGE);
+      break;
+    case ICmpInst::ICMP_ULE:
+      // If we know that C1 <= C2, we can only partially decide this relation.
+      if (pred == ICmpInst::ICMP_UGT) Result = 0;
+      if (pred == ICmpInst::ICMP_ULT) Result = 1;
+      break;
+    case ICmpInst::ICMP_SLE:
+      // If we know that C1 <= C2, we can only partially decide this relation.
+      if (pred == ICmpInst::ICMP_SGT) Result = 0;
+      if (pred == ICmpInst::ICMP_SLT) Result = 1;
+      break;
+
+    case ICmpInst::ICMP_UGE:
+      // If we know that C1 >= C2, we can only partially decide this relation.
+      if (pred == ICmpInst::ICMP_ULT) Result = 0;
+      if (pred == ICmpInst::ICMP_UGT) Result = 1;
+      break;
+    case ICmpInst::ICMP_SGE:
+      // If we know that C1 >= C2, we can only partially decide this relation.
+      if (pred == ICmpInst::ICMP_SLT) Result = 0;
+      if (pred == ICmpInst::ICMP_SGT) Result = 1;
+      break;
+
+    case ICmpInst::ICMP_NE:
+      // If we know that C1 != C2, we can only partially decide this relation.
+      if (pred == ICmpInst::ICMP_EQ) Result = 0;
+      if (pred == ICmpInst::ICMP_NE) Result = 1;
+      break;
+    }
+    
+    // If we evaluated the result, return it now.
+    if (Result != -1) {
+      if (const VectorType *VT = dyn_cast<VectorType>(C1->getType())) {
+        if (Result == 0)
+          return Constant::getNullValue(VT);
+        else
+          return Constant::getAllOnesValue(VT);
+      }
+      return ConstantInt::get(Type::Int1Ty, Result);
+    }
+    
+    if (!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) {
+      // If C2 is a constant expr and C1 isn't, flop them around and fold the
+      // other way if possible.
+      switch (pred) {
+      case ICmpInst::ICMP_EQ:
+      case ICmpInst::ICMP_NE:
+        // No change of predicate required.
+        return ConstantFoldCompareInstruction(pred, C2, C1);
+
+      case ICmpInst::ICMP_ULT:
+      case ICmpInst::ICMP_SLT:
+      case ICmpInst::ICMP_UGT:
+      case ICmpInst::ICMP_SGT:
+      case ICmpInst::ICMP_ULE:
+      case ICmpInst::ICMP_SLE:
+      case ICmpInst::ICMP_UGE:
+      case ICmpInst::ICMP_SGE:
+        // Change the predicate as necessary to swap the operands.
+        pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred);
+        return ConstantFoldCompareInstruction(pred, C2, C1);
+
+      default:  // These predicates cannot be flopped around.
+        break;
+      }
+    }
   }
+  return 0;
+}
 
-  static Constant *Shl(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() << (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
-  }
+Constant *llvm::ConstantFoldGetElementPtr(const Constant *C,
+                                          Constant* const *Idxs,
+                                          unsigned NumIdx) {
+  if (NumIdx == 0 ||
+      (NumIdx == 1 && Idxs[0]->isNullValue()))
+    return const_cast<Constant*>(C);
 
-  static Constant *Shr(const ConstantClass *V1, const ConstantClass *V2) {
-    BuiltinType R = (BuiltinType)V1->getValue() >> (BuiltinType)V2->getValue();
-    return ConstantClass::get(*Ty, R);
+  if (isa<UndefValue>(C)) {
+    const PointerType *Ptr = cast<PointerType>(C->getType());
+    const Type *Ty = GetElementPtrInst::getIndexedType(Ptr,
+                                                       (Value **)Idxs,
+                                                       (Value **)Idxs+NumIdx);
+    assert(Ty != 0 && "Invalid indices for GEP!");
+    return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace()));
   }
-};
 
-
-//===----------------------------------------------------------------------===//
-//                           DirectFPRules Class
-//===----------------------------------------------------------------------===//
-//
-// DirectFPRules provides implementations of functions that are valid on
-// floating point types, but not all types in general.
-//
-template <class ConstantClass, class BuiltinType, Type **Ty>
-struct DirectFPRules
-  : public DirectRules<ConstantClass, BuiltinType, Ty,
-                       DirectFPRules<ConstantClass, BuiltinType, Ty> > {
-  static Constant *Rem(const ConstantClass *V1, const ConstantClass *V2) {
-    if (V2->isNullValue()) return 0;
-    BuiltinType Result = std::fmod((BuiltinType)V1->getValue(),
-                                   (BuiltinType)V2->getValue());
-    return ConstantClass::get(*Ty, Result);
+  Constant *Idx0 = Idxs[0];
+  if (C->isNullValue()) {
+    bool isNull = true;
+    for (unsigned i = 0, e = NumIdx; i != e; ++i)
+      if (!Idxs[i]->isNullValue()) {
+        isNull = false;
+        break;
+      }
+    if (isNull) {
+      const PointerType *Ptr = cast<PointerType>(C->getType());
+      const Type *Ty = GetElementPtrInst::getIndexedType(Ptr,
+                                                         (Value**)Idxs,
+                                                         (Value**)Idxs+NumIdx);
+      assert(Ty != 0 && "Invalid indices for GEP!");
+      return 
+        ConstantPointerNull::get(PointerType::get(Ty,Ptr->getAddressSpace()));
+    }
   }
-};
 
-//===----------------------------------------------------------------------===//
-//                            DirectRules Subclasses
-//===----------------------------------------------------------------------===//
-//
-// Given the DirectRules class we can now implement lots of types with little
-// code.  Thank goodness C++ compilers are great at stomping out layers of 
-// templates... can you imagine having to do this all by hand? (/me is lazy :)
-//
+  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(const_cast<Constant*>(C))) {
+    // 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 (CE->getOpcode() == Instruction::GetElementPtr) {
+      const Type *LastTy = 0;
+      for (gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
+           I != E; ++I)
+        LastTy = *I;
+
+      if ((LastTy && isa<ArrayType>(LastTy)) || Idx0->isNullValue()) {
+        SmallVector<Value*, 16> NewIndices;
+        NewIndices.reserve(NumIdx + CE->getNumOperands());
+        for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i)
+          NewIndices.push_back(CE->getOperand(i));
+
+        // Add the last index of the source with the first index of the new GEP.
+        // Make sure to handle the case when they are actually different types.
+        Constant *Combined = CE->getOperand(CE->getNumOperands()-1);
+        // Otherwise it must be an array.
+        if (!Idx0->isNullValue()) {
+          const Type *IdxTy = Combined->getType();
+          if (IdxTy != Idx0->getType()) {
+            Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Type::Int64Ty);
+            Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, 
+                                                          Type::Int64Ty);
+            Combined = ConstantExpr::get(Instruction::Add, C1, C2);
+          } else {
+            Combined =
+              ConstantExpr::get(Instruction::Add, Idx0, Combined);
+          }
+        }
+
+        NewIndices.push_back(Combined);
+        NewIndices.insert(NewIndices.end(), Idxs+1, Idxs+NumIdx);
+        return ConstantExpr::getGetElementPtr(CE->getOperand(0), &NewIndices[0],
+                                              NewIndices.size());
+      }
+    }
 
-// ConstRules::find - Return the constant rules that take care of the specified
-// type.
-//
-Annotation *ConstRules::find(AnnotationID AID, const Annotable *TyA, void *) {
-  assert(AID == ConstRules::AID && "Bad annotation for factory!");
-  const Type *Ty = cast<Type>((const Value*)TyA);
-  
-  switch (Ty->getPrimitiveID()) {
-  case Type::BoolTyID:    return new BoolRules();
-  case Type::PointerTyID: return new PointerRules();
-  case Type::SByteTyID:
-    return new DirectIntRules<ConstantSInt,   signed char , &Type::SByteTy>();
-  case Type::UByteTyID:
-    return new DirectIntRules<ConstantUInt, unsigned char , &Type::UByteTy>();
-  case Type::ShortTyID:
-    return new DirectIntRules<ConstantSInt,   signed short, &Type::ShortTy>();
-  case Type::UShortTyID:
-    return new DirectIntRules<ConstantUInt, unsigned short, &Type::UShortTy>();
-  case Type::IntTyID:
-    return new DirectIntRules<ConstantSInt,   signed int  , &Type::IntTy>();
-  case Type::UIntTyID:
-    return new DirectIntRules<ConstantUInt, unsigned int  , &Type::UIntTy>();
-  case Type::LongTyID:
-    return new DirectIntRules<ConstantSInt,  int64_t      , &Type::LongTy>();
-  case Type::ULongTyID:
-    return new DirectIntRules<ConstantUInt, uint64_t      , &Type::ULongTy>();
-  case Type::FloatTyID:
-    return new DirectFPRules<ConstantFP  , float         , &Type::FloatTy>();
-  case Type::DoubleTyID:
-    return new DirectFPRules<ConstantFP  , double        , &Type::DoubleTy>();
-  default:
-    return new EmptyRules();
+    // Implement folding of:
+    //    int* getelementptr ([2 x int]* cast ([3 x int]* %X to [2 x int]*),
+    //                        long 0, long 0)
+    // To: int* getelementptr ([3 x int]* %X, long 0, long 0)
+    //
+    if (CE->isCast() && NumIdx > 1 && Idx0->isNullValue()) {
+      if (const PointerType *SPT =
+          dyn_cast<PointerType>(CE->getOperand(0)->getType()))
+        if (const ArrayType *SAT = dyn_cast<ArrayType>(SPT->getElementType()))
+          if (const ArrayType *CAT =
+        dyn_cast<ArrayType>(cast<PointerType>(C->getType())->getElementType()))
+            if (CAT->getElementType() == SAT->getElementType())
+              return ConstantExpr::getGetElementPtr(
+                      (Constant*)CE->getOperand(0), Idxs, NumIdx);
+    }
+    
+    // Fold: getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1)
+    // Into: inttoptr (i64 0 to i8*)
+    // This happens with pointers to member functions in C++.
+    if (CE->getOpcode() == Instruction::IntToPtr && NumIdx == 1 &&
+        isa<ConstantInt>(CE->getOperand(0)) && isa<ConstantInt>(Idxs[0]) &&
+        cast<PointerType>(CE->getType())->getElementType() == Type::Int8Ty) {
+      Constant *Base = CE->getOperand(0);
+      Constant *Offset = Idxs[0];
+      
+      // Convert the smaller integer to the larger type.
+      if (Offset->getType()->getPrimitiveSizeInBits() < 
+          Base->getType()->getPrimitiveSizeInBits())
+        Offset = ConstantExpr::getSExt(Offset, Base->getType());
+      else if (Base->getType()->getPrimitiveSizeInBits() <
+               Offset->getType()->getPrimitiveSizeInBits())
+        Base = ConstantExpr::getZExt(Base, Base->getType());
+      
+      Base = ConstantExpr::getAdd(Base, Offset);
+      return ConstantExpr::getIntToPtr(Base, CE->getType());
+    }
   }
+  return 0;
 }
 
-ConstRules *ConstRules::getConstantExprRules() {
-  static EmptyRules CERules;
-  return &CERules;
-}