[BitcodeReader] Infer the correct runtime preemption for GlobalValue
authorSteven Wu <stevenwu@apple.com>
Mon, 9 Jul 2018 16:52:05 +0000 (16:52 +0000)
committerSteven Wu <stevenwu@apple.com>
Mon, 9 Jul 2018 16:52:05 +0000 (16:52 +0000)
Summary:
To allow bitcode built by old compiler to pass the current verifer,
BitcodeReader needs to auto infer the correct runtime preemption from
linkage and visibility for GlobalValues.

Since llvm-6.0 bitcode already contains the new field but can be
incorrect in some cases, the attribute needs to be recomputed all the
time in BitcodeReader. This will make all the GVs has dso_local marked
correctly if read from bitcode, and it should still allow the verifier
to catch mistakes in optimization passes.

This should fix PR38009.

Reviewers: sfertile, vsk

Reviewed By: vsk

Subscribers: dexonsmith, llvm-commits

Differential Revision: https://reviews.llvm.org/D49039

llvm-svn: 336560

llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/test/Bitcode/Inputs/infer_dso_local.bc [new file with mode: 0644]
llvm/test/Bitcode/infer_dso_local.ll [new file with mode: 0644]

index b0e0407..c45b441 100644 (file)
@@ -2831,6 +2831,13 @@ Error BitcodeReader::parseComdatRecord(ArrayRef<uint64_t> Record) {
   return Error::success();
 }
 
+static void inferDSOLocal(GlobalValue *GV) {
+  // infer dso_local from linkage and visibility if it is not encoded.
+  if (GV->hasLocalLinkage() ||
+      (!GV->hasDefaultVisibility() && !GV->hasExternalWeakLinkage()))
+    GV->setDSOLocal(true);
+}
+
 Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
   // v1: [pointer type, isconst, initid, linkage, alignment, section,
   // visibility, threadlocal, unnamed_addr, externally_initialized,
@@ -2923,6 +2930,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
   if (Record.size() > 13) {
     NewGV->setDSOLocal(getDecodedDSOLocal(Record[13]));
   }
+  inferDSOLocal(NewGV);
 
   return Error::success();
 }
@@ -3007,6 +3015,7 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
   if (Record.size() > 15) {
     Func->setDSOLocal(getDecodedDSOLocal(Record[15]));
   }
+  inferDSOLocal(Func);
 
   ValueList.push_back(Func);
 
@@ -3083,6 +3092,8 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
   }
   if (OpNum != Record.size())
     NewGA->setDSOLocal(getDecodedDSOLocal(Record[OpNum++]));
+  inferDSOLocal(NewGA);
+
   ValueList.push_back(NewGA);
   IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
   return Error::success();
diff --git a/llvm/test/Bitcode/Inputs/infer_dso_local.bc b/llvm/test/Bitcode/Inputs/infer_dso_local.bc
new file mode 100644 (file)
index 0000000..171798e
Binary files /dev/null and b/llvm/test/Bitcode/Inputs/infer_dso_local.bc differ
diff --git a/llvm/test/Bitcode/infer_dso_local.ll b/llvm/test/Bitcode/infer_dso_local.ll
new file mode 100644 (file)
index 0000000..26b7212
--- /dev/null
@@ -0,0 +1,3 @@
+; RUN: opt -verify %S/Inputs/infer_dso_local.bc | llvm-dis | FileCheck %s
+
+; CHECK: define linkonce_odr hidden void @test()