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/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp
index 86e011e..9a501f1 100644
--- a/lib/Bytecode/Reader/Reader.cpp
+++ b/lib/Bytecode/Reader/Reader.cpp
@@ -461,24 +461,23 @@
     insertValue(AI, getTypeSlot(AI->getType()), FunctionValues);
 }
 
-// Convert previous opcode values into the current value and/or construct
-// the instruction. This function handles all *abnormal* cases for instruction
-// generation based on obsolete opcode values. The normal cases are handled
-// in ParseInstruction below.  Generally this function just produces a new
-// Opcode value (first argument). In a few cases (VAArg, VANext) the upgrade
-// path requies that the instruction (sequence) be generated differently from
-// the normal case in order to preserve the original semantics. In these 
-// cases the result of the function will be a non-zero Instruction pointer. In
-// all other cases, zero will be returned indicating that the *normal*
-// instruction generation should be used, but with the new Opcode value.
-// 
+/// Convert previous opcode values into the current value and/or construct
+/// the instruction. This function handles all *abnormal* cases for instruction
+/// generation based on obsolete opcode values. The normal cases are handled
+/// in ParseInstruction below.  Generally this function just produces a new
+/// Opcode value (first argument). In a few cases (VAArg, VANext) the upgrade
+/// path requies that the instruction (sequence) be generated differently from
+/// the normal case in order to preserve the original semantics. In these 
+/// cases the result of the function will be a non-zero Instruction pointer. In
+/// all other cases, zero will be returned indicating that the *normal*
+/// instruction generation should be used, but with the new Opcode value.
 Instruction*
 BytecodeReader::upgradeInstrOpcodes(
   unsigned &Opcode,   ///< The old opcode, possibly updated by this function
   std::vector<unsigned> &Oprnds, ///< The operands to the instruction
   unsigned &iType,    ///< The type code from the bytecode file
-  const Type* InstTy, ///< The type of the instruction
-  BasicBlock* BB      ///< The basic block to insert into, if we need to
+  const Type *InstTy, ///< The type of the instruction
+  BasicBlock *BB      ///< The basic block to insert into, if we need to
 ) {
 
   // First, short circuit this if no conversion is required. When signless
@@ -632,8 +631,27 @@
       Opcode = Instruction::PHI;
       break;
     case 28: // Cast
-      Opcode = Instruction::Cast;
+    {
+      Value *Source = getValue(iType, Oprnds[0]);
+      const Type *DestTy = getType(Oprnds[1]);
+      // The previous definition of cast to bool was a compare against zero. 
+      // We have to retain that semantic so we do it here.
+      if (DestTy == Type::BoolTy) { // if its a cast to bool
+        Opcode = Instruction::SetNE;
+        Result = new SetCondInst(Instruction::SetNE, Source, 
+                                Constant::getNullValue(Source->getType()));
+      } else if (Source->getType()->isFloatingPoint() && 
+                 isa<PointerType>(DestTy)) {
+        // Upgrade what is now an illegal cast (fp -> ptr) into two casts,
+        // fp -> ui, and ui -> ptr 
+        CastInst *CI = new FPToUIInst(Source, Type::ULongTy);
+        BB->getInstList().push_back(CI);
+        Result = new IntToPtrInst(CI, DestTy);
+      } else {
+        Result = CastInst::createInferredCast(Source, DestTy);
+      }
       break;
+    }
     case 29: // Call
       Opcode = Instruction::Call;
       break;
@@ -720,8 +738,66 @@
     case 40: // ShuffleVector
       Opcode = Instruction::ShuffleVector;
       break;
-    case 56: // Invoke with encoded CC
-    case 57: // Invoke Fast CC
+    case 56:   // Invoke with encoded CC
+    case 57: { // Invoke Fast CC
+      if (Oprnds.size() < 3)
+        error("Invalid invoke instruction!");
+      Value *F = getValue(iType, Oprnds[0]);
+
+      // Check to make sure we have a pointer to function type
+      const PointerType *PTy = dyn_cast<PointerType>(F->getType());
+      if (PTy == 0)
+        error("Invoke to non function pointer value!");
+      const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
+      if (FTy == 0)
+        error("Invoke to non function pointer value!");
+
+      std::vector<Value *> Params;
+      BasicBlock *Normal, *Except;
+      unsigned CallingConv = CallingConv::C;
+      if (Opcode == 57)
+        CallingConv = CallingConv::Fast;
+      else if (Opcode == 56) {
+        CallingConv = Oprnds.back();
+        Oprnds.pop_back();
+      }
+      Opcode = Instruction::Invoke;
+
+      if (!FTy->isVarArg()) {
+        Normal = getBasicBlock(Oprnds[1]);
+        Except = getBasicBlock(Oprnds[2]);
+
+        FunctionType::param_iterator It = FTy->param_begin();
+        for (unsigned i = 3, e = Oprnds.size(); i != e; ++i) {
+          if (It == FTy->param_end())
+            error("Invalid invoke instruction!");
+          Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i]));
+        }
+        if (It != FTy->param_end())
+          error("Invalid invoke instruction!");
+      } else {
+        Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1);
+
+        Normal = getBasicBlock(Oprnds[0]);
+        Except = getBasicBlock(Oprnds[1]);
+
+        unsigned FirstVariableArgument = FTy->getNumParams()+2;
+        for (unsigned i = 2; i != FirstVariableArgument; ++i)
+          Params.push_back(getValue(getTypeSlot(FTy->getParamType(i-2)),
+                                    Oprnds[i]));
+
+        // Must be type/value pairs. If not, error out.
+        if (Oprnds.size()-FirstVariableArgument & 1) 
+          error("Invalid invoke instruction!");
+
+        for (unsigned i = FirstVariableArgument; i < Oprnds.size(); i += 2)
+          Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
+      }
+
+      Result = new InvokeInst(F, Normal, Except, Params);
+      if (CallingConv) cast<InvokeInst>(Result)->setCallingConv(CallingConv);
+      break;
+    }
     case 58: // Call with extra operand for calling conv
     case 59: // tail call, Fast CC
     case 60: // normal call, Fast CC
@@ -889,12 +965,78 @@
       Result = new ShuffleVectorInst(V1, V2, V3);
       break;
     }
-    case Instruction::Cast:
+    case Instruction::Trunc:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new TruncInst(getValue(iType, Oprnds[0]), 
+                             getType(Oprnds[1]));
+      break;
+    case Instruction::ZExt:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new ZExtInst(getValue(iType, Oprnds[0]), 
+                            getType(Oprnds[1]));
+      break;
+    case Instruction::SExt:
       if (Oprnds.size() != 2)
         error("Invalid Cast instruction!");
-      Result = new CastInst(getValue(iType, Oprnds[0]),
+      Result = new SExtInst(getValue(iType, Oprnds[0]),
                             getType(Oprnds[1]));
       break;
+    case Instruction::FPTrunc:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new FPTruncInst(getValue(iType, Oprnds[0]), 
+                               getType(Oprnds[1]));
+      break;
+    case Instruction::FPExt:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new FPExtInst(getValue(iType, Oprnds[0]), 
+                             getType(Oprnds[1]));
+      break;
+    case Instruction::UIToFP:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new UIToFPInst(getValue(iType, Oprnds[0]), 
+                              getType(Oprnds[1]));
+      break;
+    case Instruction::SIToFP:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new SIToFPInst(getValue(iType, Oprnds[0]), 
+                              getType(Oprnds[1]));
+      break;
+    case Instruction::FPToUI:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new FPToUIInst(getValue(iType, Oprnds[0]), 
+                              getType(Oprnds[1]));
+      break;
+    case Instruction::FPToSI:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new FPToSIInst(getValue(iType, Oprnds[0]), 
+                              getType(Oprnds[1]));
+      break;
+    case Instruction::IntToPtr:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new IntToPtrInst(getValue(iType, Oprnds[0]), 
+                                getType(Oprnds[1]));
+      break;
+    case Instruction::PtrToInt:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new PtrToIntInst(getValue(iType, Oprnds[0]), 
+                                getType(Oprnds[1]));
+      break;
+    case Instruction::BitCast:
+      if (Oprnds.size() != 2)
+        error("Invalid cast instruction!");
+      Result = new BitCastInst(getValue(iType, Oprnds[0]),
+                               getType(Oprnds[1]));
+      break;
     case Instruction::Select:
       if (Oprnds.size() != 3)
         error("Invalid Select instruction!");
@@ -914,7 +1056,6 @@
       Result = PN;
       break;
     }
-
     case Instruction::Shl:
     case Instruction::LShr:
     case Instruction::AShr:
@@ -960,7 +1101,6 @@
     case Instruction::Call: {  // Normal Call, C Calling Convention
       if (Oprnds.size() == 0)
         error("Invalid call instruction encountered!");
-
       Value *F = getValue(iType, Oprnds[0]);
 
       unsigned CallingConv = CallingConv::C;
@@ -1021,8 +1161,6 @@
       if (CallingConv) cast<CallInst>(Result)->setCallingConv(CallingConv);
       break;
     }
-    case 56:                     // Invoke with encoded CC
-    case 57:                     // Invoke Fast CC
     case Instruction::Invoke: {  // Invoke C CC
       if (Oprnds.size() < 3)
         error("Invalid invoke instruction!");
@@ -1038,14 +1176,8 @@
 
       std::vector<Value *> Params;
       BasicBlock *Normal, *Except;
-      unsigned CallingConv = CallingConv::C;
-
-      if (Opcode == 57)
-        CallingConv = CallingConv::Fast;
-      else if (Opcode == 56) {
-        CallingConv = Oprnds.back();
-        Oprnds.pop_back();
-      }
+      unsigned CallingConv = Oprnds.back();
+      Oprnds.pop_back();
 
       if (!FTy->isVarArg()) {
         Normal = getBasicBlock(Oprnds[1]);
@@ -1486,12 +1618,12 @@
 // We can't use that function because of that functions argument requirements.
 // This function only deals with the subset of opcodes that are applicable to
 // constant expressions and is therefore simpler than upgradeInstrOpcodes.
-inline unsigned BytecodeReader::upgradeCEOpcodes(
-  unsigned Opcode, const std::vector<Constant*> &ArgVec
+inline Constant *BytecodeReader::upgradeCEOpcodes(
+  unsigned &Opcode, const std::vector<Constant*> &ArgVec, unsigned TypeID
 ) {
   // Determine if no upgrade necessary
   if (!hasSignlessDivRem && !hasSignlessShrCastSetcc)
-    return Opcode;
+    return 0;
 
   // If this is bytecode version 6, that only had signed Rem and Div 
   // instructions, then we must compensate for those two instructions only.
@@ -1587,9 +1719,25 @@
     case 26: // GetElementPtr
       Opcode = Instruction::GetElementPtr;
       break;
-    case 28: // Cast
-      Opcode = Instruction::Cast;
+    case 28: { // Cast
+      const Type *Ty = getType(TypeID);
+      if (Ty == Type::BoolTy) {
+        // The previous definition of cast to bool was a compare against zero. 
+        // We have to retain that semantic so we do it here.
+        Opcode = Instruction::SetEQ;
+        return ConstantExpr::get(Instruction::SetEQ, ArgVec[0], 
+                             Constant::getNullValue(ArgVec[0]->getType()));
+      } else if (ArgVec[0]->getType()->isFloatingPoint() && 
+                 isa<PointerType>(Ty)) {
+        // Upgrade what is now an illegal cast (fp -> ptr) into two casts,
+        // fp -> ui, and ui -> ptr 
+        Constant *CE = ConstantExpr::getFPToUI(ArgVec[0], Type::ULongTy);
+        return ConstantExpr::getIntToPtr(CE, Ty);
+      } else {
+        Opcode = CastInst::getCastOpcode(ArgVec[0], Ty);
+      }
       break;
+    }
     case 30: // Shl
       Opcode = Instruction::Shl;
       break;
@@ -1612,7 +1760,7 @@
       Opcode = Instruction::ShuffleVector;
       break;
   }
-  return Opcode;
+  return 0;
 }
 
 /// Parse a single constant value
@@ -1663,19 +1811,22 @@
     }
 
     // Handle backwards compatibility for the opcode numbers
-    Opcode = upgradeCEOpcodes(Opcode, ArgVec);
+    if (Constant *C = upgradeCEOpcodes(Opcode, ArgVec, TypeID)) {
+      if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, C);
+      return C;
+    }
 
     // Construct a ConstantExpr of the appropriate kind
     if (isExprNumArgs == 1) {           // All one-operand expressions
-      if (Opcode != Instruction::Cast)
+      if (!Instruction::isCast(Opcode))
         error("Only cast instruction has one argument for ConstantExpr");
 
-      Constant* Result = ConstantExpr::getCast(ArgVec[0], getType(TypeID));
+      Constant *Result = ConstantExpr::getCast(ArgVec[0], getType(TypeID));
       if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
       return Result;
     } else if (Opcode == Instruction::GetElementPtr) { // GetElementPtr
       std::vector<Constant*> IdxList(ArgVec.begin()+1, ArgVec.end());
-      Constant* Result = ConstantExpr::getGetElementPtr(ArgVec[0], IdxList);
+      Constant *Result = ConstantExpr::getGetElementPtr(ArgVec[0], IdxList);
       if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
       return Result;
     } else if (Opcode == Instruction::Select) {
diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h
index 37c4324..3ede6eb 100644
--- a/lib/Bytecode/Reader/Reader.h
+++ b/lib/Bytecode/Reader/Reader.h
@@ -230,19 +230,20 @@
   /// the instruction. This function handles all *abnormal* cases for 
   /// instruction generation based on obsolete opcode values. The normal cases 
   /// are handled by the ParseInstruction function.
-  Instruction* upgradeInstrOpcodes(
+  Instruction *upgradeInstrOpcodes(
     unsigned &opcode,   ///< The old opcode, possibly updated by this function
     std::vector<unsigned> &Oprnds, ///< The operands to the instruction
     unsigned &iType,    ///< The type code from the bytecode file
-    const Type* InstTy, ///< The type of the instruction
-    BasicBlock* BB      ///< The basic block to insert into, if we need to
+    const Type *InstTy, ///< The type of the instruction
+    BasicBlock *BB      ///< The basic block to insert into, if we need to
   );
 
   /// @brief Convert previous opcode values for ConstantExpr into the current 
   /// value.
-  unsigned upgradeCEOpcodes(
-    unsigned Opcode,                      ///< Opcode read from bytecode
-    const std::vector<Constant*> &ArgVec  ///< Arguments of instruction
+  Constant *upgradeCEOpcodes(
+    unsigned &Opcode,                     ///< Opcode read from bytecode
+    const std::vector<Constant*> &ArgVec, ///< Arguments of instruction
+    unsigned TypeID                       ///< TypeID of the instruction type
   );
 
   /// @brief Parse a single instruction.
diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp
index dbc7896..f2ded65 100644
--- a/lib/Bytecode/Writer/Writer.cpp
+++ b/lib/Bytecode/Writer/Writer.cpp
@@ -291,7 +291,7 @@
   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
     // FIXME: Encoding of constant exprs could be much more compact!
     assert(CE->getNumOperands() > 0 && "ConstantExpr with 0 operands");
-    assert(CE->getNumOperands() != 1 || CE->getOpcode() == Instruction::Cast);
+    assert(CE->getNumOperands() != 1 || CE->isCast());
     output_vbr(1+CE->getNumOperands());   // flags as an expr
     output_vbr(CE->getOpcode());          // Put out the CE op code
 
@@ -446,8 +446,8 @@
   output_typeid(Type);                      // Result type
 
   unsigned NumArgs = I->getNumOperands();
-  output_vbr(NumArgs + (isa<CastInst>(I)  ||
-                        isa<VAArgInst>(I) || Opcode == 56 || Opcode == 58));
+  output_vbr(NumArgs + (isa<CastInst>(I)  || isa<InvokeInst>(I) ||
+                        isa<VAArgInst>(I) || Opcode == 58));
 
   if (!isa<GetElementPtrInst>(&I)) {
     for (unsigned i = 0; i < NumArgs; ++i) {
@@ -460,7 +460,7 @@
       int Slot = Table.getSlot(I->getType());
       assert(Slot != -1 && "Cast return type unknown?");
       output_typeid((unsigned)Slot);
-    } else if (Opcode == 56) {  // Invoke escape sequence
+    } else if (isa<InvokeInst>(I)) {  
       output_vbr(cast<InvokeInst>(I)->getCallingConv());
     } else if (Opcode == 58) {  // Call escape sequence
       output_vbr((cast<CallInst>(I)->getCallingConv() << 1) |
@@ -528,8 +528,8 @@
     // variable argument.
     NumFixedOperands = 3+NumParams;
   }
-  output_vbr(2 * I->getNumOperands()-NumFixedOperands +
-             unsigned(Opcode == 56 || Opcode == 58));
+  output_vbr(2 * I->getNumOperands()-NumFixedOperands + 
+      unsigned(Opcode == 58 || isa<InvokeInst>(I)));
 
   // The type for the function has already been emitted in the type field of the
   // instruction.  Just emit the slot # now.
@@ -551,12 +551,12 @@
     output_vbr((unsigned)Slot);
   }
   
-  // If this is the escape sequence for call, emit the tailcall/cc info.
-  if (Opcode == 58) {
+  if (isa<InvokeInst>(I)) {
+    // Emit the tail call/calling conv for invoke instructions
+    output_vbr(cast<InvokeInst>(I)->getCallingConv());
+  } else if (Opcode == 58) {
     const CallInst *CI = cast<CallInst>(I);
     output_vbr((CI->getCallingConv() << 1) | unsigned(CI->isTailCall()));
-  } else if (Opcode == 56) {    // Invoke escape sequence.
-    output_vbr(cast<InvokeInst>(I)->getCallingConv());
   }
 }
 
@@ -619,7 +619,7 @@
 }
 
 void BytecodeWriter::outputInstruction(const Instruction &I) {
-  assert(I.getOpcode() < 56 && "Opcode too big???");
+  assert(I.getOpcode() < 57 && "Opcode too big???");
   unsigned Opcode = I.getOpcode();
   unsigned NumOperands = I.getNumOperands();
 
@@ -639,12 +639,6 @@
     } else {
       Opcode = 58;      // Call escape sequence.
     }
-  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
-    if (II->getCallingConv() == CallingConv::Fast)
-      Opcode = 57;      // FastCC invoke.
-    else if (II->getCallingConv() != CallingConv::C)
-      Opcode = 56;      // Invoke escape sequence.
-
   } else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) {
     Opcode = 62;
   } else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) {
@@ -750,7 +744,7 @@
         if (Slots[NumOperands-1] > MaxOpSlot)
           MaxOpSlot = Slots[NumOperands-1];
       }
-    } else if (Opcode == 56) {
+    } else if (isa<InvokeInst>(I)) {
       // Invoke escape seq has at least 4 operands to encode.
       ++NumOperands;
     }