For PR950:
The long awaited CAST patch. This introduces 12 new instructions into LLVM
to replace the cast instruction. Corresponding changes throughout LLVM are
provided. This passes llvm-test, llvm/test, and SPEC CPUINT2000 with the
exception of 175.vpr which fails only on a slight floating point output
difference.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31931 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index c2f5d73..ac8d324 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -423,7 +423,20 @@
       }
       break;
     }
-    case Instruction::Cast: {
+    case Instruction::Trunc:
+    case Instruction::ZExt:
+    case Instruction::SExt:
+    case Instruction::FPTrunc:
+    case Instruction::FPExt:
+    case Instruction::UIToFP:
+    case Instruction::SIToFP:
+    case Instruction::FPToUI:
+    case Instruction::FPToSI:
+      assert(0 && "FIXME: Don't yet support this kind of constant cast expr");
+      break;
+    case Instruction::IntToPtr:
+    case Instruction::PtrToInt:
+    case Instruction::BitCast: {
       // Support only foldable casts to/from pointers that can be eliminated by
       // changing the pointer to the appropriately sized integer type.
       Constant *Op = CE->getOperand(0);
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index ece3072..2df839f 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -40,6 +40,7 @@
 template <class ArgIt>
 static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
                                  ArgIt ArgBegin, ArgIt ArgEnd,
+                                 const unsigned *castOpcodes,
                                  const Type *RetTy, Function *&FCache) {
   if (!FCache) {
     // If we haven't already looked up this function, check to see if the
@@ -63,7 +64,12 @@
        ++I, ++ArgNo) {
     Value *Arg = *I;
     if (Arg->getType() != FT->getParamType(ArgNo))
-      Arg = new CastInst(Arg, FT->getParamType(ArgNo), Arg->getName(), CI);
+      if (castOpcodes[ArgNo])
+        Arg = CastInst::create(Instruction::CastOps(castOpcodes[ArgNo]),
+          Arg, FT->getParamType(ArgNo), Arg->getName(), CI);
+      else
+        Arg = CastInst::createInferredCast(Arg, FT->getParamType(ArgNo), 
+                                           Arg->getName(), CI);
     Operands.push_back(Arg);
   }
   // Pass nulls into any additional arguments...
@@ -76,7 +82,7 @@
   if (!CI->use_empty()) {
     Value *V = NewCI;
     if (CI->getType() != NewCI->getType())
-      V = new CastInst(NewCI, CI->getType(), Name, CI);
+      V = CastInst::createInferredCast(NewCI, CI->getType(), Name, CI);
     CI->replaceAllUsesWith(V);
   }
   return NewCI;
@@ -283,8 +289,9 @@
     // convert the call to an explicit setjmp or longjmp call.
   case Intrinsic::setjmp: {
     static Function *SetjmpFCache = 0;
+    static const unsigned castOpcodes[] = { Instruction::BitCast };
     Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin()+1, CI->op_end(),
-                               Type::IntTy, SetjmpFCache);
+                               castOpcodes, Type::IntTy, SetjmpFCache);
     if (CI->getType() != Type::VoidTy)
       CI->replaceAllUsesWith(V);
     break;
@@ -296,16 +303,20 @@
 
   case Intrinsic::longjmp: {
     static Function *LongjmpFCache = 0;
+    static const unsigned castOpcodes[] = 
+      { Instruction::BitCast, 0 };
     ReplaceCallWith("longjmp", CI, CI->op_begin()+1, CI->op_end(),
-                    Type::VoidTy, LongjmpFCache);
+                    castOpcodes, Type::VoidTy, LongjmpFCache);
     break;
   }
 
   case Intrinsic::siglongjmp: {
     // Insert the call to abort
     static Function *AbortFCache = 0;
-    ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), Type::VoidTy,
-                    AbortFCache);
+    static const unsigned castOpcodes[] =
+      { Instruction::BitCast, 0 };
+    ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), 
+                    castOpcodes, Type::VoidTy, AbortFCache);
     break;
   }
   case Intrinsic::ctpop_i8:
@@ -383,31 +394,76 @@
   case Intrinsic::dbg_declare:
     break;    // Simply strip out debugging intrinsics
 
-  case Intrinsic::memcpy_i32:
-  case Intrinsic::memcpy_i64: {
+  case Intrinsic::memcpy_i32: {
     // The memcpy intrinsic take an extra alignment argument that the memcpy
     // libc function does not.
+    static unsigned opcodes[] = 
+      { Instruction::BitCast, Instruction::BitCast, Instruction::BitCast };
+    // FIXME:
+    // if (target_is_64_bit) opcodes[2] = Instruction::ZExt;
+    // else opcodes[2] = Instruction::BitCast;
     static Function *MemcpyFCache = 0;
     ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1,
-                    (*(CI->op_begin()+1))->getType(), MemcpyFCache);
+                    opcodes, (*(CI->op_begin()+1))->getType(), MemcpyFCache);
     break;
   }
-  case Intrinsic::memmove_i32: 
+  case Intrinsic::memcpy_i64: {
+    static unsigned opcodes[] = 
+      { Instruction::BitCast, Instruction::BitCast, Instruction::Trunc };
+    // FIXME:
+    // if (target_is_64_bit) opcodes[2] = Instruction::BitCast;
+    // else opcodes[2] = Instruction::Trunc;
+    static Function *MemcpyFCache = 0;
+    ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1,
+                     opcodes, (*(CI->op_begin()+1))->getType(), MemcpyFCache);
+    break;
+  }
+  case Intrinsic::memmove_i32: {
+    // The memmove intrinsic take an extra alignment argument that the memmove
+    // libc function does not.
+    static unsigned opcodes[] = 
+      { Instruction::BitCast, Instruction::BitCast, Instruction::BitCast };
+    // FIXME:
+    // if (target_is_64_bit) opcodes[2] = Instruction::ZExt;
+    // else opcodes[2] = Instruction::BitCast;
+    static Function *MemmoveFCache = 0;
+    ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1,
+                    opcodes, (*(CI->op_begin()+1))->getType(), MemmoveFCache);
+    break;
+  }
   case Intrinsic::memmove_i64: {
     // The memmove intrinsic take an extra alignment argument that the memmove
     // libc function does not.
+    static const unsigned opcodes[] = 
+      { Instruction::BitCast, Instruction::BitCast, Instruction::Trunc };
+    // if (target_is_64_bit) opcodes[2] = Instruction::BitCast;
+    // else opcodes[2] = Instruction::Trunc;
     static Function *MemmoveFCache = 0;
     ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1,
-                    (*(CI->op_begin()+1))->getType(), MemmoveFCache);
+                    opcodes, (*(CI->op_begin()+1))->getType(), MemmoveFCache);
     break;
   }
-  case Intrinsic::memset_i32:
+  case Intrinsic::memset_i32: {
+    // The memset intrinsic take an extra alignment argument that the memset
+    // libc function does not.
+    static const unsigned opcodes[] = 
+      { Instruction::BitCast, Instruction::ZExt, Instruction::ZExt, 0 };
+    // if (target_is_64_bit) opcodes[2] = Instruction::BitCast;
+    // else opcodes[2] = Instruction::ZExt;
+    static Function *MemsetFCache = 0;
+    ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1,
+                    opcodes, (*(CI->op_begin()+1))->getType(), MemsetFCache);
+  }
   case Intrinsic::memset_i64: {
     // The memset intrinsic take an extra alignment argument that the memset
     // libc function does not.
+    static const unsigned opcodes[] = 
+      { Instruction::BitCast, Instruction::ZExt, Instruction::Trunc, 0 };
+    // if (target_is_64_bit) opcodes[2] = Instruction::BitCast;
+    // else opcodes[2] = Instruction::Trunc;
     static Function *MemsetFCache = 0;
     ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1,
-                    (*(CI->op_begin()+1))->getType(), MemsetFCache);
+                    opcodes, (*(CI->op_begin()+1))->getType(), MemsetFCache);
     break;
   }
   case Intrinsic::isunordered_f32:
@@ -422,16 +478,18 @@
                              "isunordered", CI));
     break;
   }
-  case Intrinsic::sqrt_f32:
-  case Intrinsic::sqrt_f64: {
-    static Function *sqrtFCache = 0;
+  case Intrinsic::sqrt_f32: {
+    static const unsigned opcodes[] = { 0 };
     static Function *sqrtfFCache = 0;
-    if(CI->getType() == Type::FloatTy)
-      ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(),
-                      Type::FloatTy, sqrtfFCache);
-    else
-      ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(),
-                      Type::DoubleTy, sqrtFCache);
+    ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(),
+                    opcodes, Type::FloatTy, sqrtfFCache);
+    break;
+  }
+  case Intrinsic::sqrt_f64: {
+    static const unsigned opcodes[] =  { 0 };
+    static Function *sqrtFCache = 0;
+    ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(),
+                    opcodes, Type::DoubleTy, sqrtFCache);
     break;
   }
   }
diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp
index bdbdd14..16f8dc8 100644
--- a/lib/CodeGen/MachineDebugInfo.cpp
+++ b/lib/CodeGen/MachineDebugInfo.cpp
@@ -102,7 +102,7 @@
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
     return GV;
   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
-    if (CE->getOpcode() == Instruction::Cast) {
+    if (CE->getOpcode() == Instruction::BitCast) {
       return dyn_cast<GlobalVariable>(CE->getOperand(0));
     }
   }
@@ -115,7 +115,7 @@
   if (isa<GlobalVariable>(V) || isa<ConstantPointerNull>(V)) {
     return true;
   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
-    if (CE->getOpcode() == Instruction::Cast) {
+    if (CE->getOpcode() == Instruction::BitCast) {
       return isa<GlobalVariable>(CE->getOperand(0));
     }
   }
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 8b9fa86..c18b5bc 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -557,13 +557,25 @@
                                         ISD::SETOLT); }
   void visitSetGT(User &I) { visitSetCC(I, ISD::SETGT, ISD::SETUGT,
                                         ISD::SETOGT); }
+  // Visit the conversion instructions
+  void visitTrunc(User &I);
+  void visitZExt(User &I);
+  void visitSExt(User &I);
+  void visitFPTrunc(User &I);
+  void visitFPExt(User &I);
+  void visitFPToUI(User &I);
+  void visitFPToSI(User &I);
+  void visitUIToFP(User &I);
+  void visitSIToFP(User &I);
+  void visitPtrToInt(User &I);
+  void visitIntToPtr(User &I);
+  void visitBitCast(User &I);
 
   void visitExtractElement(User &I);
   void visitInsertElement(User &I);
   void visitShuffleVector(User &I);
 
   void visitGetElementPtr(User &I);
-  void visitCast(User &I);
   void visitSelect(User &I);
 
   void visitMalloc(MallocInst &I);
@@ -1525,63 +1537,127 @@
   }
 }
 
-void SelectionDAGLowering::visitCast(User &I) {
+
+void SelectionDAGLowering::visitTrunc(User &I) {
+  // TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest).
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
+}
+
+void SelectionDAGLowering::visitZExt(User &I) {
+  // ZExt cannot be a no-op cast because sizeof(src) < sizeof(dest).
+  // ZExt also can't be a cast to bool for same reason. So, nothing much to do
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
+}
+
+void SelectionDAGLowering::visitSExt(User &I) {
+  // SExt cannot be a no-op cast because sizeof(src) < sizeof(dest).
+  // SExt also can't be a cast to bool for same reason. So, nothing much to do
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DestVT, N));
+}
+
+void SelectionDAGLowering::visitFPTrunc(User &I) {
+  // FPTrunc is never a no-op cast, no need to check
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N));
+}
+
+void SelectionDAGLowering::visitFPExt(User &I){ 
+  // FPTrunc is never a no-op cast, no need to check
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::FP_EXTEND, DestVT, N));
+}
+
+void SelectionDAGLowering::visitFPToUI(User &I) { 
+  // FPToUI is never a no-op cast, no need to check
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DestVT, N));
+}
+
+void SelectionDAGLowering::visitFPToSI(User &I) {
+  // FPToSI is never a no-op cast, no need to check
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DestVT, N));
+}
+
+void SelectionDAGLowering::visitUIToFP(User &I) { 
+  // UIToFP is never a no-op cast, no need to check
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DestVT, N));
+}
+
+void SelectionDAGLowering::visitSIToFP(User &I){ 
+  // UIToFP is never a no-op cast, no need to check
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N));
+}
+
+void SelectionDAGLowering::visitPtrToInt(User &I) {
+  // What to do depends on the size of the integer and the size of the pointer.
+  // We can either truncate, zero extend, or no-op, accordingly.
   SDOperand N = getValue(I.getOperand(0));
   MVT::ValueType SrcVT = N.getValueType();
   MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  SDOperand Result;
+  if (MVT::getSizeInBits(DestVT) < MVT::getSizeInBits(SrcVT))
+    Result = DAG.getNode(ISD::TRUNCATE, DestVT, N);
+  else 
+    // Note: ZERO_EXTEND can handle cases where the sizes are equal too
+    Result = DAG.getNode(ISD::ZERO_EXTEND, DestVT, N);
+  setValue(&I, Result);
+}
 
+void SelectionDAGLowering::visitIntToPtr(User &I) {
+  // What to do depends on the size of the integer and the size of the pointer.
+  // We can either truncate, zero extend, or no-op, accordingly.
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType SrcVT = N.getValueType();
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
+  if (MVT::getSizeInBits(DestVT) < MVT::getSizeInBits(SrcVT))
+    setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
+  else 
+    // Note: ZERO_EXTEND can handle cases where the sizes are equal too
+    setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
+}
+
+void SelectionDAGLowering::visitBitCast(User &I) { 
+  SDOperand N = getValue(I.getOperand(0));
+  MVT::ValueType DestVT = TLI.getValueType(I.getType());
   if (DestVT == MVT::Vector) {
-    // This is a cast to a vector from something else.  This is always a bit
-    // convert.  Get information about the input vector.
+    // This is a cast to a vector from something else.  
+    // Get information about the output vector.
     const PackedType *DestTy = cast<PackedType>(I.getType());
     MVT::ValueType EltVT = TLI.getValueType(DestTy->getElementType());
     setValue(&I, DAG.getNode(ISD::VBIT_CONVERT, DestVT, N, 
                              DAG.getConstant(DestTy->getNumElements(),MVT::i32),
                              DAG.getValueType(EltVT)));
-  } else if (SrcVT == DestVT) {
-    setValue(&I, N);  // noop cast.
-  } else if (DestVT == MVT::i1) {
-    // Cast to bool is a comparison against zero, not truncation to zero.
-    SDOperand Zero = isInteger(SrcVT) ? DAG.getConstant(0, N.getValueType()) :
-                                       DAG.getConstantFP(0.0, N.getValueType());
-    setValue(&I, DAG.getSetCC(MVT::i1, N, Zero, ISD::SETNE));
-  } else if (isInteger(SrcVT)) {
-    if (isInteger(DestVT)) {        // Int -> Int cast
-      if (DestVT < SrcVT)   // Truncating cast?
-        setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
-      else if (I.getOperand(0)->getType()->isSigned())
-        setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DestVT, N));
-      else
-        setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
-    } else if (isFloatingPoint(DestVT)) {           // Int -> FP cast
-      if (I.getOperand(0)->getType()->isSigned())
-        setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N));
-      else
-        setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DestVT, N));
-    } else {
-      assert(0 && "Unknown cast!");
-    }
-  } else if (isFloatingPoint(SrcVT)) {
-    if (isFloatingPoint(DestVT)) {  // FP -> FP cast
-      if (DestVT < SrcVT)   // Rounding cast?
-        setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N));
-      else
-        setValue(&I, DAG.getNode(ISD::FP_EXTEND, DestVT, N));
-    } else if (isInteger(DestVT)) {        // FP -> Int cast.
-      if (I.getType()->isSigned())
-        setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DestVT, N));
-      else
-        setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DestVT, N));
-    } else {
-      assert(0 && "Unknown cast!");
-    }
-  } else {
-    assert(SrcVT == MVT::Vector && "Unknown cast!");
-    assert(DestVT != MVT::Vector && "Casts to vector already handled!");
-    // This is a cast from a vector to something else.  This is always a bit
-    // convert.  Get information about the input vector.
+    return;
+  } 
+  MVT::ValueType SrcVT = N.getValueType();
+  if (SrcVT == MVT::Vector) {
+    // This is a cast from a vctor to something else. 
+    // Get information about the input vector.
     setValue(&I, DAG.getNode(ISD::VBIT_CONVERT, DestVT, N));
+    return;
   }
+
+  // BitCast assures us that source and destination are the same size so this 
+  // is either a BIT_CONVERT or a no-op.
+  if (DestVT != N.getValueType())
+    setValue(&I, DAG.getNode(ISD::BIT_CONVERT, DestVT, N)); // convert types
+  else
+    setValue(&I, N); // noop cast.
 }
 
 void SelectionDAGLowering::visitInsertElement(User &I) {
@@ -3402,7 +3478,8 @@
       while (isa<PHINode>(InsertPt)) ++InsertPt;
       
       InsertedCast = 
-        new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt);
+        CastInst::createInferredCast(CI->getOperand(0), CI->getType(), "", 
+                                     InsertPt);
       MadeChange = true;
     }
     
@@ -3424,9 +3501,10 @@
                                          Value *PtrOffset) {
   if (V) return V;   // Already computed.
   
+  // Figure out the insertion point
   BasicBlock::iterator InsertPt;
   if (BB == GEPI->getParent()) {
-    // If insert into the GEP's block, insert right after the GEP.
+    // If GEP is already inserted into BB, insert right after the GEP.
     InsertPt = GEPI;
     ++InsertPt;
   } else {
@@ -3440,11 +3518,14 @@
   // operand).
   if (CastInst *CI = dyn_cast<CastInst>(Ptr))
     if (CI->getParent() != BB && isa<PointerType>(CI->getOperand(0)->getType()))
-      Ptr = new CastInst(CI->getOperand(0), CI->getType(), "", InsertPt);
+      Ptr = CastInst::createInferredCast(CI->getOperand(0), CI->getType(), "",
+                                         InsertPt);
   
   // Add the offset, cast it to the right type.
   Ptr = BinaryOperator::createAdd(Ptr, PtrOffset, "", InsertPt);
-  return V = new CastInst(Ptr, GEPI->getType(), "", InsertPt);
+  // Ptr is an integer type, GEPI is pointer type ==> IntToPtr
+  return V = CastInst::create(Instruction::IntToPtr, Ptr, GEPI->getType(), 
+                              "", InsertPt);
 }
 
 /// ReplaceUsesOfGEPInst - Replace all uses of RepPtr with inserted code to
@@ -3461,8 +3542,9 @@
   while (!RepPtr->use_empty()) {
     Instruction *User = cast<Instruction>(RepPtr->use_back());
     
-    // If the user is a Pointer-Pointer cast, recurse.
-    if (isa<CastInst>(User) && isa<PointerType>(User->getType())) {
+    // If the user is a Pointer-Pointer cast, recurse. Only BitCast can be
+    // used for a Pointer-Pointer cast.
+    if (isa<BitCastInst>(User)) {
       ReplaceUsesOfGEPInst(User, Ptr, PtrOffset, DefBB, GEPI, InsertedExprs);
       
       // Drop the use of RepPtr. The cast is dead.  Don't delete it now, else we
@@ -3489,7 +3571,8 @@
     if (GEPI->getType() != RepPtr->getType()) {
       BasicBlock::iterator IP = NewVal;
       ++IP;
-      NewVal = new CastInst(NewVal, RepPtr->getType(), "", IP);
+      // NewVal must be a GEP which must be pointer type, so BitCast
+      NewVal = new BitCastInst(NewVal, RepPtr->getType(), "", IP);
     }
     User->replaceUsesOfWith(RepPtr, NewVal);
   }
@@ -3535,7 +3618,8 @@
   
   // If this is a "GEP X, 0, 0, 0", turn this into a cast.
   if (!hasConstantIndex && !hasVariableIndex) {
-    Value *NC = new CastInst(GEPI->getOperand(0), GEPI->getType(), 
+    /// The GEP operand must be a pointer, so must its result -> BitCast
+    Value *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(), 
                              GEPI->getName(), GEPI);
     GEPI->replaceAllUsesWith(NC);
     GEPI->eraseFromParent();
@@ -3550,7 +3634,7 @@
   // constant offset (which we now know is non-zero) and deal with it later.
   uint64_t ConstantOffset = 0;
   const Type *UIntPtrTy = TD->getIntPtrType();
-  Value *Ptr = new CastInst(GEPI->getOperand(0), UIntPtrTy, "", GEPI);
+  Value *Ptr = new PtrToIntInst(GEPI->getOperand(0), UIntPtrTy, "", GEPI);
   const Type *Ty = GEPI->getOperand(0)->getType();
 
   for (GetElementPtrInst::op_iterator OI = GEPI->op_begin()+1,
@@ -3577,7 +3661,7 @@
       // Ptr = Ptr + Idx * ElementSize;
       
       // Cast Idx to UIntPtrTy if needed.
-      Idx = new CastInst(Idx, UIntPtrTy, "", GEPI);
+      Idx = CastInst::createInferredCast(Idx, UIntPtrTy, "", GEPI);
       
       uint64_t ElementSize = TD->getTypeSize(Ty);
       // Mask off bits that should not be set.