Print out inline asm strings
[oota-llvm.git] / lib / VMCore / Verifier.cpp
index 2005dbf584522e83b55487290c5e98b1d9667e02..36462388b380be68b6bdc32284378758b6735bfa 100644 (file)
@@ -1,10 +1,10 @@
 //===-- Verifier.cpp - Implement the Module Verifier -------------*- C++ -*-==//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file defines the function verifier interface, that can be used for some
@@ -41,6 +41,7 @@
 
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Assembly/Writer.h"
+#include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/Pass.h"
 #include "llvm/Module.h"
@@ -53,7 +54,7 @@
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/InstVisitor.h"
-#include "Support/STLExtras.h"
+#include "llvm/ADT/STLExtras.h"
 #include <algorithm>
 #include <iostream>
 #include <sstream>
@@ -67,22 +68,28 @@ namespace {  // Anonymous namespace for class
     VerifierFailureAction action;
                           // What to do if verification fails.
     Module *Mod;          // Module we are verifying right now
-    DominatorSet *DS;     // Dominator set, caution can be null!
+    ETForest *EF;     // ET-Forest, caution can be null!
     std::stringstream msgs;  // A stringstream to collect messages
 
-    Verifier() 
+    /// InstInThisBlock - when verifying a basic block, keep track of all of the
+    /// instructions we have seen so far.  This allows us to do efficient
+    /// dominance checks for the case when an instruction has an operand that is
+    /// an instruction in the same block.
+    std::set<Instruction*> InstsInThisBlock;
+
+    Verifier()
         : Broken(false), RealPass(true), action(AbortProcessAction),
-          DS(0), msgs( std::ios_base::app | std::ios_base::out ) {}
+          EF(0), msgs( std::ios::app | std::ios::out ) {}
     Verifier( VerifierFailureAction ctn )
-        : Broken(false), RealPass(true), action(ctn), DS(0), 
-          msgs( std::ios_base::app | std::ios_base::out ) {}
-    Verifier(bool AB ) 
-        : Broken(false), RealPass(true), 
-          action( AB ? AbortProcessAction : PrintMessageAction), DS(0), 
-          msgs( std::ios_base::app | std::ios_base::out ) {}
-    Verifier(DominatorSet &ds) 
+        : Broken(false), RealPass(true), action(ctn), EF(0),
+          msgs( std::ios::app | std::ios::out ) {}
+    Verifier(bool AB )
+        : Broken(false), RealPass(true),
+          action( AB ? AbortProcessAction : PrintMessageAction), EF(0),
+          msgs( std::ios::app | std::ios::out ) {}
+    Verifier(ETForest &ef)
       : Broken(false), RealPass(false), action(PrintMessageAction),
-        DS(&ds), msgs( std::ios_base::app | std::ios_base::out ) {}
+        EF(&ef), msgs( std::ios::app | std::ios::out ) {}
 
 
     bool doInitialization(Module &M) {
@@ -99,8 +106,9 @@ namespace {  // Anonymous namespace for class
 
     bool runOnFunction(Function &F) {
       // Get dominator information if we are being run by PassManager
-      if (RealPass) DS = &getAnalysis<DominatorSet>();
+      if (RealPass) EF = &getAnalysis<ETForest>();
       visit(F);
+      InstsInThisBlock.clear();
 
       // If this is a real pass, in a pass manager, we must abort before
       // returning back to the pass manager, or else the pass manager may try to
@@ -120,8 +128,9 @@ namespace {  // Anonymous namespace for class
         if (I->isExternal()) visitFunction(*I);
       }
 
-      for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
-        visitGlobalValue(*I);
+      for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 
+           I != E; ++I)
+        visitGlobalVariable(*I);
 
       // If the module is broken, abort at this time.
       abortIfBroken();
@@ -131,7 +140,7 @@ namespace {  // Anonymous namespace for class
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesAll();
       if (RealPass)
-        AU.addRequired<DominatorSet>();
+        AU.addRequired<ETForest>();
     }
 
     /// abortIfBroken - If the module is broken and we are supposed to abort on
@@ -164,12 +173,14 @@ namespace {  // Anonymous namespace for class
     // Verification methods...
     void verifySymbolTable(SymbolTable &ST);
     void visitGlobalValue(GlobalValue &GV);
+    void visitGlobalVariable(GlobalVariable &GV);
     void visitFunction(Function &F);
     void visitBasicBlock(BasicBlock &BB);
     void visitPHINode(PHINode &PN);
     void visitBinaryOperator(BinaryOperator &B);
     void visitShiftInst(ShiftInst &SI);
-    void visitVANextInst(VANextInst &VAN) { visitInstruction(VAN); }
+    void visitExtractElementInst(ExtractElementInst &EI);
+    void visitInsertElementInst(InsertElementInst &EI);
     void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
     void visitCallInst(CallInst &CI);
     void visitGetElementPtrInst(GetElementPtrInst &GEP);
@@ -215,7 +226,7 @@ namespace {  // Anonymous namespace for class
       Broken = true;
     }
 
-    void CheckFailed( const std::string& Message, const Value* V1, 
+    void CheckFailed( const std::string& Message, const Value* V1,
                       const Type* T2, const Value* V3 = 0 ) {
       msgs << Message << "\n";
       WriteValue(V1);
@@ -255,12 +266,22 @@ void Verifier::visitGlobalValue(GlobalValue &GV) {
   }
 }
 
+void Verifier::visitGlobalVariable(GlobalVariable &GV) {
+  if (GV.hasInitializer())
+    Assert1(GV.getInitializer()->getType() == GV.getType()->getElementType(),
+            "Global variable initializer type does not match global "
+            "variable type!", &GV);
+
+  visitGlobalValue(GV);
+}
+
+
 // verifySymbolTable - Verify that a function or module symbol table is ok
 //
 void Verifier::verifySymbolTable(SymbolTable &ST) {
 
   // Loop over all of the values in all type planes in the symbol table.
-  for (SymbolTable::plane_const_iterator PI = ST.plane_begin(), 
+  for (SymbolTable::plane_const_iterator PI = ST.plane_begin(),
        PE = ST.plane_end(); PI != PE; ++PI)
     for (SymbolTable::value_const_iterator VI = PI->second.begin(),
          VE = PI->second.end(); VI != VE; ++VI) {
@@ -276,7 +297,10 @@ void Verifier::verifySymbolTable(SymbolTable &ST) {
 // visitFunction - Verify that a function is ok.
 //
 void Verifier::visitFunction(Function &F) {
-  // Check function arguments...
+  Assert1(!F.isVarArg() || F.getCallingConv() == CallingConv::C,
+          "Varargs functions must have C calling conventions!", &F);
+
+  // Check function arguments.
   const FunctionType *FT = F.getFunctionType();
   unsigned NumArgs = F.getArgumentList().size();
 
@@ -289,12 +313,12 @@ void Verifier::visitFunction(Function &F) {
 
   // Check that the argument values match the function type for this function...
   unsigned i = 0;
-  for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++i) {
+  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I, ++i) {
     Assert2(I->getType() == FT->getParamType(i),
             "Argument value does not match function argument type!",
             I, FT->getParamType(i));
     // Make sure no aggregates are passed by value.
-    Assert1(I->getType()->isFirstClassType(), 
+    Assert1(I->getType()->isFirstClassType(),
             "Functions cannot take aggregates as arguments by value!", I);
    }
 
@@ -312,12 +336,17 @@ void Verifier::visitFunction(Function &F) {
 // verifyBasicBlock - Verify that a basic block is well formed...
 //
 void Verifier::visitBasicBlock(BasicBlock &BB) {
+  InstsInThisBlock.clear();
+
+  // Ensure that basic blocks have terminators!
+  Assert1(BB.getTerminator(), "Basic Block does not have terminator!", &BB);
+
   // Check constraints that this basic block imposes on all of the PHI nodes in
   // it.
   if (isa<PHINode>(BB.front())) {
     std::vector<BasicBlock*> Preds(pred_begin(&BB), pred_end(&BB));
     std::sort(Preds.begin(), Preds.end());
-    PHINode *PN; 
+    PHINode *PN;
     for (BasicBlock::iterator I = BB.begin(); (PN = dyn_cast<PHINode>(I));++I) {
 
       // Ensure that PHI nodes have at least one entry!
@@ -327,7 +356,7 @@ void Verifier::visitBasicBlock(BasicBlock &BB) {
       Assert1(PN->getNumIncomingValues() == Preds.size(),
               "PHINode should have one entry for each predecessor of its "
               "parent basic block!", PN);
-      
+
       // Get and sort all incoming values in the PHI node...
       std::vector<std::pair<BasicBlock*, Value*> > Values;
       Values.reserve(PN->getNumIncomingValues());
@@ -335,7 +364,7 @@ void Verifier::visitBasicBlock(BasicBlock &BB) {
         Values.push_back(std::make_pair(PN->getIncomingBlock(i),
                                         PN->getIncomingValue(i)));
       std::sort(Values.begin(), Values.end());
-      
+
       for (unsigned i = 0, e = Values.size(); i != e; ++i) {
         // Check to make sure that if there is more than one entry for a
         // particular basic block in this PHI node, that the incoming values are
@@ -346,18 +375,15 @@ void Verifier::visitBasicBlock(BasicBlock &BB) {
                 "PHI node has multiple entries for the same basic block with "
                 "different incoming values!", PN, Values[i].first,
                 Values[i].second, Values[i-1].second);
-        
+
         // Check to make sure that the predecessors and PHI node entries are
         // matched up.
         Assert3(Values[i].first == Preds[i],
                 "PHI node entries do not match predecessors!", PN,
-                Values[i].first, Preds[i]);        
+                Values[i].first, Preds[i]);
       }
     }
   }
-
-  // Ensure that basic blocks have terminators!
-  Assert1(BB.getTerminator(), "Basic Block does not have terminator!", &BB);
 }
 
 void Verifier::visitTerminatorInst(TerminatorInst &I) {
@@ -370,9 +396,9 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) {
 void Verifier::visitReturnInst(ReturnInst &RI) {
   Function *F = RI.getParent()->getParent();
   if (RI.getNumOperands() == 0)
-    Assert1(F->getReturnType() == Type::VoidTy,
-            "Function returns no value, but ret instruction found that does!",
-            &RI);
+    Assert2(F->getReturnType() == Type::VoidTy,
+            "Found return instr that returns void in Function of non-void "
+            "return type!", &RI, F->getReturnType());
   else
     Assert2(F->getReturnType() == RI.getOperand(0)->getType(),
             "Function return type does not match operand "
@@ -401,6 +427,7 @@ void Verifier::visitSelectInst(SelectInst &SI) {
           "Select values must have identical types!", &SI);
   Assert1(SI.getTrueValue()->getType() == SI.getType(),
           "Select values must have same type as select instruction!", &SI);
+  visitInstruction(SI);
 }
 
 
@@ -474,7 +501,9 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
   // Check that logical operators are only used with integral operands.
   if (B.getOpcode() == Instruction::And || B.getOpcode() == Instruction::Or ||
       B.getOpcode() == Instruction::Xor) {
-    Assert1(B.getType()->isIntegral(),
+    Assert1(B.getType()->isIntegral() ||
+            (isa<PackedType>(B.getType()) && 
+             cast<PackedType>(B.getType())->getElementType()->isIntegral()),
             "Logical operators only work with integral types!", &B);
     Assert1(B.getType() == B.getOperand(0)->getType(),
             "Logical operators must have same type for operands and result!",
@@ -488,10 +517,11 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) {
     Assert1(B.getType() == B.getOperand(0)->getType(),
             "Arithmetic operators must have same type for operands and result!",
             &B);
-    Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint(),
-            "Arithmetic operators must have integer or fp type!", &B);
+    Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint() ||
+            isa<PackedType>(B.getType()),
+            "Arithmetic operators must have integer, fp, or packed type!", &B);
   }
-  
+
   visitInstruction(B);
 }
 
@@ -505,6 +535,30 @@ void Verifier::visitShiftInst(ShiftInst &SI) {
   visitInstruction(SI);
 }
 
+void Verifier::visitExtractElementInst(ExtractElementInst &EI) {
+  Assert1(isa<PackedType>(EI.getOperand(0)->getType()),
+          "First operand to extractelement must be packed type!", &EI);
+  Assert1(EI.getOperand(1)->getType() == Type::UIntTy,
+          "Second operand to extractelement must be uint type!", &EI);
+  Assert1(EI.getType() == 
+          cast<PackedType>(EI.getOperand(0)->getType())->getElementType(),
+          "Extractelement return type must match "
+          "first operand element type!", &EI);
+  visitInstruction(EI);
+}
+
+void Verifier::visitInsertElementInst(InsertElementInst &IE) {
+  Assert1(isa<PackedType>(IE.getOperand(0)->getType()),
+          "First operand to insertelement must be packed type!", &IE);
+  Assert1(IE.getOperand(1)->getType() == 
+          cast<PackedType>(IE.getOperand(0)->getType())->getElementType(),
+          "Second operand to insertelement must match "
+          "first operand element type!", &IE);
+  Assert1(IE.getOperand(2)->getType() == Type::UIntTy,
+          "Third operand to insertelement must be uint type!", &IE);
+  visitInstruction(IE);
+}
+
 void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
   const Type *ElTy =
     GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(),
@@ -535,14 +589,14 @@ void Verifier::visitStoreInst(StoreInst &SI) {
 /// verifyInstruction - Verify that an instruction is well formed.
 ///
 void Verifier::visitInstruction(Instruction &I) {
-  BasicBlock *BB = I.getParent();  
+  BasicBlock *BB = I.getParent();
   Assert1(BB, "Instruction not embedded in basic block!", &I);
 
   if (!isa<PHINode>(I)) {   // Check that non-phi nodes are not self referential
     for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
          UI != UE; ++UI)
       Assert1(*UI != (User*)&I ||
-              !DS->dominates(&BB->getParent()->getEntryBlock(), BB),
+              !EF->dominates(&BB->getParent()->getEntryBlock(), BB),
               "Only PHI nodes may reference their own value!", &I);
   }
 
@@ -570,6 +624,7 @@ void Verifier::visitInstruction(Instruction &I) {
   for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
     // Check to make sure that the "address of" an intrinsic function is never
     // taken.
+    Assert1(I.getOperand(i) != 0, "Instruction has null operand!", &I);
     if (Function *F = dyn_cast<Function>(I.getOperand(i))) {
       Assert1(!F->isIntrinsic() || (i == 0 && isa<CallInst>(I)),
               "Cannot take the address of an intrinsic!", &I);
@@ -591,25 +646,26 @@ void Verifier::visitInstruction(Instruction &I) {
         else if (OpBlock == BB) {
           // If they are in the same basic block, make sure that the definition
           // comes before the use.
-          Assert2(DS->dominates(Op, &I) ||
-                  !DS->dominates(&BB->getParent()->getEntryBlock(), BB),
+          Assert2(InstsInThisBlock.count(Op) ||
+                  !EF->dominates(&BB->getParent()->getEntryBlock(), BB),
                   "Instruction does not dominate all uses!", Op, &I);
         }
 
         // Definition must dominate use unless use is unreachable!
-        Assert2(DS->dominates(OpBlock, BB) ||
-                !DS->dominates(&BB->getParent()->getEntryBlock(), BB),
+        Assert2(EF->dominates(OpBlock, BB) ||
+                !EF->dominates(&BB->getParent()->getEntryBlock(), BB),
                 "Instruction does not dominate all uses!", Op, &I);
       } else {
         // PHI nodes are more difficult than other nodes because they actually
         // "use" the value in the predecessor basic blocks they correspond to.
         BasicBlock *PredBB = cast<BasicBlock>(I.getOperand(i+1));
-        Assert2(DS->dominates(OpBlock, PredBB) ||
-                !DS->dominates(&BB->getParent()->getEntryBlock(), PredBB),
+        Assert2(EF->dominates(OpBlock, PredBB) ||
+                !EF->dominates(&BB->getParent()->getEntryBlock(), PredBB),
                 "Instruction does not dominate all uses!", Op, &I);
       }
     }
   }
+  InstsInThisBlock.insert(&I);
 }
 
 /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
@@ -627,10 +683,10 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
     Assert1(CI.getParent()->getParent()->getFunctionType()->isVarArg(),
             "llvm.va_start intrinsic may only occur in function with variable"
             " args!", &CI);
-    NumArgs = 0;
+    NumArgs = 1;
     break;
   case Intrinsic::vaend:          NumArgs = 1; break;
-  case Intrinsic::vacopy:         NumArgs = 1; break;
+  case Intrinsic::vacopy:         NumArgs = 2; break;
 
   case Intrinsic::returnaddress:
   case Intrinsic::frameaddress:
@@ -687,18 +743,194 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
     break;
   }
 
-  case Intrinsic::isunordered:
+  case Intrinsic::isunordered_f32:
+    Assert1(FT->getNumParams() == 2,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == Type::BoolTy,
+            "Return type is not bool!", IF);
+    Assert1(FT->getParamType(0) == FT->getParamType(1),
+            "Arguments must be of the same type!", IF);
+    Assert1(FT->getParamType(0) == Type::FloatTy,
+            "Arguments must be a 32-bit floating point type!", IF);
+    NumArgs = 2;
+    break;
+
+  case Intrinsic::isunordered_f64:
     Assert1(FT->getNumParams() == 2,
             "Illegal # arguments for intrinsic function!", IF);
     Assert1(FT->getReturnType() == Type::BoolTy,
             "Return type is not bool!", IF);
     Assert1(FT->getParamType(0) == FT->getParamType(1),
             "Arguments must be of the same type!", IF);
-    Assert1(FT->getParamType(0)->isFloatingPoint(),
-            "Argument is not a floating point type!", IF);
+    Assert1(FT->getParamType(0) == Type::DoubleTy,
+            "Argument is not a 64-bit floating point type!", IF);
     NumArgs = 2;
     break;
 
+  case Intrinsic::readcyclecounter:
+    Assert1(FT->getNumParams() == 0,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == Type::ULongTy,
+            "Return type is not ulong!", IF);
+    NumArgs = 0;
+    break;
+
+  case Intrinsic::bswap_i16:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getReturnType() == Type::UShortTy,
+            "Return type is not ushort!", IF);
+    NumArgs = 1;
+    break;    
+
+  case Intrinsic::bswap_i32:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getReturnType() == Type::UIntTy,
+            "Return type is not uint!", IF);
+    NumArgs = 1;
+    break;    
+
+  case Intrinsic::bswap_i64:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getReturnType() == Type::ULongTy,
+            "Return type is not ulong!", IF);
+    NumArgs = 1;
+    break;    
+    
+  case Intrinsic::ctpop_i8:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UByteTy,
+            "Argument is not ubyte!", IF);
+    NumArgs = 1;
+    break;
+
+  case Intrinsic::ctpop_i16:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UShortTy,
+            "Argument is not ushort!", IF);
+    NumArgs = 1;
+    break;
+
+  case Intrinsic::ctpop_i32:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF);
+    NumArgs = 1;
+    break;
+
+  case Intrinsic::ctpop_i64:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::ULongTy, "Argument is not ulong!", IF);
+    NumArgs = 1;
+    break;
+
+  case Intrinsic::ctlz_i8:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UByteTy, "Argument is not ubyte!", IF);
+    NumArgs = 1;
+    break;
+
+  case Intrinsic::ctlz_i16:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UShortTy,
+            "Argument is not ushort!", IF);
+    NumArgs = 1;
+    break;
+  case Intrinsic::ctlz_i32:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF);
+    NumArgs = 1;
+    break;
+  case Intrinsic::ctlz_i64:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::ULongTy, "Argument is not ulong!", IF);
+    NumArgs = 1;
+    break;
+  case Intrinsic::cttz_i8:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UByteTy, "Argument is not ubyte!", IF);
+    NumArgs = 1;
+    break;
+  case Intrinsic::cttz_i16:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UShortTy,
+            "Argument is not ushort!", IF);
+    NumArgs = 1;
+    break;
+  case Intrinsic::cttz_i32:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::UIntTy, "Argument is not uint!", IF);
+    NumArgs = 1;
+    break;
+  case Intrinsic::cttz_i64:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type does not match source type", IF);
+    Assert1(FT->getParamType(0) == Type::ULongTy, "Argument Is not ulong!", IF);
+    NumArgs = 1;
+    break;
+
+  case Intrinsic::sqrt_f32:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getParamType(0) == Type::FloatTy,
+            "Argument is not a 32-bit floating point type!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type is not the same as argument type!", IF);
+    NumArgs = 1;
+    break;
+
+  case Intrinsic::sqrt_f64:
+    Assert1(FT->getNumParams() == 1,
+            "Illegal # arguments for intrinsic function!", IF);
+    Assert1(FT->getParamType(0) == Type::DoubleTy,
+            "Argument is not a 64-bit floating point type!", IF);
+    Assert1(FT->getReturnType() == FT->getParamType(0),
+            "Return type is not the same as argument type!", IF);
+    NumArgs = 1;
+    break;
+
   case Intrinsic::setjmp:          NumArgs = 1; break;
   case Intrinsic::longjmp:         NumArgs = 2; break;
   case Intrinsic::sigsetjmp:       NumArgs = 2; break;
@@ -723,24 +955,27 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
   case Intrinsic::memcpy:          NumArgs = 4; break;
   case Intrinsic::memmove:         NumArgs = 4; break;
   case Intrinsic::memset:          NumArgs = 4; break;
-  case Intrinsic::alpha_ctlz:      NumArgs = 1; break;
-  case Intrinsic::alpha_cttz:      NumArgs = 1; break;
-  case Intrinsic::alpha_ctpop:     NumArgs = 1; break;
-  case Intrinsic::alpha_umulh:     NumArgs = 2; break;
-  case Intrinsic::alpha_vecop:     NumArgs = 4; break;
-  case Intrinsic::alpha_pup:       NumArgs = 3; break;
-  case Intrinsic::alpha_bytezap:   NumArgs = 2; break;
-  case Intrinsic::alpha_bytemanip: NumArgs = 3; break;
-  case Intrinsic::alpha_dfpbop:    NumArgs = 3; break;
-  case Intrinsic::alpha_dfpuop:    NumArgs = 2; break;
-  case Intrinsic::alpha_unordered: NumArgs = 2; break;
-  case Intrinsic::alpha_uqtodfp:   NumArgs = 2; break;
-  case Intrinsic::alpha_uqtosfp:   NumArgs = 2; break;
-  case Intrinsic::alpha_dfptosq:   NumArgs = 2; break;
-  case Intrinsic::alpha_sfptosq:   NumArgs = 2; break;
-
-  case Intrinsic::not_intrinsic: 
+
+  case Intrinsic::stacksave:
+    NumArgs = 0;
+    Assert1(CI.getType() == PointerType::get(Type::SByteTy),
+            "llvm.stacksave must return an sbyte*", &CI);
+    break;
+  case Intrinsic::stackrestore:
+    NumArgs = 1;
+    Assert1(CI.getOperand(1)->getType() == PointerType::get(Type::SByteTy),
+            "llvm.stackrestore must take an sbyte*", &CI);
+    Assert1(CI.getType() == Type::VoidTy,
+            "llvm.stackrestore return void", &CI);
+    break;
+  case Intrinsic::prefetch:        NumArgs = 3; break;
+  case Intrinsic::pcmarker:
+    NumArgs = 1;
+    Assert1(isa<Constant>(CI.getOperand(1)),
+            "First argument to llvm.pcmarker must be a constant!", &CI);
+    break;
+
+  case Intrinsic::not_intrinsic:
     assert(0 && "Invalid intrinsic!"); NumArgs = 0; break;
   }
 
@@ -759,11 +994,11 @@ FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) {
 }
 
 
-// verifyFunction - Create 
+// verifyFunction - Create
 bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
   Function &F = const_cast<Function&>(f);
   assert(!F.isExternal() && "Cannot verify external functions");
-  
+
   FunctionPassManager FPM(new ExistingModuleProvider(F.getParent()));
   Verifier *V = new Verifier(action);
   FPM.add(V);