[llvm] fde55a9 - [LTO] Fix cloning of llvm*.used when splitting module

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 20 09:46:54 PST 2021


Author: Teresa Johnson
Date: 2021-02-20T09:46:43-08:00
New Revision: fde55a9c9bf147241249ae478760ae69dd1925ed

URL: https://github.com/llvm/llvm-project/commit/fde55a9c9bf147241249ae478760ae69dd1925ed
DIFF: https://github.com/llvm/llvm-project/commit/fde55a9c9bf147241249ae478760ae69dd1925ed.diff

LOG: [LTO] Fix cloning of llvm*.used when splitting module

Refines the fix in 3c4c205060c9398da705eb71b63ddd8a04999de9 to only
put globals whose defs were cloned into the split regular LTO module
on the cloned llvm*.used globals. This avoids an issue where one of the
attached values was a local that was promoted in the original module
after the module was cloned. We only need to have the values defined in
the new module on those globals.

Fixes PR49251.

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

Added: 
    llvm/test/Transforms/ThinLTOBitcodeWriter/split-used.ll

Modified: 
    llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
    llvm/lib/Transforms/Utils/ModuleUtils.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index bb9de5346577..2ab9dcd09910 100644
--- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -195,6 +195,29 @@ void forEachVirtualFunction(Constant *C, function_ref<void(Function *)> Fn) {
     forEachVirtualFunction(cast<Constant>(Op), Fn);
 }
 
+// Clone any @llvm[.compiler].used over to the new module and append
+// values whose defs were cloned into that module.
+static void cloneUsedGlobalVariables(const Module &SrcM, Module &DestM,
+                                     bool CompilerUsed) {
+  SmallPtrSet<GlobalValue *, 8> Used;
+  SmallPtrSet<GlobalValue *, 8> NewUsed;
+  // First collect those in the llvm[.compiler].used set.
+  collectUsedGlobalVariables(SrcM, Used, CompilerUsed);
+  // Next build a set of the equivalent values defined in DestM.
+  for (auto *V : Used) {
+    auto *GV = DestM.getNamedValue(V->getName());
+    if (GV && !GV->isDeclaration())
+      NewUsed.insert(GV);
+  }
+  // Finally, add them to a llvm[.compiler].used variable in DestM.
+  if (CompilerUsed)
+    appendToCompilerUsed(
+        DestM, std::vector<GlobalValue *>(NewUsed.begin(), NewUsed.end()));
+  else
+    appendToUsed(DestM,
+                 std::vector<GlobalValue *>(NewUsed.begin(), NewUsed.end()));
+}
+
 // If it's possible to split M into regular and thin LTO parts, do so and write
 // a multi-module bitcode file with the two parts to OS. Otherwise, write only a
 // regular LTO bitcode file to OS.
@@ -275,11 +298,6 @@ void splitAndWriteThinLTOBitcode(
   ValueToValueMapTy VMap;
   std::unique_ptr<Module> MergedM(
       CloneModule(M, VMap, [&](const GlobalValue *GV) -> bool {
-        // Clone any llvm.*used globals to ensure the included values are
-        // not deleted.
-        if (GV->getName() == "llvm.used" ||
-            GV->getName() == "llvm.compiler.used")
-          return true;
         if (const auto *C = GV->getComdat())
           if (MergedMComdats.count(C))
             return true;
@@ -292,6 +310,11 @@ void splitAndWriteThinLTOBitcode(
   StripDebugInfo(*MergedM);
   MergedM->setModuleInlineAsm("");
 
+  // Clone any llvm.*used globals to ensure the included values are
+  // not deleted.
+  cloneUsedGlobalVariables(M, *MergedM, /*CompilerUsed*/ false);
+  cloneUsedGlobalVariables(M, *MergedM, /*CompilerUsed*/ true);
+
   for (Function &F : *MergedM)
     if (!F.isDeclaration()) {
       // Reset the linkage of all functions eligible for virtual constant

diff  --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index ef9f18a2289e..f7bd8f0d500f 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -76,11 +76,13 @@ static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *>
   SmallPtrSet<Constant *, 16> InitAsSet;
   SmallVector<Constant *, 16> Init;
   if (GV) {
-    auto *CA = cast<ConstantArray>(GV->getInitializer());
-    for (auto &Op : CA->operands()) {
-      Constant *C = cast_or_null<Constant>(Op);
-      if (InitAsSet.insert(C).second)
-        Init.push_back(C);
+    if (GV->hasInitializer()) {
+      auto *CA = cast<ConstantArray>(GV->getInitializer());
+      for (auto &Op : CA->operands()) {
+        Constant *C = cast_or_null<Constant>(Op);
+        if (InitAsSet.insert(C).second)
+          Init.push_back(C);
+      }
     }
     GV->eraseFromParent();
   }

diff  --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/split-used.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-used.ll
new file mode 100644
index 000000000000..77a4c7c782fb
--- /dev/null
+++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-used.ll
@@ -0,0 +1,30 @@
+; Test to ensure that @llvm[.compiler].used is cloned to the split module for
+; any globals whose defs were cloned to that module.
+
+; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t %s
+; RUN: llvm-modextract -b -n 0 -o %t0.bc %t
+; RUN: llvm-modextract -b -n 1 -o %t1.bc %t
+; RUN: llvm-dis -o - %t0.bc | FileCheck --check-prefix=M0 %s
+; RUN: llvm-dis -o - %t1.bc | FileCheck --check-prefix=M1 %s
+
+; M0: @g1 = external global i8
+; M0: @g2 = external global i8
+; M0: @g3 = global i8 42
+; M0: @g4 = global i8 42
+; M1: @g1 = global i8 42, !type !0
+; M1: @g2 = global i8 42, !type !0
+; M1-NOT: @g
+ at g1 = global i8 42, !type !0
+ at g2 = global i8 42, !type !0
+ at g3 = global i8 42
+ at g4 = global i8 42
+
+; M0: @llvm.used = appending global [2 x i8*] [i8* @g1, i8* @g3]
+; M0: @llvm.compiler.used = appending global [2 x i8*] [i8* @g2, i8* @g4]
+; M1: @llvm.used = appending global [1 x i8*] [i8* @g1]
+; M1: @llvm.compiler.used = appending global [1 x i8*] [i8* @g2]
+ at llvm.used = appending global [2 x i8*] [ i8* @g1, i8* @g3]
+ at llvm.compiler.used = appending global [2 x i8*] [ i8* @g2, i8* @g4]
+
+; M1: !0 = !{i32 0, !"typeid"}
+!0 = !{i32 0, !"typeid"}


        


More information about the llvm-commits mailing list