Skip to content

Commit 1828e57

Browse files
samitolvanentstellar
authored andcommitted
ThinLTO: Fix inline assembly references to static functions with CFI
Create an internal alias with the original name for static functions that are renamed in promoteInternals to avoid breaking inline assembly references to them. Relands 700d07f with -msvc targets fixed. Link: ClangBuiltLinux/linux#1354 Reviewed By: nickdesaulniers, pcc Differential Revision: https://reviews.llvm.org/D104058 (cherry picked from commit 7ce1c4d)
1 parent 7161e4f commit 1828e57

File tree

5 files changed

+53
-0
lines changed

5 files changed

+53
-0
lines changed

llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ using namespace llvm;
3333

3434
namespace {
3535

36+
// Determine if a promotion alias should be created for a symbol name.
37+
static bool allowPromotionAlias(const std::string &Name) {
38+
// Promotion aliases are used only in inline assembly. It's safe to
39+
// simply skip unusual names. Subset of MCAsmInfo::isAcceptableChar()
40+
// and MCAsmInfoXCOFF::isAcceptableChar().
41+
for (const char &C : Name) {
42+
if (isAlnum(C) || C == '_' || C == '.')
43+
continue;
44+
return false;
45+
}
46+
return true;
47+
}
48+
3649
// Promote each local-linkage entity defined by ExportM and used by ImportM by
3750
// changing visibility and appending the given ModuleId.
3851
void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId,
@@ -55,6 +68,7 @@ void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId,
5568
}
5669
}
5770

71+
std::string OldName = Name.str();
5872
std::string NewName = (Name + ModuleId).str();
5973

6074
if (const auto *C = ExportGV.getComdat())
@@ -69,6 +83,13 @@ void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId,
6983
ImportGV->setName(NewName);
7084
ImportGV->setVisibility(GlobalValue::HiddenVisibility);
7185
}
86+
87+
if (isa<Function>(&ExportGV) && allowPromotionAlias(OldName)) {
88+
// Create a local alias with the original name to avoid breaking
89+
// references from inline assembly.
90+
std::string Alias = ".set " + OldName + "," + NewName + "\n";
91+
ExportM.appendModuleInlineAsm(Alias);
92+
}
7293
}
7394

7495
if (!RenamedComdats.empty())

llvm/test/ThinLTO/X86/devirt2.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,12 @@
131131
; RUN: -r=%t1.o,_ZN1D1mEi, \
132132
; RUN: -r=%t1.o,test2, \
133133
; RUN: -r=%t2.o,_ZN1A1nEi,p \
134+
; RUN: -r=%t2.o,_ZN1A1nEi, \
134135
; RUN: -r=%t2.o,_ZN1B1fEi,p \
135136
; RUN: -r=%t2.o,_ZN1C1fEi,p \
136137
; RUN: -r=%t2.o,_ZN1D1mEi,p \
137138
; RUN: -r=%t2.o,_ZN1E1mEi,p \
139+
; RUN: -r=%t2.o,_ZN1E1mEi, \
138140
; RUN: -r=%t2.o,_ZTV1B, \
139141
; RUN: -r=%t2.o,_ZTV1C, \
140142
; RUN: -r=%t2.o,_ZTV1D, \
@@ -167,10 +169,12 @@
167169
; RUN: -r=%t1.o,_ZN1D1mEi, \
168170
; RUN: -r=%t1.o,test2, \
169171
; RUN: -r=%t2.o,_ZN1A1nEi,p \
172+
; RUN: -r=%t2.o,_ZN1A1nEi, \
170173
; RUN: -r=%t2.o,_ZN1B1fEi,p \
171174
; RUN: -r=%t2.o,_ZN1C1fEi,p \
172175
; RUN: -r=%t2.o,_ZN1D1mEi,p \
173176
; RUN: -r=%t2.o,_ZN1E1mEi,p \
177+
; RUN: -r=%t2.o,_ZN1E1mEi, \
174178
; RUN: -r=%t2.o,_ZTV1B, \
175179
; RUN: -r=%t2.o,_ZTV1C, \
176180
; RUN: -r=%t2.o,_ZTV1D, \
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; REQUIRES: x86-registered-target
2+
; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o - %s | llvm-modextract -b -n 0 -o - | llvm-dis | FileCheck %s
3+
4+
target triple = "x86_64-unknown-linux-gnu"
5+
6+
; CHECK: module asm ".set a,a.[[HASH:[0-9a-f]+]]"
7+
8+
define void @b() {
9+
%f = alloca void ()*, align 8
10+
; CHECK: store{{.*}} @a.[[HASH]],{{.*}} %f
11+
store void ()* @a, void ()** %f, align 8
12+
; CHECK: %1 = call void ()* asm sideeffect "leaq a(%rip)
13+
%1 = call void ()* asm sideeffect "leaq a(%rip), $0\0A\09", "=r,~{dirflag},~{fpsr},~{flags}"()
14+
ret void
15+
}
16+
17+
; CHECK: define{{.*}} @a.[[HASH]](){{.*}} !type
18+
define internal void @a() !type !0 {
19+
ret void
20+
}
21+
22+
!0 = !{i64 0, !"typeid1"}

llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal2.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
; REQUIRES: x86-registered-target
12
; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t %s
23
; RUN: llvm-modextract -b -n 0 -o %t0 %t
34
; RUN: llvm-modextract -b -n 1 -o %t1 %t
@@ -7,6 +8,8 @@
78
; RUN: llvm-bcanalyzer -dump %t0 | FileCheck --check-prefix=BCA0 %s
89
; RUN: llvm-bcanalyzer -dump %t1 | FileCheck --check-prefix=BCA1 %s
910

11+
target triple = "x86_64-unknown-linux-gnu"
12+
1013
; ERROR: llvm-modextract: error: module index out of range; bitcode file contains 2 module(s)
1114

1215
; BCA0: <GLOBALVAL_SUMMARY_BLOCK

llvm/test/Transforms/ThinLTOBitcodeWriter/split-vfunc-internal.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
; REQUIRES: x86-registered-target
12
; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t %s
23
; RUN: llvm-modextract -b -n 0 -o - %t | llvm-dis | FileCheck --check-prefix=M0 %s
34
; RUN: llvm-modextract -b -n 1 -o - %t | llvm-dis | FileCheck --check-prefix=M1 %s
45

6+
target triple = "x86_64-unknown-linux-gnu"
7+
58
define [1 x i8*]* @source() {
69
ret [1 x i8*]* @g
710
}

0 commit comments

Comments
 (0)