[llvm] 7dc4bbf - [ThinLTO] Handle variable with twice promoted name (Rust)

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 14 10:54:54 PST 2020


Author: Teresa Johnson
Date: 2020-01-14T10:54:03-08:00
New Revision: 7dc4bbf8ab311606388faacca58b6c3e3e508b77

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

LOG: [ThinLTO] Handle variable with twice promoted name (Rust)

Summary:
Ensure that we can internalize values produced from two rounds of
promotion.

Note that this cannot happen currently via clang, but in other use cases
such as the Rust compiler which does a first round of ThinLTO on library
code, producing bitcode, and a second round on the final binary.

In particular this can happen if a function is exported and promoted,
ending up with a ".llvm.${hash}" suffix, and then goes through a round
of optimization creating an internal switch table expansion variable
that is internal and contains the promoted name of the enclosing
function. This variable will be promoted in the second round of ThinLTO
if @foo is imported again, and therefore ends up with two
".llvm.${hash}" suffixes. Only the final one should be stripped when
consulting the index to locate the summary.

Reviewers: wmi

Subscribers: mehdi_amini, inglorion, hiraditya, JDevlieghere, steven_wu, dexonsmith, arphaman, llvm-commits

Tags: #llvm

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

Added: 
    llvm/test/ThinLTO/X86/Inputs/thinlto-internalize-doublepromoted.ll
    llvm/test/ThinLTO/X86/thinlto-internalize-doublepromoted.ll

Modified: 
    llvm/include/llvm/IR/ModuleSummaryIndex.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/ModuleSummaryIndex.h b/llvm/include/llvm/IR/ModuleSummaryIndex.h
index b78c240e1d17..aa4054c8409e 100644
--- a/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -1268,9 +1268,11 @@ class ModuleSummaryIndex {
   }
 
   /// Helper to obtain the unpromoted name for a global value (or the original
-  /// name if not promoted).
+  /// name if not promoted). Split off the rightmost ".llvm.${hash}" suffix,
+  /// because it is possible in certain clients (not clang at the moment) for
+  /// two rounds of ThinLTO optimization and therefore promotion to occur.
   static StringRef getOriginalNameBeforePromote(StringRef Name) {
-    std::pair<StringRef, StringRef> Pair = Name.split(".llvm.");
+    std::pair<StringRef, StringRef> Pair = Name.rsplit(".llvm.");
     return Pair.first;
   }
 

diff  --git a/llvm/test/ThinLTO/X86/Inputs/thinlto-internalize-doublepromoted.ll b/llvm/test/ThinLTO/X86/Inputs/thinlto-internalize-doublepromoted.ll
new file mode 100644
index 000000000000..327ead5ec16a
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/Inputs/thinlto-internalize-doublepromoted.ll
@@ -0,0 +1,10 @@
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.15.0"
+
+define i32 @main() {
+entry:
+  call void @foo.llvm.123()
+  ret i32 0
+}
+
+declare void @foo.llvm.123()

diff  --git a/llvm/test/ThinLTO/X86/thinlto-internalize-doublepromoted.ll b/llvm/test/ThinLTO/X86/thinlto-internalize-doublepromoted.ll
new file mode 100644
index 000000000000..fbdedda97859
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/thinlto-internalize-doublepromoted.ll
@@ -0,0 +1,33 @@
+; Test to ensure that we can internalize values produced from two rounds
+; of ThinLTO promotion, so they end up with two ".llvm.${hash}" suffixes.
+; Only the second should be stripped when consulting the index to locate the
+; summary.
+;
+; Note that this cannot happen currently via clang, but in other use cases such
+; as the Rust compiler which does a first round of ThinLTO on library code,
+; producing bitcode, and a second round on the final binary.
+;
+; In this case we assume a prior round of ThinLTO has promoted @foo, and
+; subsequent optimization created an internal switch table expansion variable
+; that is internal and contains the promoted name of the enclosing function.
+; This variable will be promoted in the second round of ThinLTO if @foo is
+; imported again.
+
+; RUN: opt -module-summary -o %t.bc %s
+; RUN: opt -module-summary -o %t-main.bc %S/Inputs/thinlto-internalize-doublepromoted.ll
+; RUN: llvm-lto -thinlto-action=thinlink %t.bc %t-main.bc -o %t-index.bc
+; RUN: llvm-lto -thinlto-action=internalize -exported-symbol=main -thinlto-index %t-index.bc %t.bc -o %t.internalize.bc
+; RUN: llvm-dis %t.internalize.bc -o - | FileCheck %s
+
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.15.0"
+
+; CHECK: @switch.table.foo.llvm.123.llvm.0 = hidden unnamed_addr constant
+ at switch.table.foo.llvm.123 = private unnamed_addr constant [10 x i8] c"\00\01\02\03\00\00\00\00\00\09", align 1
+
+; CHECK: define hidden void @foo.llvm.123()
+define hidden void @foo.llvm.123() {
+  %1 = getelementptr inbounds [10 x i8], [10 x i8]* @switch.table.foo.llvm.123, i64 0, i64 0
+  store i8 1, i8* %1, align 8
+  ret void
+}


        


More information about the llvm-commits mailing list