Skip to content

Commit dc8e89b

Browse files
authored
[DirectX] Convert private global variables to internal linkage during Finalize Linkage pass (#146406)
Fixes #140420. The switch.table.* validation errors were caused by DXIL not supporting private global variables. Converting them to internal linkage fixes the bug. May need more discussion on the preserved analyses/a follow-up PR that fixes what this pass says it preserves.
1 parent ace3d30 commit dc8e89b

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
using namespace llvm;
1919

2020
static bool finalizeLinkage(Module &M) {
21+
bool MadeChange = false;
22+
23+
// Convert private global variables to internal linkage.
24+
for (GlobalVariable &GV : M.globals()) {
25+
if (GV.hasPrivateLinkage()) {
26+
GV.setLinkage(GlobalValue::InternalLinkage);
27+
MadeChange = true;
28+
}
29+
}
30+
2131
SmallVector<Function *> Funcs;
2232

2333
// Collect non-entry and non-exported functions to set to internal linkage.
@@ -32,13 +42,17 @@ static bool finalizeLinkage(Module &M) {
3242
}
3343

3444
for (Function *F : Funcs) {
35-
if (F->getLinkage() == GlobalValue::ExternalLinkage)
45+
if (F->getLinkage() == GlobalValue::ExternalLinkage) {
3646
F->setLinkage(GlobalValue::InternalLinkage);
37-
if (F->isDefTriviallyDead())
47+
MadeChange = true;
48+
}
49+
if (F->isDefTriviallyDead()) {
3850
M.getFunctionList().erase(F);
51+
MadeChange = true;
52+
}
3953
}
4054

41-
return false;
55+
return MadeChange;
4256
}
4357

4458
PreservedAnalyses DXILFinalizeLinkage::run(Module &M,

llvm/test/CodeGen/DirectX/finalize_linkage.ll

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,28 @@
44
target triple = "dxilv1.5-pc-shadermodel6.5-compute"
55

66
; DXILFinalizeLinkage changes linkage of all functions that are hidden to
7-
; internal.
7+
; internal, and converts private global variables to internal linkage.
8+
9+
; CHECK: @switch.table = internal unnamed_addr constant [4 x i32]
10+
@switch.table = private unnamed_addr constant [4 x i32] [i32 1, i32 257, i32 65793, i32 16843009], align 4
11+
12+
; CHECK: @private_array = internal constant [3 x float]
13+
@private_array = private constant [3 x float] [float 1.0, float 2.0, float 3.0], align 4
14+
15+
; CHECK: @private_var = internal global i32
16+
@private_var = private global i32 1, align 4
17+
18+
; Internal global should remain internal
19+
; CHECK: @internal_var = internal global i32
20+
@internal_var = internal global i32 1, align 4
21+
22+
; External global should remain external
23+
; CHECK: @external_var = external global i32
24+
@external_var = external global i32, align 4
25+
26+
; Hidden global should remain hidden
27+
; CHECK: @hidden_var = hidden global i32
28+
@hidden_var = hidden global i32 1, align 4
829

930
; CHECK-NOT: define internal void @"?f1@@YAXXZ"()
1031
define void @"?f1@@YAXXZ"() #0 {

0 commit comments

Comments
 (0)