[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 5c82de62dfd1a320351e8f856923b64c8e0a8f4f..ac7cc9b74ab95f1764bf91bebc9165dc6827c62f 100644 (file)
@@ -156,7 +156,10 @@ namespace CallingConv {
     HHVM = 81,
 
     /// \brief HHVM calling convention for invoking C/C++ helpers.
     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
 
   };
 } // End CallingConv namespace
 
index a97c196ced0dfd2319e1ad1741243b9a50c9f92b..b8e22af4bfe3d72f92cc5e781986c18a62df0851 100644 (file)
@@ -61,10 +61,12 @@ private:
   /*
    * Value::SubclassData
    *
   /*
    * 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.
    */
 
   /// 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 {
   /// 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) {
   }
   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.
   }
 
   /// @brief Return the attribute list for this Function.
index 58d5221dea89abbaf4ec7400bc0019ca44660e9e..509753bb96c246eccd05246861d220b1c925a1a5 100644 (file)
@@ -1558,8 +1558,10 @@ public:
     return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 2);
   }
   void setCallingConv(CallingConv::ID CC) {
     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) |
     setInstructionSubclassData((getSubclassDataFromInstruction() & 3) |
-                               (static_cast<unsigned>(CC) << 2));
+                               (ID << 2));
   }
 
   /// getAttributes - Return the parameter attributes for this call.
   }
 
   /// getAttributes - Return the parameter attributes for this call.
@@ -3436,7 +3438,9 @@ public:
     return static_cast<CallingConv::ID>(getSubclassDataFromInstruction());
   }
   void setCallingConv(CallingConv::ID CC) {
     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.
   }
 
   /// getAttributes - Return the parameter attributes for this invoke.
index 318b2368cd9afbbf34c0246d3380ab79e055d36f..58b9b4a189ab16cbbd92257dac1174d141f1e903 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 *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);
 
 
       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));
       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);
       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;
     }
       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(
       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;
       CallInst::TailCallKind TCK = CallInst::TCK_None;
       if (CCInfo & 1)
         TCK = CallInst::TCK_Tail;
index 53f061da00d8b8fd859b31f7b0f3a866507f649b..dcec8dc17bd6f0e8e00478febf267d4b5cdfbb3b 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()
 ; 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()
 
 ; Functions -- ret attrs (Return attributes)
 declare zeroext i64 @f.zeroext()
index d75cbca7fb1b147e7471e504c80cec600458106f..86b662000316b02f81307581e6abfa97b2d17719 100644 (file)
Binary files a/test/Bitcode/compatibility-3.6.ll.bc and b/test/Bitcode/compatibility-3.6.ll.bc differ
index af1eb5d297fa367270aebe2f8dd10b7b7a5847bc..da1471e84ef7d4c7f814430bcf1076e682ec87d4 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()
 ; 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()
 
 ; Functions -- ret attrs (Return attributes)
 declare zeroext i64 @f.zeroext()
index 1bd87c08d04ae1a53d9fc5418bd68bd44923aada..14c0f1a6d6f1bda8998e601301911f825864703d 100644 (file)
Binary files a/test/Bitcode/compatibility-3.7.ll.bc and b/test/Bitcode/compatibility-3.7.ll.bc differ
index e18c239d53014c1ab0ce5aaa2655c139102c5497..4c6349c803cf2ddfc6cfb712b592d99507a6f14f 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()
 ; 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()
 
 ; Functions -- ret attrs (Return attributes)
 declare zeroext i64 @f.zeroext()
index 01190d74c3486c7dd63f9c2c86cea0ce17fe7cc1..6a4b8885847a54a6f022fcda02fca234ba9f6dcc 100644 (file)
@@ -3,16 +3,16 @@
 
 ; Check that musttail and tail roundtrip.
 
 
 ; 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
 }
 
   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
 }
   ret void
 }