[IR] Limit bits used for CallingConv::ID, update tests
authorVedant Kumar <vsk@apple.com>
Tue, 27 Oct 2015 21:17:06 +0000 (21:17 +0000)
committerVedant Kumar <vsk@apple.com>
Tue, 27 Oct 2015 21:17:06 +0000 (21:17 +0000)
Use 10 bits to represent calling convention ID's instead of 13, and
update the bitcode compatibility tests accordingly. We now error-out in
the bitcode reader when we see bad calling conv ID's.

Thanks to rnk and dexonsmith for feedback!

Differential Revision: http://reviews.llvm.org/D13826

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251452 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/CallingConv.h
include/llvm/IR/Function.h
include/llvm/IR/Instructions.h
lib/Bitcode/Reader/BitcodeReader.cpp
test/Bitcode/compatibility-3.6.ll
test/Bitcode/compatibility-3.6.ll.bc
test/Bitcode/compatibility-3.7.ll
test/Bitcode/compatibility-3.7.ll.bc
test/Bitcode/compatibility.ll
test/Bitcode/tailcall.ll

index 5c82de6..ac7cc9b 100644 (file)
@@ -156,7 +156,10 @@ namespace CallingConv {
     HHVM = 81,
 
     /// \brief HHVM calling convention for invoking C/C++ helpers.
-    HHVM_C = 82
+    HHVM_C = 82,
+
+    /// The highest possible calling convention ID. Must be some 2^k - 1.
+    MaxID = 1023
   };
 } // End CallingConv namespace
 
index a97c196..b8e22af 100644 (file)
@@ -61,10 +61,12 @@ private:
   /*
    * Value::SubclassData
    *
-   * bit 0  : HasLazyArguments
-   * bit 1  : HasPrefixData
-   * bit 2  : HasPrologueData
-   * bit 3-6: CallingConvention
+   * bit 0      : HasLazyArguments
+   * bit 1      : HasPrefixData
+   * bit 2      : HasPrologueData
+   * bit 3      : [reserved]
+   * bits 4-13  : CallingConvention
+   * bits 14-15 : [reserved]
    */
 
   /// Bits from GlobalObject::GlobalObjectSubclassData.
@@ -158,11 +160,13 @@ public:
   /// calling convention of this function.  The enum values for the known
   /// calling conventions are defined in CallingConv.h.
   CallingConv::ID getCallingConv() const {
-    return static_cast<CallingConv::ID>(getSubclassDataFromValue() >> 3);
+    return static_cast<CallingConv::ID>((getSubclassDataFromValue() >> 4) &
+                                        CallingConv::MaxID);
   }
   void setCallingConv(CallingConv::ID CC) {
-    setValueSubclassData((getSubclassDataFromValue() & 7) |
-                         (static_cast<unsigned>(CC) << 3));
+    auto ID = static_cast<unsigned>(CC);
+    assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention");
+    setValueSubclassData((getSubclassDataFromValue() & 0xc00f) | (ID << 4));
   }
 
   /// @brief Return the attribute list for this Function.
index 58d5221..509753b 100644 (file)
@@ -1558,8 +1558,10 @@ public:
     return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 2);
   }
   void setCallingConv(CallingConv::ID CC) {
+    auto ID = static_cast<unsigned>(CC);
+    assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention");
     setInstructionSubclassData((getSubclassDataFromInstruction() & 3) |
-                               (static_cast<unsigned>(CC) << 2));
+                               (ID << 2));
   }
 
   /// getAttributes - Return the parameter attributes for this call.
@@ -3436,7 +3438,9 @@ public:
     return static_cast<CallingConv::ID>(getSubclassDataFromInstruction());
   }
   void setCallingConv(CallingConv::ID CC) {
-    setInstructionSubclassData(static_cast<unsigned>(CC));
+    auto ID = static_cast<unsigned>(CC);
+    assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention");
+    setInstructionSubclassData(ID);
   }
 
   /// getAttributes - Return the parameter attributes for this invoke.
index 318b236..58b9b4a 100644 (file)
@@ -3443,11 +3443,14 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
       auto *FTy = dyn_cast<FunctionType>(Ty);
       if (!FTy)
         return error("Invalid type for value");
+      auto CC = static_cast<CallingConv::ID>(Record[1]);
+      if (CC & ~CallingConv::MaxID)
+        return error("Invalid calling convention ID");
 
       Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage,
                                         "", TheModule);
 
-      Func->setCallingConv(static_cast<CallingConv::ID>(Record[1]));
+      Func->setCallingConv(CC);
       bool isProto = Record[2];
       uint64_t RawLinkage = Record[3];
       Func->setLinkage(getDecodedLinkage(RawLinkage));
@@ -4580,8 +4583,8 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
       I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops, OperandBundles);
       OperandBundles.clear();
       InstructionList.push_back(I);
-      cast<InvokeInst>(I)
-          ->setCallingConv(static_cast<CallingConv::ID>(~(1U << 13) & CCInfo));
+      cast<InvokeInst>(I)->setCallingConv(
+          static_cast<CallingConv::ID>(CallingConv::MaxID & CCInfo));
       cast<InvokeInst>(I)->setAttributes(PAL);
       break;
     }
@@ -4965,7 +4968,7 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
       OperandBundles.clear();
       InstructionList.push_back(I);
       cast<CallInst>(I)->setCallingConv(
-          static_cast<CallingConv::ID>((~(1U << 14) & CCInfo) >> 1));
+          static_cast<CallingConv::ID>((0x7ff & CCInfo) >> 1));
       CallInst::TailCallKind TCK = CallInst::TCK_None;
       if (CCInfo & 1)
         TCK = CallInst::TCK_Tail;
index 53f061d..dcec8dc 100644 (file)
@@ -375,8 +375,8 @@ declare cc80 void @f.cc80()
 ; CHECK: declare x86_vectorcallcc void @f.cc80()
 declare x86_vectorcallcc void @f.x86_vectorcallcc()
 ; CHECK: declare x86_vectorcallcc void @f.x86_vectorcallcc()
-declare cc8191 void @f.cc8191()
-; CHECK: declare cc8191 void @f.cc8191()
+declare cc1023 void @f.cc1023()
+; CHECK: declare cc1023 void @f.cc1023()
 
 ; Functions -- ret attrs (Return attributes)
 declare zeroext i64 @f.zeroext()
index d75cbca..86b6620 100644 (file)
Binary files a/test/Bitcode/compatibility-3.6.ll.bc and b/test/Bitcode/compatibility-3.6.ll.bc differ
index af1eb5d..da1471e 100644 (file)
@@ -375,8 +375,8 @@ declare cc80 void @f.cc80()
 ; CHECK: declare x86_vectorcallcc void @f.cc80()
 declare x86_vectorcallcc void @f.x86_vectorcallcc()
 ; CHECK: declare x86_vectorcallcc void @f.x86_vectorcallcc()
-declare cc8191 void @f.cc8191()
-; CHECK: declare cc8191 void @f.cc8191()
+declare cc1023 void @f.cc1023()
+; CHECK: declare cc1023 void @f.cc1023()
 
 ; Functions -- ret attrs (Return attributes)
 declare zeroext i64 @f.zeroext()
index 1bd87c0..14c0f1a 100644 (file)
Binary files a/test/Bitcode/compatibility-3.7.ll.bc and b/test/Bitcode/compatibility-3.7.ll.bc differ
index e18c239..4c6349c 100644 (file)
@@ -377,8 +377,8 @@ declare cc80 void @f.cc80()
 ; CHECK: declare x86_vectorcallcc void @f.cc80()
 declare x86_vectorcallcc void @f.x86_vectorcallcc()
 ; CHECK: declare x86_vectorcallcc void @f.x86_vectorcallcc()
-declare cc8191 void @f.cc8191()
-; CHECK: declare cc8191 void @f.cc8191()
+declare cc1023 void @f.cc1023()
+; CHECK: declare cc1023 void @f.cc1023()
 
 ; Functions -- ret attrs (Return attributes)
 declare zeroext i64 @f.zeroext()
index 01190d7..6a4b888 100644 (file)
@@ -3,16 +3,16 @@
 
 ; Check that musttail and tail roundtrip.
 
-declare cc8191 void @t1_callee()
-define cc8191 void @t1() {
-; CHECK: tail call cc8191 void @t1_callee()
-  tail call cc8191 void @t1_callee()
+declare cc1023 void @t1_callee()
+define cc1023 void @t1() {
+; CHECK: tail call cc1023 void @t1_callee()
+  tail call cc1023 void @t1_callee()
   ret void
 }
 
-declare cc8191 void @t2_callee()
-define cc8191 void @t2() {
-; CHECK: musttail call cc8191 void @t2_callee()
-  musttail call cc8191 void @t2_callee()
+declare cc1023 void @t2_callee()
+define cc1023 void @t2() {
+; CHECK: musttail call cc1023 void @t2_callee()
+  musttail call cc1023 void @t2_callee()
   ret void
 }