[llvm-commits] CVS: llvm/lib/VMCore/Verifier.cpp

Reid Spencer reid at x10sys.com
Sun Apr 1 00:23:14 PDT 2007



Changes in directory llvm/lib/VMCore:

Verifier.cpp updated: 1.197 -> 1.198
---
Log message:

For PR1297: http://llvm.org/PR1297 :
1. Clear up confusion between "GotBits" and "ExpectBits". GotBits is the
   type actually provided. ExpectedBits is the type expected for the
   intrinsics. Before this patch, it was reversed!
2. Implement checks for overloaded intrinsics. This involves computing the
   suffix expected and making sure the suffix matches the function name. It
   also includes some intrinsic-specific checks such as ensuring that the
   bswap parameter and result are the same width and an even number of bytes.


---
Diffs of the changes:  (+42 -7)

 Verifier.cpp |   49 ++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 42 insertions(+), 7 deletions(-)


Index: llvm/lib/VMCore/Verifier.cpp
diff -u llvm/lib/VMCore/Verifier.cpp:1.197 llvm/lib/VMCore/Verifier.cpp:1.198
--- llvm/lib/VMCore/Verifier.cpp:1.197	Wed Feb 14 21:39:18 2007
+++ llvm/lib/VMCore/Verifier.cpp	Sun Apr  1 02:22:57 2007
@@ -212,7 +212,7 @@
     void visitUserOp2(Instruction &I) { visitUserOp1(I); }
     void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
 
-    void VerifyIntrinsicPrototype(Function *F, ...);
+    void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, ...);
 
     void WriteValue(const Value *V) {
       if (!V) return;
@@ -961,12 +961,17 @@
 /// VerifyIntrinsicPrototype - TableGen emits calls to this function into
 /// Intrinsics.gen.  This implements a little state machine that verifies the
 /// prototype of intrinsics.
-void Verifier::VerifyIntrinsicPrototype(Function *F, ...) {
+void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, ...) {
   va_list VA;
   va_start(VA, F);
   
   const FunctionType *FTy = F->getFunctionType();
   
+  // For overloaded intrinsics, the Suffix of the function name must match the
+  // types of the arguments. This variable keeps track of the expected
+  // suffix, to be checked at the end.
+  std::string Suffix;
+
   // Note that "arg#0" is the return type.
   for (unsigned ArgNo = 0; 1; ++ArgNo) {
     int TypeID = va_arg(VA, int);
@@ -987,7 +992,7 @@
     }
     
     const Type *Ty;
-    if (ArgNo == 0) 
+    if (ArgNo == 0)
       Ty = FTy->getReturnType();
     else
       Ty = FTy->getParamType(ArgNo-1);
@@ -1001,10 +1006,12 @@
     }
 
     if (TypeID == Type::IntegerTyID) {
-      unsigned GotBits = (unsigned) va_arg(VA, int);
-      unsigned ExpectBits = cast<IntegerType>(Ty)->getBitWidth();
-      if (GotBits != ExpectBits) {
-        std::string bitmsg = " Expecting " + utostr(ExpectBits) + " but got " +
+      unsigned ExpectedBits = (unsigned) va_arg(VA, int);
+      unsigned GotBits = cast<IntegerType>(Ty)->getBitWidth();
+      if (ExpectedBits == 0) {
+        Suffix += ".i" + utostr(GotBits);
+      } else if (GotBits != ExpectedBits) {
+        std::string bitmsg = " Expected " + utostr(ExpectedBits) + " but got "+
                              utostr(GotBits) + " bits.";
         if (ArgNo == 0)
           CheckFailed("Intrinsic prototype has incorrect integer result width!"
@@ -1014,6 +1021,21 @@
                       "incorrect integer width!" + bitmsg, F);
         break;
       }
+      // Check some constraints on various intrinsics.
+      switch (ID) {
+        default: break; // Not everything needs to be checked.
+        case Intrinsic::bswap:
+          if (GotBits < 16 || GotBits % 16 != 0)
+            CheckFailed("Intrinsic requires even byte width argument", F);
+          if (ArgNo == 1) {
+            unsigned ResultBits = 
+              cast<IntegerType>(FTy->getReturnType())->getBitWidth();
+            if (GotBits != ResultBits)
+              CheckFailed("Intrinsic requires parameter and result bit "
+                          "widths to match", F);
+          }
+          break;
+      }
     } else if (TypeID == Type::VectorTyID) {
       // If this is a packed argument, verify the number and type of elements.
       const VectorType *PTy = cast<VectorType>(Ty);
@@ -1042,6 +1064,19 @@
   }
 
   va_end(VA);
+
+  // If we computed a Suffix then the intrinsic is overloaded and we need to 
+  // make sure that the name of the function is correct. We add the suffix to
+  // the name of the intrinsic and compare against the given function name. If
+  // they are not the same, the function name is invalid. This ensures that
+  // overloading of intrinsics uses a sane and consistent naming convention.
+  if (!Suffix.empty()) {
+    std::string Name(Intrinsic::getName(ID));
+    if (Name + Suffix != F->getName())
+      CheckFailed("Overloaded intrinsic has incorrect suffix: '" +
+                  F->getName().substr(Name.length()) + "'. It should be '" +
+                  Suffix + "'", F);
+  }
 }
 
 






More information about the llvm-commits mailing list